Http4k

Build Status GitHub license

Http4k is a Kotlin HTTP Framework to help you build scalable, high performance, quick to develop, robust, RESTful web services. Http4k is not a HTTP server but instead provides out of the box integration with multiple JVM based servers. Currently these are Servlets (eg Jetty or Tomcat), Netty, Undertow or Grizzly. Http4k provides modules for common mechanisms such as marshalling, validation, authentication, metrics, so you spend less time doing the plumbing and more time building your actual application.

Release

Current version is 0.90.0 available on maven central.

Gradle:

compile 'com.sksamuel.http4k:http4k-undertow:xxx'

Maven:

<dependency>
    <groupId>com.sksamuel.http4k</groupId>
    <artifactId>http4k-undertow</artifactId>
    <version>xxx</version>
</dependency>

Introduction and Quick Start

The basic construct in http4k is a HttpEndpoint. An endpoint is a HTTP verb, along with a URL to listen on, and a processor function which accepts a HttpRequest and returns a HttpResponse. Endpoints are defined in classes that extend HttpModule, which is the class that provides the DSL for writing endpoints as well as many default processors.

Processors are simply functions in the form HttpRequest => HttpResponse. Processors can return a HttpResponse directly, or invoke a nested processor. For example a processor may perform authentication, check for a cookie, extract a header, etc, and then pass control to a nested processor. Many processors are provided out of the box for common tasks, and so you can build a pipeline very easily. The inner most processor will typically be a functional literal which returns a response by invoking your own logic.

You can also add general purpose functions that are not tied to a particular endpoint, but are executed against many endpoints. These are referred to as HttpFilters, the same as in many other frameworks.

HttpModules are grouped in an instance of HttpContext and that context is used to start the server. Note: Http4k is not a HTTP server itself, but a HTTP framework and routing layer on top of other servers. Supported servers are servlet containers (Tomcat, Jetty, etc), Netty, Grizzly, and Undertow.

The server will listen for requests, pass the request to Scruffy which will find the matching endpoint (if any), invoke that endpoint (or return a 404), and return the generated response. That's all there is to it.

So, lets quickly build a HTTP server that allows us to query, update, and delete users.

Let's define three endpoints.

  • One for GET, to return a user.
  • One for PUT to store a user.
  • And one for DELETE that deletes a user.

To store these users we'll use a mutable map as a simple in-memory database. We'll pre-populate the database with some data.

class UserEndpoints : HttpModule() {

  val users = mutableMapOf(1 -> User(1, "Sam", "sam@domain.com"),
                           2 -> User(2, "Neil", "neil@domain.com"))

  get("user/{id}") { 
    pathParam("id") { id -> // extracts the path param 'id'
      val user = users(id)
      HttpResponse.ok.withEntity(user.name)
    }
  }

  put("user") {
    entityAs[User] { user-> // notice we are marhshalling directly to a User object
      users.put(user.id, user)
      HttpResponse.ok // `ok` is a built in helper response that returns a Http 200 OK
  }

  delete("user/{id}") {
    pathParam("id") { id -> // extracts the path param 'id'
      users.remove(id)
      HttpResponse.ok
    }
  }
}

You can see the three endpoints were created using the HTTP DSL, and you can see the entityAs[T] processor in play. That processors takes the request entity and attempts to marshall it based on the incoming content type. You can also see the pathParam processor which extracts a parameter from the URL.

Now we need to create an instance of a server, add the context and start it up. In this example we will use Netty:

fun main(args: Array<String>) {
  val context = ScruffyContext(UserEndpoints)
  val netty = NettyBootstrap(8080, context)
  netty.start().await()
}

Note: The await() call simply ensures the main thread blocks, so that the process does not immediately exit.

Chapters

Now that you've read the quick start, you know how to write a scruffy application. From here you can read about

