Pekko HTTP
Client and server backed by Pekko HTTP.
As explained in the section Mixed versioning is not allowed in the Pekko documentation, you have to make sure that all the Pekko modules of your application have the same version.
For this reason, the interpreters pekko-http-server
and pekko-http-client
have marked their dependency to Pekko as “provided”.
As a consequence, to use these interpreters you will have to explicitly add a dependency on pekko-stream
:
"org.apache.pekko" %% "pekko-stream" % "<pekko-version>"
Where <pekko-version>
is binary compatible and higher or equal to 1.0.3.
Client
endpoints4s.pekkohttp.client.Endpoints
The Endpoints
interpreter fixes the Endpoint[A, B]
type to a function from A
to Future[B]
:
sourcecase class Endpoint[A, B](
request: Request[A],
response: Response[B]
) extends (A => Future[B])
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:
sourceval eventuallyString: Future[String] = someResource(42)
endpoints4s.pekkohttp.client.ChunkedEntities
The ChunkedEntities
interpreter fixes the Chunks[A]
type to pekko.stream.scaladsl.Source[A, _]
:
sourcetype Chunks[A] = org.apache.pekko.stream.scaladsl.Source[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:
sourceimport org.apache.pekko.stream.scaladsl.Source
val bytesSource: Source[Array[Byte], _] =
Source.futureSource(logo(()))
bytesSource.runForeach { bytes => println(s"Received ${bytes.length} bytes") }
Server
endpoints4s.pekkohttp.server.Endpoints
The Endpoints
interpreter fixes the Endpoint[A, B]
type to something that, given an implementation function A => B
, returns an org.apache.pekko.http.scaladsl.server.Route
that can be integrated to your Pekko HTTP 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 route: Route =
someResource.implementedBy(x => s"Received $x")
Alternatively, there is also a method implementedByAsync
that takes an implementing function returning a Future[B]
.
endpoints4s.pekkohttp.server.ChunkedEntities
The ChunkedEntities
interpreter fixes the Chunks[A]
type to pekko.stream.scaladsl.Source[A, _]
.
For instance, given the following chunked endpoint definition:
sourceval logo: Endpoint[Unit, Chunks[Array[Byte]]] =
endpoint(get(path / "logo.png"), ok(bytesChunksResponse))
It can be implemented as follows:
sourceimport java.nio.file.Paths
import org.apache.pekko.stream.scaladsl.FileIO
val logoRoute: Route =
logo.implementedBy { _ =>
FileIO.fromPath(Paths.get("/foo/bar/logo.png")).map(_.toArray)
}
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 routes constructed by endpoints4s can’t do anything. You have to deal with such errors in the usual Pekko HTTP way: by using an implicit org.apache.pekko.http.scaladsl.server.RejectionHandler
having a handleNotFound
clause.
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.