http4s

Client and server backed by http4s.

Client

API documentation

endpoints4s.http4s.client.Endpoints

The Endpoints interpreter provides a trait Endpoint[A, B] with methods send and sendAndConsume, to invoke an endpoint.

This means that, given the following endpoint definition:

sourceval someResource: Endpoint[Int, String] =
  endpoint(get(path / "some-resource" / segment[Int]()), ok(textResponse))

It can be invoked as follows using IO:

sourceval eventuallyString: IO[String] = someResource.sendAndConsume(42)

ChunkedEntities

The ChunkedEntities interpreter fixes the Chunks[A] type to fs2.Stream[Effect, A]:

sourcetype Chunks[A] = fs2.Stream[Effect, A]

This means that, given the following endpoint definition:

sourceval logo: Endpoint[Unit, Chunks[Array[Byte]]] =
  endpoint(get(path / "logo.png"), ok(bytesChunksResponse))

It can be invoked as follows:

sourceval bytesSource: Resource[Effect, fs2.Stream[Effect, Array[Byte]]] =
  logo.send(())

bytesSource.use(stream =>
  stream.evalMap { bytes => IO(println(s"Received ${bytes.length} bytes")) }.compile.drain
)

Server

API documentation

endpoints4s.http4s.server.Endpoints

The Endpoints interpreter provides a routesFromEndpoints operation that turns a sequence of endpoints with their implementation into an org.http4s.HttpRoutes[F] value that can be integrated to your http4s application.

For instance, given the following endpoint definition:

sourceval someResource: Endpoint[Int, String] =
  endpoint(get(path / "some-resource" / segment[Int]()), ok(textResponse))

It can be implemented as follows:

sourceval routes: HttpRoutes[IO] = HttpRoutes.of(
  routesFromEndpoints(
    someResource.implementedBy(x => s"Received $x")
  )
)

The result is a regular value of type org.http4s.HttpRoute[IO] that can be integrated in your application like any other http4s service.

Error handling

When the server processes requests, three kinds of errors can happen: the incoming request doesn’t match any endpoint, the request does match an endpoint but is invalid (e.g. one parameter has a wrong type), or an exception is thrown.

The incoming request doesn’t match any endpoint

In that case, the router constructed by endpoints4s can’t do anything. You have to deal with such errors in the usual http4s way (usually, by adding a .orNotFound call to your application services).

The incoming request is invalid

In that case, endpoints4s returns a “Bad Request” (400) response reporting all the errors in a JSON array. You can change this behavior by overriding the handleClientErrors method.

An exception is thrown

If an exception is thrown during request decoding, or when running the business logic, or when encoding the response, endpoints4s returns an “Internal Server Error” (500) response reporting the error in a JSON array. You can change this behavior by overriding the handleServerError method.