Concerns
Concerns allow to add behavior to a section of your web application by intercepting requests and responses. The framework allows any handler to be extended by using concerns. The following example will add a custom HTTP header to every response generated by the server:
import org.genhttp.api.content.Concern
import org.genhttp.api.content.io.Resource
import org.genhttp.engine.internal.Host
import org.genhttp.modules.io.*
suspend fun main() {
val customConcern = Concern.from { request, content ->
content.handle(request)
?.rebuild()
?.header("X-Custom-Header", "Custom Concern")
?.build()
}
val handler = Content.from(Resource.fromString("Hello World"))
.add(customConcern)
Host.create()
.handler(handler)
.run()
}This code uses a shortcut provided by the IO module (Concern.from { ... }, which
needs import org.genhttp.modules.io.*) to reduce the boilerplate required to implement
the Concern interface. The full version of the example above would look like this:
import org.genhttp.api.content.Concern
import org.genhttp.api.content.ConcernBuilder
import org.genhttp.api.content.Handler
import org.genhttp.api.content.io.Resource
import org.genhttp.api.infrastructure.Server
import org.genhttp.api.protocol.Request
import org.genhttp.api.protocol.Response
import org.genhttp.engine.internal.Host
import org.genhttp.modules.io.*
suspend fun main() {
val handler = Content.from(Resource.fromString("Hello World"))
.add(CustomConcernBuilder())
Host.create()
.handler(handler)
.run()
}
class CustomConcern(override val content: Handler) : Concern {
override suspend fun prepare(server: Server) = content.prepare(server)
override suspend fun handle(request: Request): Response? =
content.handle(request)
?.rebuild()
?.header("X-Custom-Header", "Custom Concern")
?.build()
}
class CustomConcernBuilder : ConcernBuilder {
override fun build(content: Handler): Concern = CustomConcern(content)
}genhttp-kt uses the same mechanism to achieve functionality such as compression or support for CORS.
If your concern reads additional headers or generates additional responses, you can implement
DocumentedConcern instead to add this functionality to the specification generated by the
Open API concern.