Page 1
Alessandro Cinelli (cirpo)
Don’t screw it up!
how to build durable apis
Page 2
How to build durable
web APIs
Page 3
1. Can you predict the future?
Page 4
Dubai Marina ~2000
Page 6
CAN YOU REALLY PREDICT THE FUTURE?
Page 7
If there’s one thing we learned over the past 5 years of development...
Page 8
Monoliths are disappearing
Page 9
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
Page 10
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
Page 11
LEGO, something new in a geek talk…
Page 13
FROM
a single page application written in
Page 14
TO
an hybrid solution
Page 17
APIs written in PHP <3
Page 18
EVERYONE WANTS API
Page 19
EVERYDAY SERVICES
Page 20
DEV-ORIENTED SERVICES
Page 22
2. HTTP IS HERE TO STAY
Page 23
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”
Page 25
HTTP FUNDAMENTALS
Page 26
HTTP FUNDAMENTALS
GET POST
Page 27
HTTP FUNDAMENTALS
GET POST
PUT HEAD
DELETEPATCH
OPTIONS
Page 28
HTTP FUNDAMENTALS
HEADERS
Page 29
HTTP FUNDAMENTALS
HEADERS
Accept
Accept-Encoding
Accept-LanguageCookie
Content-Type
Referer
If-Modified-Since
If-None-Match
OriginUser-Agent
Cache-Control
Page 31
HTTP FUNDAMENTALS
CUSTOM HEADERS
Page 32
HTTP FUNDAMENTALS
CUSTOM HEADERS
N-LocationN-Locale
N-Device
N-Platform
N-App
N-Theme
Page 33
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
Page 34
SPDY/1…3
A protocol “invented” by Google, which supports:
extended compression
multiplexing
prioritization
server push
Page 35
SPDY/1…3
A protocol “invented” by Google, which supports:
extended compression
multiplexing
prioritization
server push
Page 36
SPDY/1…3
A protocol “invented” by Google, which supports:
extended compression
multiplexing
prioritization
server push
Page 37
SPDY/1…3
A protocol “invented” by Google, which supports:
extended compression
multiplexing
prioritization
server push
Page 39
HTTP/2.0
BASED ON SPDY
Page 40
HTTP/2.0
WHICH IS A FASTER VERSION OF HTTPS
Page 41
HTTP/2.0
WHICH IS A SAFER VERSION OF HTTP
Page 42
HTTP is definitely here to stay, semantics won’t change
Page 43
3. PLAN FOR FAILURE
Page 46
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
Page 47
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
Page 49
VERSIONING TO THE RESCUE
Page 50
VERSIONING TO THE RESCUE
Page 51
VERSIONING TO THE RESCUE
Page 52
VERSIONING TO THE RESCUE
Page 53
How to detect the version?
Page 54
How to detect the version?
http://api.example.com/v1/…
Page 55
How to detect the version?
SIMPLE
Page 56
How to detect the version?
BUT HOW TO DETECT IT?
Page 57
DETECTING THE VERSION
Page 58
DETECTING THE VERSION
Here it belongs to the route/controller, you need
it at the Request level
Page 59
How to detect the version?
USE A HEADER!
Page 60
DETECTING THE VERSION
Page 61
LET NGINX DO THE JOB
Page 62
LET NGINX DO THE JOB
$req->getHeader(‘API-Version)
Page 63
LET NGINX DO THE JOB
api.example.com/v1/customers
Page 64
LET NGINX DO THE JOB
api.example.com/customers
API-Version: 1
Page 65
LET NGINX DO THE JOB
Without polluting your router or controller class
Page 66
“I beg to differ”
Page 67
“I beg to differ”
URL, subdomain, media type, header...
Page 68
“I beg to differ”
Picking a wrong implementation doesn’t matter
Page 69
“I beg to differ”
AT ALL.
Page 70
“I beg to differ”
How it impacts the design of your
software matters
Page 73
GET or POST?
api. example.com/login/?username=cirpo&login=wunderbar
Page 75
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 ...
Page 76
cURL is your best friend
Page 77
PHP
cuzzle cURL command
from Guzzle requests
github.com/namshi/cuzzle
Page 78
cURL is your best friend
Page 79
cURL is your best friend
Page 80
cURL is your best friend
Page 83
Javascript
mockserver mock your APIs
in a matter of seconds!
github.com/namshi/mockserver
Page 84
Javascript
mockserver
Page 85
Javascript users_GET.mock file
mockserver
Page 86
Javascript
mockserver
Page 88
Android 2.3 native browser…
Page 90
TESTING APIS
you can even decrypt the https responses :)
Page 91
Javascript
github.com/namshi/shish
shisha smoke tests made easy!
Page 92
Javascript
shisha
.smoke file
Page 93
Javascript
shisha
Page 95
An API is a layer on top of your domain
Page 96
Pick the layer that is most suitable
to your needs
Page 97
HTTP APIs are a good start
Page 99
HTTP METHOD
POST or PUT?
Page 100
HTTP METHOD
PUT or PATCH?
Page 101
USER TAGS
/users/johnny/tags
Page 102
USER TAGS
deleting a non-existent tag: 200, 204 or 404?
Page 103
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
Page 105
NAMING
/user/1 /users
/order/1 /orders
Page 106
NAMING
/city/1 /cities
/curriculum/1 /curricula
Page 107
NAMING/user/1 /users /order/1 /orders /city/1
/cities /curriculum/1 /curricula
Page 108
NAMING/user/1 /users /order/1 /orders /city/1
/cities /curriculum/1 /curricula
NOT GOD AT ALL!
Page 109
STICK WITH PLURALS!
Page 110
NAMING
/users1 /users
/orders/1 /orders
Page 111
NAMING
/cities/1 /cities
/curricula/1 /curricula
Page 112
NAMING/users/1 /users /orders/1 /orders /cities/1
/cities /curricula/1 /curricula
Page 113
UNIQUE RESOURCES
/users/1
/users/cirpo
/users/A323K833
Page 114
UNIQUE RESOURCES
/orders/15
/orders/A323K833
Page 115
UNIQUE RESOURCES
/orders/15
/orders/A323K833
AVOID INCREMENTAL NUMBERS
IF IT’S BUSINESS CRITICAL
Page 116
Unstructured APIs =
API aggregation
Page 117
api.example.org/v1/latest-news
Page 118
latest news + metatags + banners + navigation
yada yada yada
Page 119
Sort of a “wild” API for your whole app
Page 120
The client receives a GET on /something and will let the API figure out
what /u/something actually is
Page 121
Orchestration Layers
Page 122
https://engineering.groupon.com/2013/misc/i-tier-dismantling-the-monoliths/
Page 123
“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
Page 124
DOMAIN
users orders stock
images
Page 125
DOMAIN
Think about collections not
controllers
Page 126
DOMAIN
PUT/PATCH
try to always plan for full updates
Page 127
UNIFORM RESPONSES
Page 128
CODEBASE ORGANIZATION
Page 129
CODEBASE ORGANIZATION
one bundle for each api?
one bundle for each application?
one app for each sets of api?
Page 130
CODEBASE ORGANIZATION
start with an app
organize bundles semantically
create shared bundles
Page 132
CODEBASE ORGANIZATION
BUNDLES product
checkout warehouse
generic entity
Page 133
CODEBASE ORGANIZATION
APP product
BUNDLES checkout
warehouse generic entity
Page 135
CACHE ALL THE THINGS!
Page 137
MIDDLEWARE - CONNECT
Page 138
MIDDLEWARE - STACK
Page 140
EVERYTHING AS A RESOURCE
Page 144
(silly) browsers
Page 145
(silly) browsers
if a cross-domain request is cacheable, the android browser
goes nuts
Page 146
(silly) browsers
The request does not include
the Origin header
Page 147
(silly) browsers
Status code: 0
Page 148
(silly) browsers
WHAT. THE. HECK.
http://opensourcehacker.com/2011/03/20/android-webkit-xhr-status-code-0-and-expires-headers/
Page 150
Don’t play with fire
Page 151
Don’t play with fire
1 API, N clients consuming it
Page 152
Don’t play with fire
desktop browser, mobile browser,
ios app, android app...
Page 153
Don’t play with fire
Keep as much logic as possible on the
server
Page 154
Don’t play with fire
Less things to implement on every
client and centralized implementations
Page 155
Don’t play with fire
make it easy for theAPI clients
Page 156
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",
}
Page 157
Security matters
Page 158
Security matters
[ "[email protected] ", "[email protected] ", ...
]
Page 159
Security matters
for(;;);[ "[email protected] ", "[email protected] ", ...
]
Page 160
Security matters
while(1);[ "[email protected] ", "[email protected] ", ...
]
Page 161
Security matters
while(1);[ "[email protected] ", "[email protected] ", ...
]
Page 162
Security matters
Avoid [...]
http://bit.ly/json-hijacking
Page 163
Security matters
USE {…}
Page 164
That’s all folks
Page 165
@cirpo
github.com/cirpo
/
Page 166
we are hiring!tech.namshi.com/join-us
github.com/namshi
twitter.com/TechNamshi
tech.namshi.com
Page 169
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