don't screw it up! how to build durable api

169
Alessandro Cinelli (cirpo) Don’t screw it up! how to build durable apis

Upload: alessandro-cinelli

Post on 20-Aug-2015

1.556 views

Category:

Internet


6 download

TRANSCRIPT

Alessandro Cinelli (cirpo)

Don’t screw it up!

how to build durable apis

How to build durable

web APIs

1. Can you predict the future?

Dubai Marina ~2000

Dubai Marina 2014

CAN YOU REALLY PREDICT THE FUTURE?

If there’s one thing we learned over the past 5 years of development...

Monoliths are disappearing

FULL STACK IS DEAD!

Microservice Architecture, [...] a particular way of designing software applications as suites of independently deployable services

http://martinfowler.com/articles/microservices.html

FULL STACK IS DEAD!

Microservice Architecture, [...] a particular way of designing software applications as suites of independently deployable services

http://martinfowler.com/articles/microservices.html

SERVICE-ORIENTED ARCHITECTURES

LEGO, something new in a geek talk…

FROM

a single page application written in

TO

an hybrid solution

IN TWO WEEKS!!!

HOW?

APIs written in PHP <3

EVERYONE WANTS API

EVERYDAY SERVICES

DEV-ORIENTED SERVICES

API MANIACS

2. HTTP IS HERE TO STAY

GET vs POST

“The difference is that in a GET request you have the parameters in the url , with a POST the parameters are in the request’s body”

GET vs POST

HTTP FUNDAMENTALS

HTTP FUNDAMENTALS

GET POST

HTTP FUNDAMENTALS

GET POST

PUT HEAD

DELETEPATCH

OPTIONS

HTTP FUNDAMENTALS

HEADERS

HTTP FUNDAMENTALS

HEADERS

Accept

Accept-Encoding

Accept-LanguageCookie

Content-Type

Referer

If-Modified-Since

If-None-Match

OriginUser-Agent

Cache-Control

HTTP FUNDAMENTALS

CUSTOM HEADERS

HTTP FUNDAMENTALS

CUSTOM HEADERS

N-LocationN-Locale

N-Device

N-Platform

N-App

N-Theme

WAKA

“A new protocol designed to match the efficiency of well-designed Web Applications”

http://tools.ietf.org/agenda/83/slides/slides-83-httpbis-5.pdf

SPDY/1…3

A protocol “invented” by Google, which supports:

extended compression

multiplexing

prioritization

server push

SPDY/1…3

A protocol “invented” by Google, which supports:

extended compression

multiplexing

prioritization

server push

SPDY/1…3

A protocol “invented” by Google, which supports:

extended compression

multiplexing

prioritization

server push

SPDY/1…3

A protocol “invented” by Google, which supports:

extended compression

multiplexing

prioritization

server push

HTTP/2.0

HTTP/2.0

BASED ON SPDY

HTTP/2.0

WHICH IS A FASTER VERSION OF HTTPS

HTTP/2.0

WHICH IS A SAFER VERSION OF HTTP

HTTP is definitely here to stay, semantics won’t change

3. PLAN FOR FAILURE

WORK AROUND BUGS

WORK AROUND BUGS

FAILOVER

HTTP/1.1 200 OKDate: Fri, 25 Apr 2014 16:52:37 GMTContent-Type: application/jsonTransfer-Encoding: chunkedConnection: keep-aliveVary: Accept-EncodingCache-Control: stale-if-error=3600, stale-while-revalidate=6000Age: 0Via: 1.1 varnishX-Cache: MISSAlternate-Protocol: 443:npn-spdy/2

FAILOVER

HTTP/1.1 200 OKDate: Fri, 25 Apr 2014 16:52:37 GMTContent-Type: application/jsonTransfer-Encoding: chunkedConnection: keep-aliveVary: Accept-EncodingCache-Control: stale-if-error=3600, stale-while-revalidate=6000Age: 0Via: 1.1 varnishX-Cache: MISSAlternate-Protocol: 443:npn-spdy/2

CACHE AVAILABLE IF BACKEND IS DOWN

DESIGN MISTAKES?

VERSIONING TO THE RESCUE

VERSIONING TO THE RESCUE

VERSIONING TO THE RESCUE

VERSIONING TO THE RESCUE

How to detect the version?

How to detect the version?

http://api.example.com/v1/…

How to detect the version?

SIMPLE

How to detect the version?

