π π§ Kotlin + Ktor
AndreasVolkmann opened this issue Β· comments
Progress / ToDo
- π Fork the starter repo & post the link in this issue
- π¨ Create logo for repo & update issue status (@EricSimons)
- π¨ Implement all of Conduit's functionality per the spec & API
- π Move repo to main org & Peer review final codebase by admins/community (RFC)
- π Tag v1 release and officially list it on the README!
Current Status
Codebase in progress: dragneelfps/realworld-kotlin-ktor
@goreRatzete awesome man! Can't wait to see this!
@goreRatzete is this project still active? I'm trying to get involved here. And unfortunately, there is no Issues tab in your Github forked project, which make it hard to discuss
@Muhannad508 Hi there. Yes it is still alive. I had a smaller break but will continue working on it soon. I haven't created any issues since I was working alone so far. I can either tell you what needs to be done, or you can have a look yourself.
Also I have placed many TODOs in the code to show what is missing. If you go through the routes you can quickly find them.
2 things I am not 100% sure on yet:
- Database access and design
- Json serialization
I have implemented a realworld backend using ktor and MongoDB here: https://github.com/soywiz/realworld-kotlin
EDIT: @AndreasVolkmann did you finished it? Maybe we can merge efforts.
@soywiz Hi there, no it's not finished. Mainly I am waiting for the optional auth feature before proceeding. I see you build it manually in your repo.
Is your's feature complete yet? Of course we can / should merge.
One thing that I would change in your setup is the use of Mongo.
I use an in-memory H2 DB which makes it lighter and easier to try out locally, because you do not have to install any db.
@AndreasVolkmann Nice. FYI: We have just released 0.9.3 that supports optional authentication.
@soywiz Yeah I saw it π Great job by the way.
Again, is you version feature complete yet?
I see no reason to maintain two separate repos.
We have a couple of options afaik:
- Merge your code into my project
- Deprecate my project and use yours from now on
My version is feature complete as far as I know, but it's a bit quick and dirty and needs reviewing and a bit polishing.
Using h2 to not have external dependencies is a good idea for people to use it, but I also think that using another readical different db engine like mongodb provides value to show another way of doing things.
I think that realworld won't require too much effort maintaining once it is done and people could contribute to the implementation.
My proposal would be to complete your version and publish it, and maybe, later, add a folder with another possible implementation using mongodb?
@AndreasVolkmann @soywiz did we settle on a final merged version of this repo? If so could we get this building on TravisCI. It really helps get rid of system dependent hacks and gets everyone on the same page. Thanks!
Nothing new from my side. But my proposal is still to finish the H2 version, and once it is published explore options.
@AndreasVolkmann I can help you finish your implementation if you don't have enough time, and if you are accepting PRs
@AndreasVolkmann
Is this still alive? I am planning to build it from scratch for learning purposes.
@dragneelfps please go ahead. I am not working on this anymore.
Hi, I have started working on it.
https://github.com/dragneelfps/realworld-kotlin-ktor
@AndreasVolkmann can you update the top post status so that it reflect that I am working on it. It will be helpful for people reading this issue.
I have completed the features as per the API spec. But there might be things that I overlooked so I'll do revisions if needed. Also, any PR is welcome.
I need to do documentation about the stuff the backend is built on, in the readme and some in code, though it mostly is self explanatory.
If someone can review my code, so we can move forward.
Any update? Its out of wip
Could you run the API tests given in this repo (/api folder). Also could you add some CI service on your repo (eg TravisCI). Thanks!
@anishkny the tests in the postman collection mentions "celebs" but in the API spec there is not mention of that. Are both, API spec and postman updated? I followed the API spec in my code.
I ran the tests after fixing my code for failing tests. Following is the output:
[sourabh@sourabh-pc` api_tests]$ env APIURL=http://localhost:8080/api ./run-api-tests.sh > api-tests-output.txt
+++ dirname ./run-api-tests.sh
++ cd .
++ pwd
+ SCRIPTDIR=/home/sourabh/IdeaProjects/Realworld/api_tests
+ APIURL=http://localhost:8080/api
++ date +%s
+ USERNAME=u1561310429
+ EMAIL=u1561310429@mail.com
+ PASSWORD=password
+ npx newman run /home/sourabh/IdeaProjects/Realworld/api_tests/Conduit.postman_collection.json --delay-request 500 --global-var APIURL=http://localhost:8080/api --global-var USERNAME=u1561310429 --global-var EMAIL=u1561310429@mail.com --global-var PASSWORD=password
npx: installed 152 in 2.793s
newman
Conduit
β Auth
β³ Register
POST http://localhost:8080/api/users [200 OK, 487B, 58ms]
β Response contains "user" property
β User has "email" property
β User has "username" property
β User has "bio" property
β User has "image" property
β User has "token" property
β³ Login
POST http://localhost:8080/api/users/login [200 OK, 487B, 11ms]
β Response contains "user" property
β User has "email" property
β User has "username" property
β User has "bio" property
β User has "image" property
β User has "token" property
β³ Login and Remember Token
POST http://localhost:8080/api/users/login [200 OK, 487B, 12ms]
β Response contains "user" property
β User has "email" property
β User has "username" property
β User has "bio" property
β User has "image" property
β User has "token" property
β Global variable "token" has been set
β³ Current User
GET http://localhost:8080/api/user [200 OK, 346B, 9ms]
β Response contains "user" property
β User has "email" property
β User has "username" property
β User has "bio" property
β User has "image" property
β User has "token" property
β³ Update User
PUT http://localhost:8080/api/user [200 OK, 487B, 15ms]
β Response contains "user" property
β User has "email" property
β User has "username" property
β User has "bio" property
β User has "image" property
β User has "token" property
β Articles
β³ All Articles
GET http://localhost:8080/api/articles [200 OK, 247B, 7ms]
β Response code is 200 OK
β Response contains "articles" property
β Response contains "articlesCount" property
β articlesCount is an integer
β articlesCount is 0 when feed is empty
β³ Articles by Author
GET http://localhost:8080/api/articles?author=johnjacob [200 OK, 247B, 10ms]
β Response code is 200 OK
β Response contains "articles" property
β Response contains "articlesCount" property
β articlesCount is an integer
β articlesCount is 0 when feed is empty
β³ Articles Favorited by Username
GET http://localhost:8080/api/articles?favorited=jane [200 OK, 247B, 10ms]
β Response code is 200 OK
β Response contains "articles" property
β Response contains "articlesCount" property
β articlesCount is an integer
β articlesCount is 0 when feed is empty
β³ Articles by Tag
GET http://localhost:8080/api/articles?tag=dragons [200 OK, 247B, 11ms]
β Response code is 200 OK
β Response contains "articles" property
β Response contains "articlesCount" property
β articlesCount is an integer
β articlesCount is 0 when feed is empty
β Articles, Favorite, Comments
β³ Create Article
POST http://localhost:8080/api/articles [200 OK, 700B, 13ms]
β Response contains "article" property
β Article has "title" property
β Article has "slug" property
β Article has "body" property
β Article has "createdAt" property
β Article's "createdAt" property is an ISO 8601 timestamp
β Article has "updatedAt" property
β Article's "updatedAt" property is an ISO 8601 timestamp
β Article has "description" property
β Article has "tagList" property
β Article's "tagList" property is an Array
β Article has "author" property
β Article has "favorited" property
β Article has "favoritesCount" property
β favoritesCount is an integer
β³ Feed
GET http://localhost:8080/api/articles/feed [200 OK, 247B, 8ms]
β Response code is 200 OK
β Response contains "articles" property
β Response contains "articlesCount" property
β articlesCount is an integer
β articlesCount is 0 when feed is empty
β³ All Articles
GET http://localhost:8080/api/articles [200 OK, 728B, 9ms]
β Response code is 200 OK
β Response contains "articles" property
β Response contains "articlesCount" property
β articlesCount is an integer
β Article has "title" property
β Article has "slug" property
β Article has "body" property
β Article has "createdAt" property
β Article's "createdAt" property is an ISO 8601 timestamp
β Article has "updatedAt" property
β Article's "updatedAt" property is an ISO 8601 timestamp
β Article has "description" property
β Article has "tagList" property
β Article's "tagList" property is an Array
β Article has "author" property
β Article has "favorited" property
β Article has "favoritesCount" property
β favoritesCount is an integer
β³ All Articles with auth
GET http://localhost:8080/api/articles [200 OK, 728B, 12ms]
β Response code is 200 OK
β Response contains "articles" property
β Response contains "articlesCount" property
β articlesCount is an integer
β Article has "title" property
β Article has "slug" property
β Article has "body" property
β Article has "createdAt" property
β Article's "createdAt" property is an ISO 8601 timestamp
β Article has "updatedAt" property
β Article's "updatedAt" property is an ISO 8601 timestamp
β Article has "description" property
β Article has "tagList" property
β Article's "tagList" property is an Array
β Article has "author" property
β Article has "favorited" property
β Article has "favoritesCount" property
β favoritesCount is an integer
β³ Articles by Author
GET http://localhost:8080/api/articles?author=u1561310429 [200 OK, 728B, 10ms]
β Response code is 200 OK
β Response contains "articles" property
β Response contains "articlesCount" property
β articlesCount is an integer
β Article has "title" property
β Article has "slug" property
β Article has "body" property
β Article has "createdAt" property
β Article's "createdAt" property is an ISO 8601 timestamp
β Article has "updatedAt" property
β Article's "updatedAt" property is an ISO 8601 timestamp
β Article has "description" property
β Article has "tagList" property
β Article's "tagList" property is an Array
β Article has "author" property
β Article has "favorited" property
β Article has "favoritesCount" property
β favoritesCount is an integer
β³ Articles by Author with auth
GET http://localhost:8080/api/articles?author=u1561310429 [200 OK, 728B, 13ms]
β Response code is 200 OK
β Response contains "articles" property
β Response contains "articlesCount" property
β articlesCount is an integer
β Article has "title" property
β Article has "slug" property
β Article has "body" property
β Article has "createdAt" property
β Article's "createdAt" property is an ISO 8601 timestamp
β Article has "updatedAt" property
β Article's "updatedAt" property is an ISO 8601 timestamp
β Article has "description" property
β Article has "tagList" property
β Article's "tagList" property is an Array
β Article has "author" property
β Article has "favorited" property
β Article has "favoritesCount" property
β favoritesCount is an integer
β³ Articles Favorited by Username
GET http://localhost:8080/api/articles?favorited=jane [200 OK, 247B, 7ms]
β Response code is 200 OK
β Response contains "articles" property
β Response contains "articlesCount" property
β articlesCount is an integer
β articlesCount is 0 when feed is empty
β³ Articles Favorited by Username with auth
GET http://localhost:8080/api/articles?favorited=jane [200 OK, 247B, 8ms]
β Response code is 200 OK
β Response contains "articles" property
β Response contains "articlesCount" property
β articlesCount is an integer
β articlesCount is 0 when feed is empty
β³ Single Article by slug
GET http://localhost:8080/api/articles/how-to-train-your-dragon [200 OK, 700B, 8ms]
β Response contains "article" property
β Article has "title" property
β Article has "slug" property
β Article has "body" property
β Article has "createdAt" property
β Article's "createdAt" property is an ISO 8601 timestamp
β Article has "updatedAt" property
β Article's "updatedAt" property is an ISO 8601 timestamp
β Article has "description" property
β Article has "tagList" property
β Article's "tagList" property is an Array
β Article has "author" property
β Article has "favorited" property
β Article has "favoritesCount" property
β favoritesCount is an integer
β³ Articles by Tag
GET http://localhost:8080/api/articles?tag=dragons [200 OK, 728B, 10ms]
β Response code is 200 OK
β Response contains "articles" property
β Response contains "articlesCount" property
β articlesCount is an integer
β Article has "title" property
β Article has "slug" property
β Article has "body" property
β Article has "createdAt" property
β Article's "createdAt" property is an ISO 8601 timestamp
β Article has "updatedAt" property
β Article's "updatedAt" property is an ISO 8601 timestamp
β Article has "description" property
β Article has "tagList" property
β Article's "tagList" property is an Array
β Article has "author" property
β Article has "favorited" property
β Article has "favoritesCount" property
β favoritesCount is an integer
β³ Update Article
PUT http://localhost:8080/api/articles/how-to-train-your-dragon [200 OK, 700B, 12ms]
β Response contains "article" property
β Article has "title" property
β Article has "slug" property
β Article has "body" property
β Article has "createdAt" property
β Article's "createdAt" property is an ISO 8601 timestamp
β Article has "updatedAt" property
β Article's "updatedAt" property is an ISO 8601 timestamp
β Article has "description" property
β Article has "tagList" property
β Article's "tagList" property is an Array
β Article has "author" property
β Article has "favorited" property
β Article has "favoritesCount" property
β favoritesCount is an integer
β³ Favorite Article
POST http://localhost:8080/api/articles/how-to-train-your-dragon/favorite [200 OK, 699B, 14ms]
β Response contains "article" property
β Article has "title" property
β Article has "slug" property
β Article has "body" property
β Article has "createdAt" property
β Article's "createdAt" property is an ISO 8601 timestamp
β Article has "updatedAt" property
β Article's "updatedAt" property is an ISO 8601 timestamp
β Article has "description" property
β Article has "tagList" property
β Article's "tagList" property is an Array
β Article has "author" property
β Article has "favorited" property
β Article's 'favorited' property is true
β Article has "favoritesCount" property
β favoritesCount is an integer
β Article's 'favoritesCount' property is greater than 0
β³ Unfavorite Article
DELETE http://localhost:8080/api/articles/how-to-train-your-dragon/favorite [200 OK, 700B, 12ms]
β Response contains "article" property
β Article has "title" property
β Article has "slug" property
β Article has "body" property
β Article has "createdAt" property
β Article's "createdAt" property is an ISO 8601 timestamp
β Article has "updatedAt" property
β Article's "updatedAt" property is an ISO 8601 timestamp
β Article has "description" property
β Article has "tagList" property
β Article's "tagList" property is an Array
β Article has "author" property
β Article has "favorited" property
β Article has "favoritesCount" property
β favoritesCount is an integer
β Article's "favorited" property is false
β³ Create Comment for Article
POST http://localhost:8080/api/articles/how-to-train-your-dragon/comments [200 OK, 500B, 11ms]
β Response contains "comment" property
β Comment has "id" property
β Comment has "body" property
β Comment has "createdAt" property
β "createdAt" property is an ISO 8601 timestamp
β Comment has "updatedAt" property
β "updatedAt" property is an ISO 8601 timestamp
β Comment has "author" property
β³ All Comments for Article
GET http://localhost:8080/api/articles/how-to-train-your-dragon/comments [200 OK, 505B, 8ms]
β Response code is 200 OK
β Response contains "comments" property
β Comment has "id" property
β Comment has "body" property
β Comment has "createdAt" property
β "createdAt" property is an ISO 8601 timestamp
β Comment has "updatedAt" property
β "updatedAt" property is an ISO 8601 timestamp
β Comment has "author" property
β³ Delete Comment for Article
DELETE http://localhost:8080/api/articles/how-to-train-your-dragon/comments/5 [200 OK, 154B, 9ms]
β³ Delete Article
DELETE http://localhost:8080/api/articles/how-to-train-your-dragon [200 OK, 154B, 12ms]
β Profiles
β³ Register Celeb
POST http://localhost:8080/api/users [200 OK, 499B, 10ms]
β Response contains "user" property
β User has "email" property
β User has "username" property
β User has "bio" property
β User has "image" property
β User has "token" property
β³ Profile
GET http://localhost:8080/api/profiles/celeb_u1561310429 [200 OK, 324B, 12ms]
β Response code is 200 OK
β Response contains "profile" property
β Profile has "username" property
β Profile has "bio" property
β Profile has "image" property
β Profile has "following" property
β³ Follow Profile
POST http://localhost:8080/api/profiles/celeb_u1561310429/follow [200 OK, 323B, 14ms]
β Response code is 200 OK
β Response contains "profile" property
β Profile has "username" property
β Profile has "bio" property
β Profile has "image" property
β Profile has "following" property
β Profile's "following" property is true
β³ Unfollow Profile
DELETE http://localhost:8080/api/profiles/celeb_u1561310429/follow [200 OK, 324B, 19ms]
β Response code is 200 OK
β Response contains "profile" property
β Profile has "username" property
β Profile has "bio" property
β Profile has "image" property
β Profile has "following" property
β Profile's "following" property is false
β Tags
β³ All Tags
GET http://localhost:8080/api/tags [200 OK, 242B, 9ms]
β Response code is 200 OK
β Response contains "tags" property
β "tags" property returned as array
βββββββββββββββββββββββββββ¬βββββββββββββββββββ¬ββββββββββββββββββ
β β executed β failed β
βββββββββββββββββββββββββββΌβββββββββββββββββββΌββββββββββββββββββ€
β iterations β 1 β 0 β
βββββββββββββββββββββββββββΌβββββββββββββββββββΌββββββββββββββββββ€
β requests β 31 β 0 β
βββββββββββββββββββββββββββΌβββββββββββββββββββΌββββββββββββββββββ€
β test-scripts β 46 β 0 β
βββββββββββββββββββββββββββΌβββββββββββββββββββΌββββββββββββββββββ€
β prerequest-scripts β 17 β 0 β
βββββββββββββββββββββββββββΌβββββββββββββββββββΌββββββββββββββββββ€
β assertions β 280 β 0 β
βββββββββββββββββββββββββββ΄βββββββββββββββββββ΄ββββββββββββββββββ€
β total run duration: 16.8s β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β total data received: 7.81KB (approx) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β average response time: 12ms [min: 7ms, max: 58ms, s.d.: 8ms] β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Is this good?
Yup looks good! It also helps a lot setting up CI - could you try that next?
What kind of CI does need to be set up? For the .sh(postman tests) provided or ktor unit tests?
Edit: I did the setup for Travis which builds and runs ktor tests.
Any update?
Hey why was build #3 cancelled? That had Postman tests correct?
#3
was cancelled because the .travis.yaml configuration was wrong. I need help setting up configuration for postman test. My problem is how to run the server, run the .sh test and then stop the server gracefully.
Hmm. How about :
script:
- ./gradlew test build
- ./gradlew run & ## <---- notice ampersand
- ./postman_tests/run-api-tests.sh
- ./gradlew --stop
@anishkny thank you for your input. It works now. If there is nothing more to do, I think this repo is ready to be included in the realworld.io project.
great! LGTM PTAL @Cameron-C-Chapman