Skip to content

Commit

Permalink
http clients
Browse files Browse the repository at this point in the history
  • Loading branch information
daviddenton committed Apr 2, 2017
1 parent c472e60 commit a123777
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 16 deletions.
48 changes: 46 additions & 2 deletions src/main/hugosite2/content/cookbook/http-clients.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,51 @@
+++
title = "http clients"
tags = ["client", "finagle api", "getting started"]
tags = ["client", "ssl", "secure", "finagle api", "getting started"]
categories = ["recipe"]
+++

hello
Unlike traditional HTTP client libraries, **Finagle HTTP clients are configured to only talk to a single service** using one or more hosts that are known at creation time of that client.

### Simple HTTP
```scala
import com.twitter.finagle.{Http, Service}
import com.twitter.finagle.http.{Request, Response, Status}
import com.twitter.util.Future

val client = Http.newService("pokeapi.co:80")
val futureOk = client(Request("/")) // eventually yields some JSON from the pokemon api
```

### HTTP 1.1 compliance
Currently, Finagle does not add the HTTP-required Host header by default - this can cause problems talking to some HTTP services. To work around this, we can use a Fintrospect provided `Filter`:
```scala
import com.twitter.finagle.Http
import com.twitter.finagle.http.Request
import com.twitter.util.Await.result
import io.fintrospect.configuration.{Host, Port}
import io.fintrospect.filters.RequestFilters.AddHost

val authority = Host("pokeapi.co").toAuthority(Port._80)
val client = AddHost(authority).andThen(Http.newService(authority.toString))
val futureOk = client(Request("/")) // eventually yields some JSON from the pokemon api
```

### Secure communication using TLS
TLS support needs to be explicitly enabled for the HTTP codec. Below we are also using a Fintrospect `Filter` to add the GitHub required `User-Agent` header to all requests:
```scala
import com.twitter.finagle.Http
import com.twitter.finagle.http.Request
import com.twitter.util.Await.result
import io.fintrospect.filters.RequestFilters.AddUserAgent

val client = Http.client.withTls("api.github.com").newService("api.github.com:443")

val request = Request("/users/daviddenton/repos")

AddUserAgent("Fintrospect client").andThen(client)(request) // eventually yields some json
```

## Further reading
<a name="reading"></a>

- Finagle Clients [guide](https://twitter.github.io/finagle/guide/Clients.html)
8 changes: 4 additions & 4 deletions src/main/hugosite2/content/cookbook/services-and-filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ import com.twitter.finagle.{Http, Service}
import com.twitter.finagle.http.{Request, Response, Status}
import com.twitter.util.Future

val httpServer = Http.serve(":9999", Service.mk { in:Request => Future(Response(Status.Ok)) })
val futureOk = httpServer(Request()) // eventually yields an empty Ok response
val server = Http.serve(":9999", Service.mk { in:Request => Future(Response(Status.Ok)) })
val futureOk = server(Request("/")) // eventually yields an empty Ok response
```

And here is the equivalent for creating an HTTP client. See the [Client recipe](../http-clients) for more examples:
Expand All @@ -44,8 +44,8 @@ import com.twitter.finagle.{Http, Service}
import com.twitter.finagle.http.{Request, Response, Status}
import com.twitter.util.Future

val httpClient = Http.newService("localhost:9999")
val futureOk = httpClient(Request()) // eventually yields an empty Ok response
val client = Http.newService("pokeapi.co:80")
val futureOk = client(Request("/")) // eventually yields some JSON from the pokemon api
```

## Filters
Expand Down
14 changes: 8 additions & 6 deletions src/test/scala/cookbook/finagle/Http1dot1_Client_Example.scala
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package cookbook.finagle

import com.twitter.finagle.Http
import com.twitter.finagle.http.Request
import com.twitter.util.Await.result
import io.fintrospect.configuration.{Host, Port}
import io.fintrospect.filters.RequestFilters


object Http1dot1_Client_Example extends App {

import com.twitter.finagle.Http
import com.twitter.finagle.http.Request
import com.twitter.util.Await.result
import io.fintrospect.configuration.{Host, Port}
import io.fintrospect.filters.RequestFilters.AddHost

val authority = Host("pokeapi.co").toAuthority(Port._80)
val client = RequestFilters.AddHost(authority)
val client = AddHost(authority)
.andThen(Http.newService(authority.toString))

println(result(client(Request("/"))).contentString)
Expand Down
9 changes: 5 additions & 4 deletions src/test/scala/cookbook/finagle/SSL_Client_Example.scala
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package cookbook.finagle

import com.twitter.finagle.Http
import com.twitter.finagle.http.Request
import com.twitter.util.Await.result
import io.fintrospect.filters.RequestFilters.AddUserAgent

object SSL_Client_Example extends App {

import com.twitter.finagle.Http
import com.twitter.finagle.http.Request
import com.twitter.util.Await.result
import io.fintrospect.filters.RequestFilters.AddUserAgent

val client = Http.client.withTls("api.github.com").newService("api.github.com:443")

val request = Request("/users/daviddenton/repos")
Expand Down

0 comments on commit a123777

Please sign in to comment.