BUT HOW TO DETECT IT?

DETECTING THE VERSION

DETECTING THE VERSION

Here it belongs to the route/controller, you need

it at the Request level

How to detect the version?

USE A HEADER!

DETECTING THE VERSION

LET NGINX DO THE JOB

LET NGINX DO THE JOB

$req->getHeader(‘API-Version)

LET NGINX DO THE JOB

api.example.com/v1/customers

LET NGINX DO THE JOB

api.example.com/customers

API-Version: 1

LET NGINX DO THE JOB

Without polluting your router or controller class

“I beg to differ”

“I beg to differ”

URL, subdomain, media type, header...

“I beg to differ”

Picking a wrong implementation doesn’t matter

“I beg to differ”

AT ALL.

“I beg to differ”

How it impacts the design of your

software matters

4. BE PRAGMATIC

GET or POST?

GET or POST?

api. example.com/login/?username=cirpo&login=wunderbar

5.TESTING

cURL is your best friend

curl -X GET https://api.example.com/products

curl -X POST https://api.example com/order -data=”{...}”

curl -X DELETE ...

curl -X PATCH ...

cURL is your best friend

PHP

cuzzle cURL command

from Guzzle requests

github.com/namshi/cuzzle

cURL is your best friend

cURL is your best friend

cURL is your best friend

HTTPARTY

HTTPIE

Javascript

mockserver mock your APIs

in a matter of seconds!

github.com/namshi/mockserver

Javascript

mockserver

Javascript users_GET.mock file

mockserver

Javascript

mockserver

TESTING APIS

Android 2.3 native browser…

TESTING APIS

TESTING APIS

you can even decrypt the https responses :)

Javascript

github.com/namshi/shish

shisha smoke tests made easy!

Javascript

shisha

.smoke file

Javascript

shisha

6. DESIGN

An API is a layer on top of your domain

Pick the layer that is most suitable

to your needs

HTTP APIs are a good start

REST IS A DREAM!

HTTP METHOD

POST or PUT?

HTTP METHOD

PUT or PATCH?

USER TAGS

/users/johnny/tags

USER TAGS

deleting a non-existent tag: 200, 204 or 404?

USER TAGS

deleting a non-existent tag: 200, 204 or 404?

ON STACKOVERFLOW THEY’RE

STILL FIGHTING http://stackoverflow.com/questions/2342579/http-status-code-for-

update-and-delete

be consistent

NAMING

/user/1 /users

/order/1 /orders

NAMING

/city/1 /cities

/curriculum/1 /curricula

NAMING/user/1 /users /order/1 /orders /city/1

/cities /curriculum/1 /curricula

NAMING/user/1 /users /order/1 /orders /city/1

/cities /curriculum/1 /curricula

NOT GOD AT ALL!

STICK WITH PLURALS!

NAMING

/users1 /users

/orders/1 /orders

NAMING

/cities/1 /cities

/curricula/1 /curricula

NAMING/users/1 /users /orders/1 /orders /cities/1

/cities /curricula/1 /curricula

UNIQUE RESOURCES

/users/1

/users/cirpo

/users/A323K833

UNIQUE RESOURCES

/orders/15

/orders/A323K833

UNIQUE RESOURCES

/orders/15

/orders/A323K833

AVOID INCREMENTAL NUMBERS

IF IT’S BUSINESS CRITICAL

Unstructured APIs =

API aggregation

api.example.org/v1/latest-news

latest news + metatags + banners + navigation

yada yada yada

Sort of a “wild” API for your whole app

The client receives a GET on /something and will let the API figure out

what /u/something actually is

Orchestration Layers

https://engineering.groupon.com/2013/misc/i-tier-dismantling-the-monoliths/

“Most APIs are designed by the API provider with the goal of maintaining data model purity. When building an OL, be prepared to sometimes abandon purity in favor of optimizations and/or performance.”

Daniel Jacobson,director of engineering

for the Netflix APIhttp://www.infoq.com/presentations/API-Revolution

DOMAIN

users orders stock

images

DOMAIN

Think about collections not

controllers

DOMAIN

PUT/PATCH

try to always plan for full updates

UNIFORM RESPONSES

CODEBASE ORGANIZATION

CODEBASE ORGANIZATION

one bundle for each api?

one bundle for each application?

one app for each sets of api?

CODEBASE ORGANIZATION

start with an app

organize bundles semantically

create shared bundles

