Don't screw it up: how to build durable web apis @ PHPDay 2014 in Verona (ITA)
-
Upload
alessandro-nadalin -
Category
Technology
-
view
2.081 -
download
2
Transcript of Don't screw it up: how to build durable web apis @ PHPDay 2014 in Verona (ITA)
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
STACK
https://gist.github.com/odino/b3fdacceaa0cce65fbce
Avoid sessions
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
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
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