don't screw it up: how to build durable web apis

183
Don’t screw it up! @cirpo @_odino_

Upload: alessandro-cinelli

Post on 21-Apr-2017

12.297 views

Category:

Internet


0 download

TRANSCRIPT

Don’t screw it up!

@cirpo @_odino_

How to build durableweb APIs

How to build durableweb APIs

1. Can you predictthe 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 serviceshttp://martinfowler.com/articles/microservices.html

Full stack is dead

Microservice Architecture, [...] a particular way of designing software applications as suites of independently deployable serviceshttp://martinfowler.com/articles/microservices.html

SERVICE-ORIENTEDARCHITECTURES

LEGO, something new in a geek presentation...

FROM

a single page application written in

TO

an hybrid solution

In TWO weeks!

HOW???

APIs written in PHP <3

Everyone wants APIs

Everyday normal 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 POSTPUT

HEAD

DELETEPATCH

OPTIONS

HTTP FUNDAMENTALS

HEADERSAccept

Accept-Encoding Accept-Language

Cookie

Content-Type

Referer

If-Modified-Since

If-None-Match

Origin User-Agent

Cache-Control

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

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 fasterversion of HTTPS

HTTP/2.0

which is a saferversion of HTTP

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

3. Plan for failure

Work around bugs

https://gist.github.com/odino/11295759/revisions

Work around bugs

https://gist.github.com/odino/11295759/revisions

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

Failover

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

cache availableif the backend

is down

Design mistakes?

Versioning to the rescue

Versioning to the rescue

https://gist.github.com/odino/bf4c7468cba8b16c6493

Versioning to the rescue

https://gist.github.com/odino/f820dda941bf44aa7605

Versioning to the rescue

https://gist.github.com/odino/b5d963d8f8aec904d76c

Versioning to the rescue

https://gist.github.com/odino/0fbb5be8113deed752fc

How to detect the version?

How to detect the version?

api.domain.org/v1/...

How to detect the version?

SIMPLE

How to detect the version?

...but how to detect it?

Detecting the version

https://gist.github.com/odino/f5a1026449e35cfa8a29

Detecting the version

https://gist.github.com/odino/f5a1026449e35cfa8a29

Here it belongs tothe route/controller,

you need it at theRequest level

Detecting the version

https://gist.github.com/odino/f5a1026449e35cfa8a29

Use a header!

Detecting the version

https://gist.github.com/odino/bf4c7468cba8b16c6493

Can’t test it easily!

Let Nginx do the dirty work

https://gist.github.com/odino/6750004f735c8d08687d

Let Nginx do the dirty work

https://gist.github.com/odino/6750004f735c8d08687d

example.org/v1/customers/1

Let Nginx do the dirty work

https://gist.github.com/odino/6750004f735c8d08687d

example.org/customers/1

Api-Version: 1

Let Nginx do the dirty work

https://gist.github.com/odino/6750004f735c8d08687d

$req->getHeader(‘Api-Version’)

Let Nginx do the dirty work

https://gist.github.com/odino/6750004f735c8d08687d

Without pollutingrouting and controllers

“I beg to differ”

“I beg to differ”

URL, subdomain,media type, header...

“I beg to differ”

Picking a wrongimplementationdoesn’t matter

“I beg to differ”

Picking a wrongimplementationdoesn’t matterAT ALL.

“I beg to differ”

How it impacts thedesign of your

software matters

“I beg to differ”

#NoSilverBullet

4. Be Pragmatic

/login

GET or POST?

5. Testing

cURL is your best friend

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

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

curl -X DELETE ...

curl -X PATCH ...

cURL is your best friend

cURL is your best friend

cURL is your best friend

cURL is your best friend

https://docs.python.org/2/library/json.html

httparty

https://docs.python.org/2/library/json.html

httpie

https://github.com/jkbr/httpie

smoke tests made easy

consuming/testing apis locally

https://gist.github.com/cirpo/92fa22d4c45fddf0ccfa

consuming/testing apis locally

