Http

Finagle provides APIs for writing http services and clients.

Server

A minimal HTTP server example is available in the Finagle docs. Essentially it’s a Finagle Service that handles http.Requests and returns http.Responses.

import com.twitter.finagle.{Http, Service}
import com.twitter.finagle.http
import com.twitter.util.{Await, Future}

// the http service
val service = new Service[http.Request, http.Response] {
  def apply(req: http.Request): Future[http.Response] =
    Future.value(
      http.Response(req.version, http.Status.Ok)
    )
}

Starting the http server with a default configuration.

val server = Http.serve(":8080", service)
Await.ready(server)

5xx responses as failures

Finagle is protocol agnostic so it treats a http 5xx as a valid response. The behaviour can be configured with a ResponseClassifier.

import com.twitter.finagle.http.service.HttpResponseClassifier

val server = Http.server
  .withResponseClassifier(HttpResponseClassifier.ServerErrorsAsFailures)
  .serve(":8080", service)
Await.ready(server)

Client

Creating a http client is done via Http.client.

import com.twitter.finagle.{Http, Service}
import com.twitter.finagle.http

val hostname = "gutefrage.net"
val client: Service[http.Request, http.Response] =
  Http.client
      .newService(s"$hostname:80")

HTTPS

For a https connection change the port and add a TLS hostname.

import com.twitter.finagle.{Http, Service}
import com.twitter.finagle.http

val hostname = "gutefrage.net"
val client: Service[Request, Response] =
  Http.client
      .withTls(hostname)
      .newService(s"$hostname:443")

Web Proxy

There is built-in support for tunneling TCP-based protocols through web proxy servers in a default Finagle client that might be used with any TCP traffic, not only HTTP(S). See Squid documentation on this feature.

The following example enables tunneling HTTP traffic through a web proxy server my-proxy-server.com to twitter.com.

HTTP Proxy documentation example

import com.twitter.finagle.{Service, Http}
import com.twitter.finagle.http.{Request, Response}
import com.twitter.finagle.client.Transporter
import java.net.SocketAddress

val twitter: Service[Request, Response] = Http.client
  .configured(Transporter.HttpProxy(Some(
     new InetSocketAddress("my-proxy-server.com", 3128)
  )))
  .withSessionQualifier.noFailFast
  .newService("gutefrage.net")

Service discovery

In general DNS is used for service discovery when using http. However you can also use the zookeeper or other service-discovery methods for http services.