HTTP/2 for WebAPIs – Part 0: Brief HTTP history



HTTP/2 for WebAPIs – Part 0: Brief HTTP history

0 0


http2-webapi

Talk about HTTP/2 at the Hamburg WebAPI Meetup

On Github JanAhrens / http2-webapi

HTTP/2 for WebAPIs

One year after 🔍

Raise your hands ✋

Who used HTTP/1.1 for Web APIs?

Who looked at SPDY?

Who read about HTTP/2

Who used HTTP/2 in production?

Part 0: Brief HTTP history 🚂

HTTP/1.0

HTTP V0.9 in 1991 - only GET 🍼

HTTP V1.0 in 1996 - other methods and headers

HTTP/1.1

HTTP/1.1 in 1997

Updates in 1999 as RFC 2616 👍

2007: HTTPbis WG formed to work on a revised spec 👓

2014: RFC 723{0,5} released ⌛️

Don't use RFC 2616 any longer ⚠️

HTTP/2

July 2012: Google made SPDY public 🚀

November 2012: SPDY gets used as first draft for HTTP/2

2015: Release of RFC 7540 (HTTP/2) 🎉

Part 1: What HTTP/2 is about 🔮

No change in semantics 🎉

No new verbs

No change in status code

Same request and response cycle

RFC 723{0,5} (HTTP/1.1) still applies

This specification is an alternative to, but does not obsolete, the HTTP/1.1 message syntax. HTTP's existing semantics remain unchanged.

- RFC 7540 (HTTP/2)

Binary protocol 🤔

Goodbye, telnet!

Parsing is easier to implement

Request and response sizes are smaller

Harder to debug

TLS is preferred 🎉

ALPN for fast TLS HTTP/2 connections

h2c - HTTP/2 over cleartext

Using h2c takes longer than h2

Browser vendors decided against supporting h2c

No head-of-line blocking 🎉

Source: http2-explained.haxx.se/content/en/part2.html

Streams 🔀

Send data when it's available

Replaces HTTP/1.1 pipelining

Source: http2-explained.haxx.se/content/en/part6.html
Source: http2-explained.haxx.se/content/en/part6.html
Source: http2-explained.haxx.se/content/en/part6.html

Streams 🔀

No need to open multiple TCP connections

No need for image spriting hacks

No need for concatenating of CSS/JS files hacks

Caching can be used as intended

Header Compression 🗜

Each HTTP/2 connection maintains a table of known headers

Known headers can be referenced instead of retransmitted

No need to send cookies (and similar) with every request 🍪

Server Push 🎁

Send response in advance to prepopulate the cache

Can be disabled altogether by the client

Opt out of individual pushes by closing the stream

Part 2: HTTP/2 for WebAPIs 🔬

Caching can finally be used

Bold claim: Most Web APIs don't use caching as intended 👻

Minimal request overhead:

Single TCP connection with streams 🔀

No need to send headers twice (HPACK) 🗜

Caching in HTTP/1.1 🤓

RFC 7234 - HTTP/1.1: Caching

Cache entries may be used until they become stale 🧀

Validation of stale entries:

Time-based ⏰

Tag-based 🏷

Time-based validation ⏰

HTTP/1.1 200 OK
Last-Modified: Mon, 20 Jun 2016 13:52:06 GMT
Cache-Control: public, max-age=60, s-maxage=60

Cache entry will become stale in 60 seconds

GET /users/janahrens HTTP/1.1
If-Modified-Since: Mon, 20 Jun 2016 13:52:06 GMT

Revalidation request

HTTP/1.1 304 Not Modified
Last-Modified: Mon, 20 Jun 2016 13:52:06 GMT
Cache-Control: public, max-age=60, s-maxage=60

Tag-based caching 🏷

HTTP/1.1 200 OK
ETag: "d056f833afafabe90e01640ae321b5da"
Cache-Control: public, max-age=60, s-maxage=60

Cache entry will become stale in 60 seconds

GET /users/janahrens HTTP/1.1
If-None-Match: "d056f833afafabe90e01640ae321b5da"

Revalidation request

HTTP/1.1 304 Not Modified
Cache-Control: public, max-age=60, s-maxage=60

Model cache-friendly resources 💾

Don't include everything in a response

{
  "name": "Roy Fielding",
  "contributions": [
    {"id": "cce61228-19dc-4129-94b4-20ed0125c471", "name": "RFC 2616"},
    {"id": "7f68c66d-b303-4ac4-9a3a-d68cfd81ad06", "name": "RFC 7230"}
  ]
}

vs.

{
  "name": "Roy Fielding",
  "contributionIds": [
    "cce61228-19dc-4129-94b4-20ed0125c471",
    "7f68c66d-b303-4ac4-9a3a-d68cfd81ad06"
  ]
}

Do your clients support caching?

Use server push 🎁

Push resources that the client will likely need

For example: associated data, images, next-pages, ..

Hypermedia becomes more important ✨

If resources become more cache-friendly make related resources easy to discover

{
  "name": "Roy Fielding",
  "contributions": [
    "/rfc/cce61228-19dc-4129-94b4-20ed0125c471",
    "/rfc/7f68c66d-b303-4ac4-9a3a-d68cfd81ad06"
  ]
}

This is a very, very simple example ⚠️

Is JSON still the right format?

HTTP/2 is binary

JSON is plaintext

BSON - binary JSON

Or Protocol Buffers, they are

Typed

Space efficient

Backwards compatible

What type of clients do you serve?

gRPC 🎩

RPC framework on top of HTTP/2 with Protocol Buffers

"Abuse" push promises for bi-directional communication

No longer RESTful

grpc.io

Part 3: Adaptation of HTTP/2 📈

HTTP/2 Dashboard

isthewebhttp2yet.com

based on Alexa Top 1 Million

currently 12.7 %

Web server support

Nginx since 1.9.5 (September 2015)

Apache since 2.4.17 (October 2015)

Wikipedia: Software and services supporting HTTP/2

cURL with HTTP/2

cURL needs to be linked against nghttp2

On OSX using Homebrew

$ brew install curl --with-nghttp2
$ brew link curl --force
$ curl -v --http2 https://www.google.com/

State of languages

Rack (Ruby) doesn't support HTTP/2, yet

h2o can be used as an application server (also for Ruby)

Servlet 4.0 adds HTTP/2 support for Java EE 8 (not released)

Don't wait for Servlet 4.0, use Undertow, Netty, Jetty, ..

Go has excellent HTTP/2 support in the standard library

Load balancing ⚠️

Long running TCP connection from client to server

The GOAWAY frame

Some hardware load balacers have support already (i.e. F5)

No HTTP/2 support for Amazon ELB, yet

Terminate HTTP/2 at the LB, speak HTTP/1.1 internally 💡

Sources / Further reading

RFC 7540 (HTTP/2)

http2-explained.haxx.se/content/en

se-radio.net/2015/07/episode-232-mark-nottingham-on-http2

http2.akamai.com/demo

blog.codeclimate.com/blog/2014/06/05/choose-protocol-buffers

Questions and/or comments?

Slides: blog.jan-ahrens.eu/http2-webapi

HTTP/2 for WebAPIs One year after 🔍