Engines
genhttp-kt is both a HTTP server implementation and a web service application framework. Depending on your requirements, the underlying HTTP engine can be replaced with another web server.
Modules do not depend on the engine: they are written against the API only, and the acceptance tests of
the project run against every engine, as in GenHTTP. This ensures that you can replace the engine without
any further adjustments to your application code - all you change is the dependency and the package of
the Host you import.
Choosing an Engine
| Engine | Package | Good fit for |
|---|---|---|
| Internal | genhttp-core | Embedding into another application, small Docker containers, few dependencies |
| Netty | genhttp-core-netty | High performance on Linux using epoll or io_uring, handlers that suspend rather than block |
Both engines speak HTTP/1.1 (plain and over TLS), keep connections alive and answer pipelined requests. They
differ in how they run your handlers: the internal engine runs every connection on virtual threads, so
blocking calls in a handler are fine, while the Netty engine runs every connection on the event loop that
accepted it, which is faster but must never be blocked. genhttp-full and genhttp-full-netty add all
modules to the respective engine.
GenHTTP runs on its internal engine, on Kestrel and on ioxide. Kestrel is specific to .NET and not available on the JVM; the Netty engine is the counterpart of ioxide.
Detecting the Engine
The engine a server runs on is exposed as Server.serverEngine, a ServerEngine value
(Internal, Netty or Custom - GenHTTP additionally knows Kestrel and Ioxide). Handlers and concerns
receive the server instance in their prepare(server) call, so a module can select an engine-specific code
path during preparation:
class EngineAwareHandler : Handler {
private var optimized = false
override suspend fun prepare(server: Server) {
optimized = server.serverEngine == ServerEngine.Netty
}
override suspend fun handle(request: Request): Response? = null
}A module must provide its functionality independently of the underlying engine and must not fail for an engine it does not recognize, so this field is intended for optional optimizations rather than for business logic. No module of genhttp-kt relies on it today.
Custom Engines
An engine builds on genhttp-engine-shared, which contains what the engines of GenHTTP share as well:
AbstractServerHost implements the ServerHost interface, collects the configuration (endpoints, logging,
development mode) and adds the concerns every engine applies (protocol compliance, error handling, request
logging) to the handler. An engine extends it and creates its Server in build(config, handler) - a
server that reports ServerEngine.Custom.
If you are interested in adding a new engine to the project, feel free to get in touch via GitHub or Discord. The basic requirements are:
- Your engine runs on the JVM
- The engine passes the acceptance tests of the project
- The change does not affect the stability of the CI pipeline of the project