Judging by the <https://ktor.io/docs/default-reque...
# ktor
s
Judging by the https://ktor.io/docs/default-request.html docs, I would think I was supposed to be in the scope of an
HttpRequestBuilder
when configuring
DefaultRequest
, but I'm instead in the scope of a
DefaultRequestBuilder
. AFAICT, they don't share the same structure. Previously, in ktor-client v1.6.7, I was able to access
body
inside of this builder scope, but no more. Docs:
Copy code
val client = HttpClient(CIO) {
    defaultRequest {
        // this: HttpRequestBuilder
    }
}
Actual (ktor-client-core-jvm-2.0.0.jar):
Copy code
public class DefaultRequest private constructor(private val block: DefaultRequestBuilder.() -> Unit) {

    public companion object Plugin : HttpClientPlugin<DefaultRequestBuilder, DefaultRequest> {
        // ...
    }

    // ...
}

// Hence:

defaultRequest {
    // this: io.ktor.client.plugins.DefaultRequest.DefaultRequestBuilder
}
Is this by design? Are the docs wrong here?
h
Yeah, the docs are incorrect. What is the use-case for setting a default body?
s
Great question. I see that we're checking if the type of the body is a
FormDataContent
and if it is, we're overriding the content type of the request. I'm not sure of the reasoning behind this, though, but I'm assuming there is one. 😅
a
Yes. This is by design and documentation is incorrect. Could you please describe why do you need to change a content type?
s
I'm investigating why right now, but AFAICT, it's really no reason to. We're doing a
.submitForm
and changing the Content-Type to application/json, when we should probably just to a regular
.post
, so I'm gonna try that now. 😅
Thanks for the link and explanation. 😁
So, we're setting the Content-Type for all requests to application/json because we want the JSON serialization to kick in on all requests. But we wanted to not set it for form submissions, hence the body type check. But I figured we don't really need to submit form data in those couple of places we did, so it's all good. 👍
But is setting Content-Type to application/json the Correct Way™ to make sure that the
ContentNegotiation
plugin (configured with
io.ktor.serialization.kotlinx.json.JsonSupportKt#json()
) kicks in and serializes the body, or is there a more correct approach to that?
a
Yes, it’s the right way. The only problem is that
MultiPartFormDataContent
sets the
Content-Type
with a boundary so you can’t just override the header manually.
s
But if I set a Content-Type application/json in
defaultRequest
and make a request using
submitForm()
, it would still be using the application/json (default request) Content-Type, right? I imagine that's the reason we had that check in the first place. Or will
MultiPartFormDataContent
then make sure that the Content-Type is overridden from application/json to the proper Content-Type?
a
But if I set a Content-Type application/json in
defaultRequest
and make a request using
submitForm()
, it would still be using the application/json (default request) Content-Type, right?
Yes. And if the
ContentNegotiation
plugin is installed then it will try to serialize an
MultiPartFormDataContent
object.
s
Right! I believe that was the reason we had the body check, in that case, so we only set application/json for non-multipart request bodies.