Server-Side Kotlin with Ktor · API Post Endpoint | raywenderlich.com


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/2885892-server-side-kotlin-with-ktor/lessons/6
1 Like

wow. this stuff is brushed over. therefore its pretty hard whats going on. explanations would be great.

HI. Running this app in intellij, I get no response from the terminal curl post. I have done a POST through Postman and get a 415 Unsupported media response. I have put println on the start and end of the phrase endpoint and it starts but does not finish. I downloaded your materials and ran the end point code in Intellij and get the same error. Please help. This is my first course with your organisation so I am interested to see how the support works.

Thank you for the feedback @eoin_a! Can you let us know which parts you feel were brushed over? We’ll try to go into more depth on them when we update this course. Thanks again!

Thank you for the question @oldiwon! When you run the app, do you see the Responding at http://0.0.0.0:8080 message in the Run panel? Also, could you post here the curl command you are using? And maybe post here your Application.kt file and api/Phrase.kt file. Thanks!

Hi Joe. Thanks for getting back to me. It’s probably something silly but I just can’t see it. I have imported the 1-006-api-post-endpoint version into Intellij and get the same error message.

Thanks and see below for answers to your questions.

Yes I do get the Responding at message and the get requests work for about etc.

curl -X POST -H “Content-Type: application/json” -d @/Users/garydean/IdeaTrainingProjects/resources/request.json http://localhost:8090/api/vi/phrase

I have used postman with both a file and inline json see below request, and that gives me a response of 415Unsupported Media Type

Request Headers

Content-Type: application/json

User-Agent: PostmanRuntime/7.20.1

Accept: /

Cache-Control: no-cache

Postman-Token: 123b9ca1-8b5d-4da6-9504-0a01eefd7904

Host: localhost:8090

Accept-Encoding: gzip, deflate

Content-Length: 244

Connection: keep-alive

  • :arrow_forward:Request Body
  1. file: “{“emoji”: “emoji list”, “phrase”:“Doing my homework”}”

package com.core

import com.core.api.*
import com.core.repository.*
import com.core.webapp.*
import com.ryanharter.ktor.moshi.*
import io.ktor.application.*
import io.ktor.features.*
import io.ktor.http.*
import io.ktor.response.*
import io.ktor.routing.*

fun main(args: Array): Unit = io.ktor.server.netty.EngineMain.main(args)

@Suppress(“unused”) // Referenced in application.conf
@kotlin.jvm.JvmOverloads
fun Application.module(testing: Boolean = false) {
install(DefaultHeaders)
install(StatusPages) {
exception { e → call.respondText(e.localizedMessage, ContentType.Text.Plain, HttpStatusCode.InternalServerError) }
}

install(ContentNegotiation) {
        moshi()
}


val db = InMemoryRepository()

routing {
    home()
    about()

    // API
    phrase(db)
}

}

const val API_VERSION = “/api/v1”

package com.core.api

import com.core.*
import com.core.model.*
import com.core.repository.*
import io.ktor.application.*
import io.ktor.request.*
import io.ktor.response.*
import io.ktor.routing.*

const val PHRASE_ENDPOINT = “$API_VERSION/phrase”

fun Route.phrase(db: Repository){
post(path = PHRASE_ENDPOINT){
println(“Got phrase request”)

    val request = call.receive<Request>()

    println("phrase text ${request.phrase}")

    val phrase: EmojiPhrase = db.add(EmojiPhrase(request.emoji, request.phrase))
    call.respond(phrase)
    println("Finished request")
}

}

Thanks for sending that info, @oldiwon. The only thing I see different from the episode is that you’re using port 8090, whereas the default port is 8080. Were you using 8090 because you changed the default port?

Hi. I use 8090 because I have a spring boot app running on 8080. I have amended the application conf file and it works with the about get call.

Hope this helps.

Gary

Hi @oldiwon. I don’t see any particular problems in the code you sent, the only difference being the port number we discussed. I think I’d need you to zip up the project and post it here, if it works, or on some kind of file sharing site. Then I could try and run your project to diagnose the issue. Let me know if you think you’d have a chance to do that. Thanks!

Hi macsimus. I get the same error if I run the downloaded lesson end point. 1-006-api-post-endpoint. Therefore I do not think it is due to my code. Could you check the downloaded version still works on your setup?

Gary

Hi @oldiwon thanks for that info. I’ll try and check the downloaded materials in the next few days and let you know what I find.

@macsimus @oldiwon Having the same issue. After some time I resolved it. Be sure to add the correct emoji unicode into de json file.

I found another issue in moshi version 1.0.1. “receive()” is throwing an error. Link to issue and temporary solution: Fails on ktor 1.3.0 · Issue #7 · rharter/ktor-moshi · GitHub

Also i need to add:

    moshi {
        add(KotlinJsonAdapterFactory())
    }
1 Like

Hi @lsuarez and @oldiwon. I finally had a chance to download the materials for this episode and try this out to try to reproduce the errors you are seeing. I was not able to reproduce the errors.

I opened the downloaded end project in IntelliJ IDEA 2019.3.3 on macOS 10.15.3. Once the Gradle build was complete, I ran the project and the server was up and running with the message `Application - Responding at http://0.0.0.0:8080". There were no errors.

I then created the /tmp/request.json file as in the video, and ran the curl command from the video. The server respond with the JSON result, just as in the video.

I’m not sure about the need for that moshi change, since it was not needed in my run.

For the 415Unsupported Media Type error, sounds like there may be an issue with the request.json file that was created. What editor did you use to create it?

Using Ktor 1.3.0 or later, on the

Router.phrase(db:Repository)

extension, when is processing the request the line

val request = call.receive<Request>()

return the following error to the client:

kotlinx/coroutines/io/ByteReadChannel

1 Like

I am getting the same error as @alxnophis

I removed Moshi and changed to using GSON: see the KTor sample pages for how to set it up with gradle and the Application code. For some reason, the curl request (using the file) as the instructor put was causing errors for me. I raw formatted the data in a json body directly in the curl terminal command and it worked.

@macsimus Can you please help with this when you get a chance? Thank you - much appreciated! :]

I have the same problem with ktor 1.3.0.
to resolve this problem I changed Moshi by Gson.
In build.gradle dependencies add:

implementation “io.ktor:ktor-gson:$ktor_version”

and in Application.kt:
replace:

install (ContentNegotiation) {
moshi ()
}

by:

install (ContentNegotiation) {
gson {
setPrettyPrinting ()
}
}

It worked for me.

1 Like

Thanks @nasoasis41 , your solution works. @macsimus Please update the video so that newcomers don’t have to struggle upon this.

@anasoasis41 Thank you for sharing your solution - much appreciated! :]