https://gist.github.com/cirpo/c6d497c5654094904306

testing apis

Android 2.3 native browser

testing apis

testing apis

you can even decrypt the https

responses :)

6. Design

An API is a layer ontop of your domain

Pick the layer thatis most suitable

to your needs

HTTP APIs are agood start

REST is a DREAM

POST or PUT?

HTTP METHOD

PUT or PATCH?

HTTP METHOD

/users/johnny/tags

USER TAGS

USER TAGS

to remove a tag

PUT, PATCH or DELETE?

USER TAGS

deleting a non-existent tag

200 or 204 or 404?

http://stackoverflow.com/questions/2342579/http-status-code-for-update-and-delete

USER TAGS

deleting a non-existent tag

200 or 204 or 404?

http://stackoverflow.com/questions/2342579/http-status-code-for-update-and-delete

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 good AT ALL!

STICK WITH PLURALS

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

AVOID INCREMENTAL NUMBER

(if it’s business critical)

Unstructured APIs=

API aggregation

api.example.org/v1/latest-news

latest news +metatags +banners +

navigationyada yada yada

Sort of a “wild” APIfor your whole app

The client receives a GET on /something

and will let theAPI 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

usersordersstock

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

7. Scalability

CACHE ALL THE THINGS!

Middlewares to the rescue!

CONNECT

https://gist.github.com/cirpo/e9ec20871e2e8d433f8d

STACK

https://gist.github.com/cirpo/11296317

Avoid sessions

Everything as a resource

http://leaphly.org/

8. We have a problem

CORS

CORS

iFrames to the rescue!

iFrames to the rescue!

domain.org includes an

iframe fromapi.domain.org

iFrames to the rescue!

then sends ita message

through thepostMessage

API

iFrames to the rescue!

the iFrametriggers theajax request

on its owndomain with

the parametersin the message

iFrames to the rescue!

and sendsthe result back

to the caller

iFrames to the rescue!

and sendsthe result back

to the caller#ghetto

CORS

xDomain,cross-browserwithout CORS

https://github.com/jpillora/xdomain

CORS

great idea, butJaime is alone :(

CORS

poor file uploadsupport

CORS

no automated tests

CORS

not a long-term solution :’-(

CORS

xAuth, a standard

https://github.com/xauth/xauth

CORS

initially thoughtto provide

a decentralizedauth service

CORS

on the centralizedxauth.org

http://hueniverse.com/2010/06/05/xauth-a-terrible-horrible-no-good-very-bad-idea/

CORS

Dead.

CORS

DEAD.

CORS

Use an API proxy

CORS

example.org/api/

(silly) browsers

(silly) browsers

if a cross-domainrequest is cacheable,the android browser

goes nuts

(silly) browsers

The request doesnot 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 clientsconsuming it

Don’t play with fire

desktop browser, mobile browser,

ios app, android app...

Don’t play with fire

Keep as much logicas possible on the

server

Don’t play with fire

Less things toimplement on every

client and centralizedimplementations

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"=>"Alex", "lastName"=>"Nadalin", "birthday"=>"21/10/1988",

}

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]", ...

]

http://bit.ly/why-does-google

Security matters

Avoid [...]

http://bit.ly/json-hijacking

Security matters

Use {...}

That’s all folks

github.com/cirpo

twitter.com/cirpo

cirpo.org

github.com/odino

twitter.com/_odino_

odino.org

Namshi Lead Developer Namshi VP Technology

github.com/cirpo

cirpo.org

thank you!

joind.in/11310

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

github.com/namshi

twitter.com/TechNamshi

tech.namshi.com

CREDITS

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

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

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

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

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

https://www.flickr.com/photos/30835738@N03/7936491790/sizes/lhttps://www.flickr.com/photos/deboni/2959228565/sizes/lhttps://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/lhttps://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/lhttps://www.flickr.com/photos/msc72/2600035028/sizes/l

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

https://www.flickr.com/photos/music_embassy/7137413247/sizes/lhttp://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