http4k is a "Server as a Function" HTTP toolkit written in Kotlin with a focus on simple, testable APIs
Switch branches/tags
Nothing to show
Clone or download
Permalink
Failed to load latest commit information.
.github Release 2.26.0 Sep 9, 2017
gradle/wrapper [Tom] updating packages to the point where http4k builds on java 10 w… Apr 16, 2018
http4k-aws Fix #165 Aug 21, 2018
http4k-client-apache-async inlined asClientError so we just have description now Jul 25, 2018
http4k-client-apache pulling out smaller classes from complex ones Sep 15, 2018
http4k-client-jetty inlined asClientError so we just have description now Jul 25, 2018
http4k-client-okhttp upgrade http libs Aug 27, 2018
http4k-client-websocket pulling out smaller classes from complex ones Sep 15, 2018
http4k-contract new request tests Aug 27, 2018
http4k-core fixed all but one test of RPC contracts Sep 15, 2018
http4k-format-argo Fix Argo and Gson json-rpc contract test for invalid request (#180) Sep 17, 2018
http4k-format-gson Fix Argo and Gson json-rpc contract test for invalid request (#180) Sep 17, 2018
http4k-format-jackson fixed all but one test of RPC contracts Sep 15, 2018
http4k-format-moshi add duration to JSON auto-marshalling Aug 12, 2018
http4k-format-xml update dependencies Sep 16, 2018
http4k-incubator fix up changes to micrometer API Sep 16, 2018
http4k-jsonrpc Simplify json-rpc lenses to only need one generic mapping one (#181) Sep 17, 2018
http4k-metrics-micrometer fix up changes to micrometer API Sep 16, 2018
http4k-multipart coverage for multipart Aug 27, 2018
http4k-resilience4j update dependencies Sep 16, 2018
http4k-security-oauth test for oauth providers Aug 27, 2018
http4k-server-apache update dependencies Sep 16, 2018
http4k-server-jetty tidy folds Aug 12, 2018
http4k-server-netty remove apache dependencies from wherever possible Aug 9, 2018
http4k-server-undertow update dependencies Sep 16, 2018
http4k-serverless-lambda code tidy - intellij warnings fixed Jul 27, 2018
http4k-template-dust code tidy - intellij warnings fixed Jul 27, 2018
http4k-template-handlebars tweak to templates Jun 30, 2018
http4k-template-pebble Fix #142 - Pebble templates don't load from JAR files Jun 30, 2018
http4k-template-thymeleaf code tidy - intellij warnings fixed Jul 27, 2018
http4k-testing-chaos fix chaos pattern Sep 12, 2018
http4k-testing-hamkrest Fix #168 Aug 27, 2018
http4k-testing-webdriver improve web driver support for forms Sep 3, 2018
src fix up changes to micrometer API Sep 16, 2018
tools fix publish script to upgrade versions Apr 29, 2017
.codebeatignore ignore apache code Oct 20, 2017
.gitignore nano record Aug 30, 2018
.travis.yml try to only build various stages in master (#182) Sep 17, 2018
CHANGELOG.md fix chaos pattern Sep 12, 2018
CONTRIBUTING.md update to contributiing Aug 26, 2018
LICENSE adding license May 3, 2017
README.md Release 3.38.1 Sep 12, 2018
build.gradle add incubator to main project Aug 26, 2018
build.sh moved methods from being extension methods to part of HttpMessage May 3, 2017
delete_version.sh Chaos testing module (#130) Jun 22, 2018
dependencies.gradle update dependencies Sep 16, 2018
gradlew Initial commit Mar 23, 2017
gradlew.bat Upgrade gradle to 2.14.1 (minimum version required for bintray) Mar 31, 2017
release-api.sh release API docs Apr 24, 2018
release-ci.sh json rpc refactoring Sep 12, 2018
release-maven-central.sh added incubator module, and move new resource loading code into it. Aug 26, 2018
release-site.sh Changed doc invocation via YML as per Travis's suggestion for avoidin… Jun 28, 2018
release.sh add missing set -e to site scriptπ Sep 25, 2017
requirements.txt test checkin Jan 25, 2018
serve-site.sh rename scripts Jun 11, 2017
settings.gradle added incubator module, and move new resource loading code into it. Aug 26, 2018
version.json Release 3.38.1 Sep 12, 2018

README.md

Download build status coverage GitHub license kotlin codebeat badge Awesome Kotlin Badge
build status build status

http4k is a lightweight but fully-featured HTTP toolkit written in pure Kotlin that enables the serving and consuming of HTTP services in a functional and consistent way. http4k applications are just Kotlin functions which can be mounted into a running backend. For example, here's a simple echo server:

 val app: HttpHandler = { request: Request -> Response(OK).body(request.body) }
 val server = app.asServer(SunHttp(8000)).start()

http4k consists of a core library, http4k-core, providing a base HTTP implementation + a number of capability abstractions (such as servers, clients, templating, websockets etc). These capabilities are then implemented in add-on modules.

The principles of http4k are:

  • Application as a Function: Based on the Twitter paper "Your Server as a Function", all HTTP services can be composed of 2 types of simple function:
    • HttpHandler: (Request) -> Response - provides a remote call for processing a Request.
    • Filter: (HttpHandler) -> HttpHandler - adds Request/Response pre/post processing. These filters are composed to make stacks of reusable behaviour that can then be applied to an HttpHandler.
  • Immutability: All entities in the library are immutable unless their function explicitly disallows this.
  • Symmetric: The HttpHandler interface is identical for both HTTP services and clients. This allows for simple offline testability of applications, as well as plugging together of services without HTTP container being required.
  • Dependency-lite: Apart the from Kotlin StdLib, http4k-core module has ZERO dependencies and weighs in at ~700kb. Add-on modules only have dependencies required for specific implementation.
  • Testability Built by TDD enthusiasts, so supports super-easy mechanisms for both In and Out of Container testing of:
    • individual endpoints
    • applications
    • websockets
    • full suites of microservices
  • Modularity: Common behaviours are abstracted into the http4k-core module. Current add-on modules provide:
    • Pluggable HTTP client adapters for Apache, Jetty, OkHttp and Websockets
    • Pluggable Server backends: Single LOC Server spinup for Jetty, Netty, Undertow, Apache (Httpcore) and SunHttp.
    • Serverless backends: Test your application locally and then deploy it to AWS Lambda.
    • Templating support: Caching and Hot-Reload engine support for Handlebars, Pebble, Dust and Thymeleaf
    • HTTP message adapters for Argo JSON, Gson JSON, Jackson JSON, Moshi JSON and XML - includes auto-marshalling capabilities to convert directly to Kotlin data classes.
    • Typesafe, auto-validating, self-documenting (via OpenApi/Swagger) contracts for HTTP services
    • AWS request signing: super-simple interactions with AWS services.
    • Metrics gathering for performance analysis.
    • Multipart form handling, including stream processing for uploaded files.
    • Resilience features: Circuits, retrying, rate limiting, bulkheading - via Resilience4J integration.
    • Security: Simple, pluggable support for OAuth Auth Code Grant flow and ready made configurations to integrate with popular OAuth providers.
    • Testing: Selenium WebDriver implementation for lightning fast, browserless testing of http4k apps
    • Testing: Hamkrest Matchers for http4k objects.
    • Testing: Chaos Injection mechanism, allowing simple, dynamic injection of failure modes into http4k applications.

Module feature overview

  • Core:
    • Base HTTP handler and immutable HTTP message objects, cookie handling.
    • Commonly used HTTP functionalities provided as reusable Filters (caching, debugging, Zipkin request tracing)
    • Path-based routing, including nestable contexts
    • Typesafe HTTP message construction/desconstruction and Request Contexts using Lenses
    • Static file-serving capability with Caching and Hot-Reload
    • Servlet implementation to allow plugin to any Servlet container
    • Launch applications in 1LOC with an embedded SunHttp server backend (recommended for development use only)
    • Path-based websockets including typesafe message marshalling using Lenses
    • APIs to record and replay HTTP traffic to disk or memory
    • Core abstraction APIs implemented by the other modules
  • Client:
    • 1LOC client adapters
      • Apache sync + async HTTP
      • Jetty HTTP (supports sync and async HTTP)
      • OkHttp HTTP (supports sync and async HTTP)
      • Java (bundled with http4k-core)
    • 1LOC WebSocket client, with blocking and non-blocking modes
  • Server:
    • 1LOC server backend spinup for:
      • Jetty (including websocket support)
      • Netty
      • Undertow
      • Apache (from httpcore)
      • SunHttp (bundled with http4k-core)
    • API design allows for plugging into configurable instances of each
  • Serverless:
    • Implement a single Factory method, then upload your http4k applications to AWS Lambda to be called from API Gateway.
  • Contracts:
    • Define Typesafe HTTP contracts, with required and optional path/query/header/bodies
    • Typesafe path matching
    • Auto-validation of incoming requests == zero boilerplate validation code
    • Self-documenting for all routes - eg. Built in support for live OpenApi/Swagger description endpoints including JSON Schema model breakdown.
  • Templating:
    • Pluggable templating system support for:
      • Dust
      • Handlebars
      • Pebble
      • Thymeleaf
    • Caching and Hot-Reload template support
  • Message formats:
    • Consistent API provides first class support for marshalling JSON to/from HTTP messages for:
  • Resilience:
    • Support for Circuits, Retrying, Rate-Limiting, Bulkheading via Resilience4J integration.
  • Metrics:
    • Support for plugging http4k apps into micrometer
  • Multipart:
    • Support for Multipart HTML forms, including Lens extensions for type-safe marshalling of fields.
  • AWS:
    • Client filter to allow super-simple interaction with AWS services (via request signing)
  • OAuth Security
    • Implement OAuth Authorisation Code Grant flow with a single Interface
    • Pre-configured OAuth for following providers:
      • Auth0
      • Dropbox
      • Google
      • Soundcloud
  • WebDriver:
    • Ultra-lightweight Selenium WebDriver implementation for http4k application.
  • Hamkrest:
    • A set of Hamkrest matchers for testing http4k Request and Response messages.
  • Chaos:
    • API for declaring and injecting failure modes into http4k applications, allowing modelling and hence answering of "what if" style questions to help understand how code fares under failure conditions such as latency and dying processes.

Example

This quick example is designed to convey the simplicity & features of http4k . See also the quickstart for the simplest possible starting point.

To install, add these dependencies to your Gradle file:

dependencies {
    compile group: "org.http4k", name: "http4k-core", version: "3.38.1"
    compile group: "org.http4k", name: "http4k-server-jetty", version: "3.38.1"
    compile group: "org.http4k", name: "http4k-client-okhttp", version: "3.38.1"
}

This "Hello World" style example () demonstrates how to serve and consume HTTP services with dynamic routing:

package cookbook

import org.http4k.client.OkHttp
import org.http4k.core.Filter
import org.http4k.core.HttpHandler
import org.http4k.core.Method.GET
import org.http4k.core.Request
import org.http4k.core.Response
import org.http4k.core.Status.Companion.OK
import org.http4k.core.then
import org.http4k.filter.CachingFilters
import org.http4k.routing.bind
import org.http4k.routing.path
import org.http4k.routing.routes
import org.http4k.server.Jetty
import org.http4k.server.asServer

fun main(args: Array<String>) {
    // we can bind HttpHandlers (which are just functions from  Request -> Response) to paths/methods to create a Route,
    // then combine many Routes together to make another HttpHandler
    val app: HttpHandler = routes(
        "/ping" bind GET to { _: Request -> Response(OK).body("pong!") },
        "/greet/{name}" bind GET to { req: Request ->
            val path: String? = req.path("name")
            Response(OK).body("hello ${path ?: "anon!"}")
        }
    )

    // call the handler in-memory without spinning up a server
    val inMemoryResponse: Response = app(Request(GET, "/greet/Bob"))
    println(inMemoryResponse)

// Produces:
//    HTTP/1.1 200 OK
//
//
//    hello Bob

    // this is a Filter - it performs pre/post processing on a request or response
    val timingFilter = Filter {
        next: HttpHandler ->
        {
            request: Request ->
            val start = System.currentTimeMillis()
            val response = next(request)
            val latency = System.currentTimeMillis() - start
            println("Request to ${request.uri} took ${latency}ms")
            response
        }
    }

    // we can "stack" filters to create reusable units, and then apply them to an HttpHandler
    val compositeFilter = CachingFilters.Response.NoCache().then(timingFilter)
    val filteredApp: HttpHandler = compositeFilter.then(app)

    // only 1 LOC to mount an app and start it in a container
    filteredApp.asServer(Jetty(9000)).start()

    // HTTP clients are also HttpHandlers!
    val client: HttpHandler = OkHttp()

    val networkResponse: Response = client(Request(GET, "http://localhost:9000/greet/Bob"))
    println(networkResponse)

// Produces:
//    Request to /api/greet/Bob took 1ms
//    HTTP/1.1 200
//    cache-control: private, must-revalidate
//    content-length: 9
//    date: Thu, 08 Jun 3.38.13:01:13 GMT
//    expires: 0
//    server: Jetty(9.3.16.v3.38.120)
//
//    hello Bob
}

Acknowledgments

Contributors

This project exists thanks to all the people who contribute.

Backers & Sponsors

If you use http4k in your project or enterprise and would like to support ongoing development, please consider becoming a backer or a sponsor. Sponsor logos will show up here with a link to your website.