CODEBASE ORGANIZATION

BUNDLES product

checkout warehouse

generic entity

CODEBASE ORGANIZATION

APP product

BUNDLES checkout

warehouse generic entity

7. SCALABILITY

CACHE ALL THE THINGS!

MIDDLEWARE

MIDDLEWARE - CONNECT

MIDDLEWARE - STACK

AVOID SESSIONS

EVERYTHING AS A RESOURCE

8. ISSUES

CORS

CORS

(silly) browsers

(silly) browsers

if a cross-domain request is cacheable, the android browser

goes nuts

(silly) browsers

The request does not include

the Origin header

(silly) browsers

Status code: 0

(silly) browsers

WHAT. THE. HECK.

http://opensourcehacker.com/2011/03/20/android-webkit-xhr-status-code-0-and-expires-headers/

“standards”

Don’t play with fire

Don’t play with fire

1 API, N clients consuming it

Don’t play with fire

desktop browser, mobile browser,

ios app, android app...

Don’t play with fire

Keep as much logic as possible on the

server

Don’t play with fire

Less things to implement on every

client and centralized implementations

Don’t play with fire

make it easy for theAPI clients

Don’t play with fire

POST https://api.example.com/login

200 OKdate: Thu, 01 May 2014 21:52:33 GMTcontent-type: application/jsontransfer-encoding: chunkedconnection: closeset-cookie: login=...;cache-control: no-cache

{ “email"=>"[email protected]", "firstName"=>"Alessandro", "lastName"=>"Cinelli", “birthday”=>"14/09/1985",

}

Security matters

Security matters

[ "[email protected]", "[email protected]", ...

]

Security matters

for(;;);[ "[email protected]", "[email protected]", ...

]

Security matters

while(1);[ "[email protected]", "[email protected]", ...

]

Security matters

while(1);[ "[email protected]", "[email protected]", ...

]

Security matters

Avoid [...]

http://bit.ly/json-hijacking

Security matters

USE {…}

That’s all folks

@cirpo

github.com/cirpo

/

we are hiring!tech.namshi.com/join-us

github.com/namshi

twitter.com/TechNamshi

tech.namshi.com

THANKS

CREDITS

http://www.panoramio.com/photo/30329016 https://farm3.staticflickr.com/2199/2365883747_3a5c753719_o.jpg

http://news.buzzbuzzhome.com/2013/04/top-7-aerial-photos-cities.html https://www.flickr.com/photos/superlekker/5917559189/sizes/l https://www.flickr.com/photos/derekbruff/12336187505/sizes/l

https://www.flickr.com/photos/chberge/3803475294/sizes/l https://www.flickr.com/photos/neilsingapore/8057578769

https://www.flickr.com/photos/dionnehartnett/6805481856/sizes/l https://www.flickr.com/photos/thomashawk/186339737

https://www.flickr.com/photos/cesarastudillo/3981364314/sizes/l https://www.flickr.com/photos/an_untrained_eye/6630719431

https://www.flickr.com/photos/30835738@N03/7936491790/sizes/l https://www.flickr.com/photos/deboni/2959228565/sizes/l https://www.flickr.com/photos/ghalog/6782751111/sizes/l

https://www.flickr.com/photos/timzim/177640262/sizes/o/ https://www.flickr.com/photos/innoxiuss/2824204305

https://www.flickr.com/photos/hawk59/6038847752/sizes/l https://www.flickr.com/photos/remydwd/5487417702/sizes/l

https://www.flickr.com/photos/rammorrison/4359793666/sizes/o/ https://www.flickr.com/photos/piers_nye/2501994750/sizes/o/

https://www.flickr.com/photos/danielygo/7559750132/sizes/l https://www.flickr.com/photos/msc72/2600035028/sizes/l

https://www.flickr.com/photos/sicilianitaliano/3609275241/sizes/l https://www.flickr.com/photos/scottmontreal/7235110028/sizes/l https://www.flickr.com/photos/piet_musterd/6170853224/sizes/l

https://www.flickr.com/photos/music_embassy/7137413247/sizes/l http://upload.wikimedia.org/wikipedia/commons/9/9c/William_James_b1842c.jpg

http://theverybesttop10.files.wordpress.com/2013/08/the-world_s-top-10-things-no-person-with-a-ocd-should-see-1.jpg https://www.flickr.com/photos/62244271@N03/8553590682/sizes/l