longquanzheng / http4k

The Functional toolkit for Kotlin HTTP applications. http4k provides a simple and uniform way to serve, consume, and test HTTP services.

Home Page:https://http4k.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool


http4k logo

download build status coverage GitHub license kotlin version codebeat awesome kotlin Kotlin Slack back us! sponsor us!


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 ~1mb. 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

Quickstart

Bored with reading already and just want to get coding? For the impatient, visit the quickstart or the examples repo, which showcases a variety of http4k use-cases and features.

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
    • Single Page Application support 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, which are testable without a running container
    • 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
      • Java (bundled with http4k-core)
      • Jetty HTTP (supports sync and async HTTP)
      • OkHttp HTTP (supports sync and async HTTP)
    • 1LOC WebSocket client, with blocking and non-blocking modes
    • GraphQL client (bundled with GraphQL module)
  • Server:
    • 1LOC server backend spin-up for:
      • Apache v4 & v5 (from httpcore)
      • Jetty (including websocket support)
      • Ktor CIO & Netty
      • Netty (including websocket support)
      • SunHttp (bundled with http4k-core)
      • Undertow
    • API design allows for simple customization of underying backend.
    • Native Friendly Several of the supported backends can be compiled with GraalVM and Quarkus with zero configuration.
  • Serverless:
    • AWS Lambda Implement a single Factory method, then upload your http4k applications to AWS Lambda to be called from API Gateway or AppLoadBalancer.
    • Google Cloud Functions Implement a single Factory method, then upload your http4k applications to Google Cloud Functions with GCloud.
    • Apache OpenWhisk Implement a single Factory method, then upload your http4k applications to IBM Cloud/OpenWhisk installations.
    • Azure Functions Implement a single Factory method, then upload your http4k applications to the MS Cloud.
    • Alibaba Function Compute Implement a single Factory method, then upload your http4k applications to Alibaba.
    • Tencent Serverless Cloud Functions Implement a single Factory method, then upload your http4k applications to SCF.
  • 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 v2 and v3 description endpoints including JSON Schema model breakdown.
  • Templating:
    • Pluggable templating system support for:
      • Dust
      • Freemarker
      • Handlebars
      • Pebble
      • Thymeleaf
      • Jade4j
    • Caching and Hot-Reload template support
  • Message formats:
    • Consistent API provides first class support for marshalling formats to/from HTTP messages for:
      • JSON - with support for:
      • XML - includes support for:
        • Jackson - includes support for fully automatic marshalling of Data classes
        • Xml - includes support for one way automatic marshalling of Data classes
      • YAML - includes support for:
        • Jackson - includes support for fully automatic marshalling of Data classes
  • Resilience4J:
    • Support for Circuits, Retrying, Rate-Limiting, Bulkheading via Resilience4J integration
  • Micrometer:
    • Support for plugging http4k apps into Micrometer.
  • OpenTelemetry:
    • Support for instrumenting http4k apps with OpenTelemetry tooling.
  • Multipart:
    • Support for Multipart HTML forms, including Lens extensions for type-safe marshalling of fields.
  • GraphQL:
    • Integration with GraphQL Java library to route and serve Graph-based apps. Plus conversion of any HttpHandler to be a GraphQL client.
  • AWS:
    • Plug a standard HttpHandler into the AWS v2 SDKs. This massively simplifies testing and allows for sniffing of the exact traffic going to AWS - brilliant for debugging and building fakes.
    • 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
  • Cloud Native:
    • Tooling to support operating http4k applications in orchestrated cloud environments such as Kubernetes and CloudFoundry. 12-factor configuration, dual-port servers and health checks such as liveness and readiness checking.
  • WebDriver:
    • Ultra-lightweight Selenium WebDriver implementation for http4k application.
  • Hamkrest:
    • A set of Hamkrest matchers for testing http4k Request and Response messages.
  • Kotest:
    • A set of Kotest matchers for testing http4k Request and Response messages.
  • Approval Testing:
  • 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.
  • Service Virtualisation:
    • Record and replay versioned HTTP contracts to/from Servirtium Markdown format. Includes Servirtium MiTM server and simple JUnit extensions.

Example

This quick example is designed to convey the simplicity & features of http4k . See also the quickstart for the simplest possible starting point and demonstrates how to serve and consume HTTP services with dynamic routing.

To install, add these dependencies to your Gradle file:

dependencies {
    implementation group: "org.http4k", name: "http4k-core", version: "3.283.1"
    implementation group: "org.http4k", name: "http4k-server-jetty", version: "3.283.1"
    implementation group: "org.http4k", name: "http4k-client-okhttp", version: "3.283.1"
}
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() {
    // 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 name: String? = req.path("name")
            Response(OK).body("hello ${name ?: "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 2017 13:01:13 GMT
//    expires: 0
//    server: Jetty(9.3.16.v20170120)
//
//    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.

About

The Functional toolkit for Kotlin HTTP applications. http4k provides a simple and uniform way to serve, consume, and test HTTP services.

https://http4k.org

License:Apache License 2.0


Languages

Language:Kotlin 91.1%Language:JavaScript 6.2%Language:Java 1.8%Language:Shell 0.4%Language:CSS 0.2%Language:HTML 0.1%Language:Python 0.1%Language:Handlebars 0.1%Language:Pug 0.0%