THE

HTT(PANCAKE) REQUEST

KEEPING YOUR CLIENTS HAPPY, NOT HANGRY

KRISELDA RABINO

SOFTWARE ENGINEER @ DELIVEROO

say hi: ​@krissygoround

say hi: ​@krissygoround

"MAKE ME A WEBSITE?"

OUR JOBS AREN'T ONLY TO BUILD GOOD APPLICATIONS; BUT GOOD RELATIONSHIPS BETWEEN THEM.

say hi: ​@krissygoround

SPEAKING HTTP

say hi: ​@krissygoround

THE HYPERTEXT TRANSFER PROTOCOL AND THE CLIENT/SERVER RELATIONSHIP

HTTP HOSPITALITY 

  • REQUEST/RESPONSE FORMATS

  • CONTENT NEGOTIATION

  • COMPRESSION

  • CONDITIONAL HEADERS + CACHING

  • PARTIAL RESPONSES

  • KEEP-ALIVE / PERSISTENT CONNECTIONS

  • REQUEST PIPELINING

  • CHUNKED TRANSFER ENCODING

  • ...

say hi: ​@krissygoround

BUT FIRST,

LET'S TALK ABOUT BRUNCH 

=

THE MEAL BETWEEN BREAKFAST AND LUNCH

say hi: ​@krissygoround

say hi: ​@krissygoround

MOAR METADATA

1991: HTTP/0.9

 Minimal, one line GET request & a simple HTML response. Hello World Wide Web!

1996: HTTP/1.0

Request/response headers, useful status codes, HTTP version specification - enabling content negotiation.

<html>
I'm a menu in a simple HTML (HyperText Markup Language) document.
...
</html>
GET /menu
STATUS 200 OK
Date: Sun, 18 Sep 2016 12:30:54 GMT
...
<html>...
GET /menu HTTP/1.0
Accept-Language: en-gb ...

BAD BRUNCH

THE ELUSIVE ERROR

STATUS 500 INTERNAL SERVER ERROR
{
  "error": "SORRY, NO ROOM!!1"
}

say hi: ​@krissygoround

BETTER BRUNCH

THOUGHTFUL ERROR RESPONSES

STATUS 501 NOT IMPLEMENTED
Date: Sun, 18 Sep 2016 12:30:54 GMT
{
  "code": "123-NO-PRAMS",
  "message": "Due to space restrictions, the
              restaurant garden can not accommodate 
              prams.",
  "more_info": "http://brunchlove.com/faq#prams"
}

say hi: ​@krissygoround

HTT(PANCAKE) TIP 1:

GO OUT OF YOUR WAY TO BE INFORMATIVE AND HELPFUL

  • DON'T USE GENERIC HTTP STATUS CODES
  • USE APPROPRIATE REQUEST/RESPONSE HEADERS
  • GIVE DETAILED RESPONSES, ESPECIALLY IF SOMETHING GOES WRONG

say hi: ​@krissygoround

say hi: ​@krissygoround

TCP CONNECTION

THE THREE-WAY HANDSHAKE

HTTP 1.0 REQUIRED OPENING/CLOSING A TCP CONNECTION FOR EVERY REQUEST MADE.

 

MAKING A REQUEST IS EXPENSIVE (TIME-WISE).

 

THIS WAS OK BACK THEN WHEN WEBSITES WERE MORE LIGHTWEIGHT.

 

say hi: ​@krissygoround

BUT THINGS HAVE CHANGED

taco.com (1996)

~47 requests

deliveroo.co.uk (2016)

~88 requests

some workarounds: precompiling assets into one to reduce requests, image compression, minification, caching...

say hi: ​@krissygoround

GETTING PERSISTENT

KEEP-ALIVE CONNECTIONS

BETWEEN 1997-1999,

HTTP 1.1 WAS DEVELOPED WITH A PLETHORA OF IMPROVEMENTS.

 

ONE BEING THE ABILITY TO MAKE SEVERAL REQUESTS OVER ONE TCP CONNECTION. YAY!

HTT(PANCAKE) TIP 2:

THE SLOTH IS NOT YOUR SERVICE'S SPIRIT CREATURE

  • STRIVE FOR LOW LATENCY (TIME BETWEEN A REQUEST AND A RESPONSE), MANY METHODS TO DO THIS ON THE CLIENT AND SERVER
  • ENABLE PERSISTENT (KEEP-ALIVE) CONNECTIONS - DEFAULT IN MODERN BROWSERS BUT NOT NECESSARILY IN HTTP LIBRARIES USED FOR APIS

say hi: ​@krissygoround

say hi: ​@krissygoround

WHEN PEOPLE MAKE ME FEEL SPESH

BAD BRUNCH

TREAT CLIENTS GENERICALLY

STATUS 200 OK
Date: Sun, 18 Sep 2016 12:30:54 GMT
...
{
    "type": "Brunch",
    "items": [
        {
            "id": 123,
            "name": "Potato Pancakes",
            "price": "8.99"
        },
        ...
    ]
}
GET /menu?type=brunch

say hi: ​@krissygoround

BETTER BRUNCH

CATER FOR CONDITIONAL REQUESTS

GET /menu?type=brunch
STATUS 200 OK
Date: Sun, 18 Sep 2016 12:30:54 GMT
Cache-Control: private, max-age=2592000
Last-Modified: 10 Jun 2016 10:00:00 GMT
Etag: "15f0fff99ed5aae4edffdd6496d7131f"
...
{
    "type": "Brunch",
    "items": [
        {
            "id": 123,
            "name": "Potato Pancakes",
            "price": "8.99"
        },
        ...
    ]
}

say hi: ​@krissygoround

BETTER BRUNCH

CATER FOR CONDITIONAL REQUESTS

GET /menu?type=brunch
If-Modified-Since: 10 Jun 2016 10:00:00 GMT
STATUS 304 NOT MODIFIED

GET /menu?type=brunch
If-None-Match: "15f0fff99ed5aae4edffdd6496d7131f"

or:

say hi: ​@krissygoround

HTTP CACHING

IN RAILS

def show
  @menu = Menu.find(params[:id])
  expires_in(5.minutes, "must-revalidate": true, public: false)
  # responds with 304 if not stale
  if stale?(@menu, public: false)
    render json: MenuSerializer.new(@menu)
  end
end

That's seriously it. ^

(NB: not "all" of it - HTTP caching is quite the giant topic!)

say hi: ​@krissygoround

HTT(PANCAKE) TIP 3:

GIVE YOUR CLIENTS WHAT THEY ACTUALLY ASK FOR

  • CATER FOR CONDITIONAL REQUEST HEADERS
  • CACHE YOUR RESPONSES WHEN POSSIBLE
  • MAKE YOUR CLIENTS FEEL SPESH

say hi: ​@krissygoround

TAKE-AWAYS

Your most unhappy customers are your greatest source of learning. - Bill Gates

BUILD THE TYPE OF SERVICE YOU WOULD ENJOY INTERACTING WITH AGAIN.

 

LEAVE YOUR CLIENTS HAPPY,

NOT HANGRY.

say hi: ​@krissygoround

LINKS AND KUDOS

 

say hi: ​@krissygoround

The HTT(Pancake) Request

By Kriselda Rabino

The HTT(Pancake) Request

Leave your clients happy, not hangry.

  • 2,164