gtfhxy
gtfhxy

Reputation: 25

How to get http body of call.reponse in Ktor?

I build a web server with Ktor, and want to cache API method result. But I don't know how to get the response body from call.response. Code like below

fun Application.module(){

    // before method was called
    intercept(ApplicationCallPipeline.Features) {
        val cache = redis.get("cache")
        if(cache) {
            call.respond(cache)
        }

        return @intercept finish()
    }
    
    // after method was called
    intercept(ApplicationCallPipeline.Fallback) {
        // TODO, how to get call.response.body
        redis.set("cache", call.response.body)
    }
}

If I can't get the response body, Any other solution to cache the result of an API method in Ktor?

Upvotes: 2

Views: 2070

Answers (1)

Aleksei Tirman
Aleksei Tirman

Reputation: 7079

Inside an interceptor, for the ApplicationCallPipeline.Features phase you can add a phase just before the ApplicationSendPipeline.Engine and intercept it to retreive a response body (content):

val phase = PipelinePhase("phase")
call.response.pipeline.insertPhaseBefore(ApplicationSendPipeline.Engine, phase)
call.response.pipeline.intercept(phase) { response ->
    val content: ByteReadChannel = when (response) {
        is OutgoingContent.ByteArrayContent -> ByteReadChannel(response.bytes())
        is OutgoingContent.NoContent -> ByteReadChannel.Empty
        is OutgoingContent.ReadChannelContent -> response.readFrom()
        is OutgoingContent.WriteChannelContent -> GlobalScope.writer(coroutineContext, autoFlush = true) {
            response.writeTo(channel)
        }.channel
        else -> error("")
    }

    // Do something with content
}

Upvotes: 2

Related Questions