Finch 101:

HTTP APIs with Finagle, TwitterServer and Finch

@vkostyukov

$ whoami

Agenda

  • Finagle HTTP
  • "Hello, World", Clients/Servers/Services, Stack API
  • Finch
  • "Hello, World", Routers, RequestReaders, Shapeless, circe, TodoBackend
  • TwitterServer
  • Metrics, Flags, HTTP Admin Interface

Finagle: Status

Finagle: Who is using?

  • Foursquare
  • PagerDuty
  • Pinterest
  • Rdio
  • SoundCloud
  • Strava
  • ... and many more

Finagle: @Twitter

Demo: finagle hello world

Your Server as a Function

trait Service[-Req, +Req] extends (Req => Future[Rep])

Servers, Clients, Services, oh my!

  • Services are symmetric
  • Clients produce (i.e., Httpx.client.newService) Services
  • Servers serve (i.e., Httpx.server.serve) Services
  • Conventional API pattern: <Protocol>.client and <Protocol>.server

Demo: finagle http proxy

Stack API

  • A modern replacement for ClientBuilder and ServerBuilder
  • Servers and Clients are backed by a Stack of modules (ServiceFactories)
  • Allows the user to configure or transform ("an expert-level API") the underlying Stack

Demo: finagle stack params

Demo: finch hello world

Finch: Why?

Finch: Status

Finch affects the Scala community!

Finch: @Twitter

  • Finch is an OSS, a community-driven project that is happened to be maintained by two Twitter engineers
  • Finch is neither used nor developed at Twitter

Demo: finch greetings

RequestReaders

trait RequestReader[A] extends (Request => Future[A]) {
  def ::[B](that: RequestReader[B]): RequestReader[A :: B :: HNil]
}
...
def param(name: String): RequestReader[String] = ???
def paramOption(name: String): RequesReader[Option[String]] = ???
val body: RequestReader[String] = ???
val bodyOption: RequestReader[Option[String]] = ???
...

Routers

trait Router[A] extends (Input => Option[(Input, () => Future[A])]) {
  def /[B](that: Router[B]): Router[A :: B :: HNil]
  def :+:[B](that: Router[B]): Router[A :+: B :+: CNil]
  def ?[B](that: RequestReader[B]): Router[A :: B :: HNil]
}
...
val int: Router[Int] = ???
val string: Router[String] = ???
...

Demo: Shapeless and Circe

TodoBackend.com

  • Endpoints
  • GET /todos; POST /todos; PATCH /todos/:id
    DELETE /todos/:id; DELETE /todos
  • Model
  • case class Todo(
      id: String, title: String, completed: Boolean, order: Int
    )

Demo: todobackend

TwitterServer

TwitterServer: What is inside?

  • HTTP Admin interface
  • Metrics
  • Flags
  • Lifecycle Management
  • ... and more

Demo: twitterserver

How to contribute to Finch?

Want to join the CSL team?

http://vkostyukov.ru/slides/finch-101

https://github.com/vkostyukov/finch-101

https://github.com/finagle/finch