io

finch

package finch

This is a root package of the Finch library, which provides an immutable layer of functions and types atop of Finagle for writing lightweight HTTP services. It roughly contains three packages: io.finch.route, io.finch.request, io.finch.response, which correspond to three simple steps to a robust REST/HTTP API:

Step 1. Routing the HTTP requests to a Service.

The Router abstraction routes the requests depending on their path and method information. Router combinator provides a bunch of predefined routers handling separated parts of a route. Routers might be composed with either / (andThen) or /> (map) operator. There is also | (orElse) operator that combines two routers in terms of the inclusive or operator.

val router: Endpoint[HttpRequest, HttpResponse] =
  Get / ("users" | "user") / int /> GetUser

Step 2. Reading the HTTP requests in a Service.

The RequestReader abstraction is responsible for reading any details form the HTTP request. RequestReader is composable in both ways: via the monadic API (using the for-comprehension, i.e., flatMap) and via the applicative API (using the ~ operator). These approaches define an unlimited number of readers out the plenty of predefined ones.

val pagination: RequestReader[(Int, Int)] =
  OptionalParam("offset").as[Int] ~ OptionalParam("limit").as[Int] map {
    case offset ~ limit => (offset.getOrElse(0), limit.getOrElse(100))
  }
val p = pagination(request)

Step 3. Building the HTTP responses in a Service.

The ResponseBuilder abstraction provides a convenient way of building the HTTP responses any type. In fact, ResponseBuilder is a function that takes some content and builds an HTTP response of a type depending on a content. There are plenty of predefined builders that might be used directly.

val ok: HttpResponse = Ok("Hello, world!") // plain/text HTTP response with status code 200
Linear Supertypes
Ordering
  1. Alphabetic
  2. By inheritance
Inherited
  1. finch
  2. AnyRef
  3. Any
  1. Hide All
  2. Show all
Learn more about member selection
Visibility
  1. Public
  2. All

Type Members

  1. implicit final class AnyOps[A] extends AnyVal

    Alters any object within a toFuture method.

    Alters any object within a toFuture method.

    A

    an object type

  2. trait Endpoint[Req, Rep] extends AnyRef

    A REST API endpoint that primary defines a route and might be implicitly converted into Finagle service Service[Req, Rep] if there is an implicit view from Req to HttpRequest available in the scope.

    A REST API endpoint that primary defines a route and might be implicitly converted into Finagle service Service[Req, Rep] if there is an implicit view from Req to HttpRequest available in the scope.

    Req

    the request type

    Rep

    the response type

  3. implicit final class FilterOps[ReqIn, ReqOut, RepIn, RepOut] extends AnyVal

    Alters underlying filter within ! methods composing a filter with a given endpoint or withing a next filter.

  4. type HttpRequest = Request

    An alias for httpx.Request.

  5. type HttpResponse = Response

    An alias for httpx.Response.

  6. implicit class ServiceOps[Req, RepIn] extends AnyRef

    Alters underlying service within afterThat method composing a service with a given filter.

    Alters underlying service within afterThat method composing a service with a given filter.

    RepIn

    a input response type

  7. implicit final class ThrowableOps extends AnyVal

    Alters any throwable with a toFutureException method.

