Is it possible to use Locations with POST?
# ktor
l
Is it possible to use Locations with POST?
Copy code
@Location("/v1/check") class IntegrationsContainer

...

post<IntegrationsContainerC> { body ->
call.respond(realAppLogic(body))
}
but I get
2018-01-26 10:59:50.226 [nettyCallPool-4-1] ERROR Application - Unhandled: POST - /v1/check
s
The properties in
IntegrationsContainerC
cannot be used for post variables
l
what about JSON?
s
Only get variables
l
Ok - so no locations
s
Well, you can still use locations but you just cannot route based on post body data
k
Copy code
@Location("/")
class Post(val test: Int) //only query params

data class Body(val x: Int) //actual body

post<Post> { post ->// contains query params
    val body = call.receive<Body>() // contains body
    call.respond(body)
}
the unhandled POST probably means you did not specify all the query params in the
IntegrationsContainer
class
l
Ok - so the class uses in Location is just for (mandatory?) query params, and I need to use
call.receive<T>()
to get my actual class
but if my class (the
Body
class above) is a complex one, can it be used? If I get a JSON body with a
Content-Type: application/json
header, can I use something like Content-Negotiation feature, or should I just use a plain string / JSON serializer by hand?
s
You can have optional query params also. I think they just need a default value. ie
class Foo(val bar : String = "")
No experience with the built in json
k
content negotiation works with the exact same code
you just need to install one of the json features (gson, jackson) and it just works
l
As an update, it indeeds magically works
Copy code
fun Application.main() {
    install(DefaultHeaders)
    install(CallLogging)
    install(ContentNegotiation) {
        install(ContentNegotiation) {
            jackson {
                configure(SerializationFeature.INDENT_OUTPUT, true)
                registerModule(JavaTimeModule())
            }
        }
    }

    routing {
       post("/v1/check") {
            try {
                val myObj = call.receive<MyObject>()
                call.respond(HttpStatusCode.OK)
            } catch (e: Exception) {
                call.respond(HttpStatusCode.BadRequest)
            }
        }
    }
}
k
you have duplicate
install(ContentNegotiation)
calls, just a minor oversight