  • Processors - more information on how processors tie into endpoints and how to write your own custom processor.
  • Default processors - see a list of the built in processors and how to use them.
  • Servers - setup guide on the different servers that Scruffy supports and how to create and start a server in 2 to 3 lines of code.
  • Filters- pre-process and post-process request/responses for all endpoints using filters.
  • Default filters - see a list of the built in filters and how to use them.
  • Sessions - scruffy supports sessions using pluggable session managers, such as file based or in memory cache using Guava. Also contains a guide on how to write a custom session manager.
  • Media types - explains how to return JSON / XML / other content types from your endpoints using typeclasses.
  • Conversions - scruffy supports many common Scala types as a return and will implicitly convert those to HttpResponses.
  • Websockets - Support websockets as easily as writing a partial function.
  • Listeners - lifecycle listeners that you can register for callbacks on startup, shutdown, request handling, etc
  • Static file endpoint - serve static resources through the scruffy DSL
  • Error handling - how to support server wide exception mapping using partial functions. These can be chained across your modules.
  • Not found handler - how to generate custom 404 pages

Modules

Http4k has a number of optional extra integrations. Please contribute anything you think might be missing!

Jackson

Provides default implementations for the media type serializers. If you are looking for a general purpose serializer that handles JSON / XML or both then include this module and import ScruffyJackson.Implicits._ where a Serializer/Deserializer is required.

Healthcheck

Http4k provides a simple framework for runtime healthchecks of your server and other processes. See healthcheck.md for details on writing custom healthchecks and setting up the framework.

Metrics

Scruffy provides out of the box request/response/system metrics based on the excellent codahale metrics library. See metrics.md for more details on how to use this.

Security

The security add on provides a simple authentication and authorization framework, with built in support for common mechanisms such as BasicAuth and DigestAuth. It is easy to integrate with whatever backing store provides your users details. See security.md for integration guides.

Client

The scruffy-client add on is a stand alone dependency that provides an async client based on the excellent Ning Async-Http project. See client.md for examples on how to make requests using the client.

Release History

1.13.0
  • Websocket support for Netty and Undertow, including new WebsocketModule and DSL.
  • Akka module updated to support websockets
  • Introduced typeclasses for MediaType marshalling to replace Scalper project.
1.12.4
  • Added support for byte arrays and input streams as implicit response types
  • Added CSV metrics output
  • Added path param extractors
1.12.3
  • Added healthcheck module. Inspired by drop-wizard, this is a convenience framework for add custom healthcheck instances, which are then exposed by a /healthcheck endpoint.
  • Breaking change: Renamed providers to HttpModule
  • Endpoints are now resolved in order of most specific to least specific. So /a/{param} will not override /a/b/{param} even if it is defined first.
  • Updated validators to pick up validator from implicit scope
1.12.2
  • Updated static file endpoint to support welcome page and multiple resource roots
  • Enhanced handling of scalaz types as responses
  • Added redirects. If your endpoint returns an instance of Redirect with a relative path then the request will be redirected without a round trip the client.
1.12.1
  • Added static file handling endpoint
  • Added benchmarks for each of the server implementations
  • Added Future[T] => Future[HttpResponse] implicit when T=>HttpResponse in scope to simplify integration with other libraries that use futures.
  • Added support for streaming results by returning InputStream as the response entity
1.12.0
  • Added file system based session manager
  • Improved endpoint DSL for performance.
  • Changed the way endpoints are managed by introducing a ScruffyContext which is used as a mountpoint for endpoint providers. The context is then passed to whatever server implementation you are using.
  • Changed Java requirement to 1.7.
  • Added custom 404 handling
  • Breaking change: Renamed error handling registration method
1.11.1
  • Fixed unbounded thread error in client
  • Added new session processors
1.11.0
  • Added support for Grizzly as a backing server for the Scruffy DSL. Grizzly performs well compared to the other servers, and exceeds Undertow in some internal benchmarks, but support is still new and so we'd still recommend undertow until Grizzly support has been more robustly tested.
1.10.0
  • New metrics module, backed by codahale metrics, capturing number of requests, rate of requests, status codes of all responses, as well as thread and memory usage. Metrics endpoints output in Json and XML. Other outputs include console and JMX.
1.9.0
  • Added support for Undertow as a backing server for the Scruffy DSL. Undertow becomes our recommended choice for new projects as performance metrics indicate it outperforms Netty (although both still continue to be very good).
1.8.1
  • Added support for partial functions for error handling. Invoke errorHandler { } with a partial function of Throwable to Responses to set an error handler.
1.8.0
  • Seperated DSL from Server implementations. Existing Netty server now becomes one implementation of the DSL. Code should be updated to use ScruffyOnNetty as the entry class.

License

This software is licensed under the Apache 2 license, quoted below.

Copyright 2014 Stephen Samuel

Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.