Value Members

  1. object Endpoint

    A companion object for Endpoint

  2. implicit def endpointToService[Req, Rep](e: Endpoint[Req, Rep])(implicit ev: (Req) ⇒ HttpRequest): Service[Req, Rep]

    Allows to use an Endpoint when Service is expected.

    Allows to use an Endpoint when Service is expected. The implicit conversion is possible if there is an implicit view from Req to HttpRequest available in the scope.

    val e: Endpoint[HttpRequest, HttpResponse] = ???
    Httpx.serve(new InetSocketAddress(8081), e)
    Req

    the request type

    Rep

    the response type

    e

    the endpoint to convert

    ev

    the evidence of implicit view

    returns

    a service that delegates the requests to the underlying endpoint

  3. implicit def futureToService[Req, Rep](f: Future[Rep]): Service[Req, Rep]

    Allows for the creation of Endpoints without an explicit service.

    Allows for the creation of Endpoints without an explicit service.

    Endpoint {
      Method.Get -> Root / "hello" => Ok("world").toFuture
    }
    f

    a future to implicitly convert

    returns

    a service generated by ignoring the Req and returning the Future[Rep]

  4. package micro

    An experimental package that enables a secret Finch mode: "Your REST API as a Monad".

    An experimental package that enables a secret Finch mode: "Your REST API as a Monad". The idea is to replace Service with RequestReader. Both RequestReader and Service do similar things, process request (they both functions Req => Future[Rep]), but the RequestReader is insanely composable (being a monad), so it makes sense to route request directly to RequestReader. Thus, an Endpoint is Router[RequestReader[HttpResponse]].

    The high-level idea behind this package is to allow users to work the domain types that matter rather than deal with raw HTTP types directly.

    In order to make things clear, this package introduces a new type Micro (from "microservice"), which is actually an alias to RequestReader, since it's no longer a reader but _processor_.

    See this gist for more details.

  5. package request

    This package introduces types and functions that enable _request processing_ in Finch.

    This package introduces types and functions that enable _request processing_ in Finch. The io.finch.request primitives allow both to _read_ the various request items (query string param, header and cookie) using the RequestReader and _validate_ them using the ValidationRule.

    The cornerstone abstraction of this package is a RequestReader, which is responsible for reading any amount of data from the HTTP request. RequestReaders might be composed with each other using either monadic API (flatMap method) or applicative API (~ method). Regardless the API used for RequestReaders composition, the main idea behind it is to use primitive readers (i.e., RequiredParam, OptionalParam) in order to _compose_ them together and _map_ to the application domain data.

    case class Complex(r: Double, i: Double)
    val complex: RequestReader[Complex] =
      param("real").as[Double] ~
      paramOption("imaginary").as[Double].withDefault(0.0) ~> Complex

    A ValidationRule enables a reusable way of defining a validation rules in the application domain. It might be composed with RequestReaders using either should or shouldNot methods and with other ValidationRules using logical methods and and or.

    case class User(name: String, age: Int)
    val user: RequestReader[User] =
      param("name") should beLongerThan(3) ~
      param("age").as[Int] should (beGreaterThan(0) and beLessThan(120)) ~> User
  6. package response

    This package enables a reasonable approach of building HTTP responses using the ResponseBuilder abstraction.

    This package enables a reasonable approach of building HTTP responses using the ResponseBuilder abstraction. The ResponseBuilder provides an immutable way of building concrete Response instances by specifying their status, headers and cookies. There are plenty of predefined builders named by HTTP statuses, i.e., Ok, Created, NotFound. Thus, the typical use case of the ResponseBuilder abstraction involves usage of concrete builder instead of abstract ResponseBuilder itself.

    val ok: HttpResponse = Ok("Hello, World!")

    In addition to plain/text responses, the ResponseBuilder is able to build any response, whose content-type is specified by an implicit type-class EncodeResponse instance. In fact, any type A may be passed to a RequestReader if there is a corresponding EncodeRequest[A] instance available in the scope.

    implicit val encodeBigInt = EncodeResponse[BigInt]("plain/text") { _.toString }
    val ok: HttpResponse = Ok(BigInt(100))
  7. package route

    This package contains various of functions and types that enable _router combinators_ in Finch.

    This package contains various of functions and types that enable _router combinators_ in Finch. A Finch Router is an abstraction that is responsible for routing the HTTP requests using their method and path information. There are two types of routers in Finch: Router0 and RouterN. Router0 matches the route and returns an Option of the rest of the route. RouterN[A] (or just Router[A]) in addition to the Router0 behaviour extracts a value of type A from the route.

    A Router that maps route to a Service is called an Endpoint. An endpoint Req => Rep might be implicitly converted into a Service[Req, Rep]. Thus, the following example is a valid Finch code:

    def hello(s: String) = new Service[HttRequest, HttpResponse] {
      def apply(req: HttpRequest) = Ok(s"Hello $name!").toFuture
    }
    
    Httpx.serve(
      new InetSocketAddress(8081),
      Get / string /> hello // will be implicitly converted into service
    )

Inherited from AnyRef

Inherited from Any

Ungrouped