SlideShare a Scribd company logo
1 of 85
Download to read offline
THE DARK SIDE
OF THE APP
WHO ARE WE
?
SIMONE DI MAULO
Backend Developer
@Kataskopeo.com
aka @toretto460
Pugger since 2012
CLAUDIO D’ALICANDRO
Backend developer
@Chupamobile.com
@ClaudioSThought on twitter
Pugger since 2013
PUG ROMA
Monthly Meetings
TECH TALKS
PHP Fast API by @toretto460
ZendFramework by @lorenzoferrara
Laravel by @malatestafra
MongoDB by @kekko
… take a look at http://roma.grusp.org/
PROJECTS
https://github.com/PUGX
THE DARK SIDE
OF THE APP
android
iOS
APIs
i have a product
i have a service
i need APIs
DURABLE
EASY TO EVOLVE
SCALABLE
Booking Engine APIs
Booking engine requirements
● A user should be able to find a hotel so that he can
check the availability.
● A user should be able to show a list of room with
details so that he can choose one of them.
● A user should be able to find a hotel for the given
check-in/check-out date so that he can make a
reservation by choosing a free room.
Booking engine APIs
● Check the hotel availability
● Show the room detail
● Book a room
● Check the room availability
● Modify a booking
● Cancel a booking
RPC
Exposing the booking
functionality as function calls
that accept parameters.
RPC - Style
POST /booking-engine
Host: my-hotel.com
{
"action": "findHotelsByCity",
"args": {
"city": "Todi",
"order_by": "distance"
}
}
RPC - Style
HTTP/1.1 200 OK
{
"hotels": [
{
"id": "dahu5942hfki58-fjaau7645-lo987",
"name": "Hotel Europa",
"coordinates": { "lat": ..., "long": ...}
},
{
"id": "dr594dahty71013-jfuh628fh47ft37",
"name": "Hotel Asia",
"coordinates": { "lat": ..., "long": ...}
}
]
}
RPC - Style
POST /booking-engine
Host: my-hotel.com
{
"action": "getAvailability",
"args": {
"interval": {
"checkin": "2015-09-26",
"checkout": "2015-09-27"
},
"hotel_id": "dahu5942hfki58-fjaau7645-lo987"
}
}
There is no contract
between client and server
Hard to evolve
Hard to cache
too much lacks!
SOAP is the key
● a structured definition - WSDL ✓
● Transactions ✓
● WS-Security ✓
SOAP - Request
POST /FindHotelByCity.asmx HTTP/1.1
Host: my-hotel.com
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://my-hotel.com/FindHotelByCity"
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://my-
hotel.com/">
<SOAP-ENV:Body>
<ns1:HotelsToFind>
<ns1:City>Todi</ns1:City>
</ns1:HotelsToFind>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
SOAP - Response
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.
org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<HotelList>
<Hotel id="w3dhfu8272dlo-ldo8364j">
<Name>Hotel Europa</Name>
<Coordinates lat=".." lon=".."><Coordinates>
</Hotel>
<Hotel id="w3dhfu8272dlo-ldo8364j">
<Name>Hotel Europa</Name>
<Coordinates lat=".." lon=".."><Coordinates>
</Hotel>
</HotelList>
</soap:Body>
</soap:Envelope>
is SOAP the key ?
● Documentation NOT SO READABLE
● Tunneling over HTTP POST BAD
● Non standard Errors BAD
● Impossible to CACHE REALLY BAD
Use a contract
don’t expose the
domain logic
scalable
decoupled
IS SOAP THE KEY?
MAYBE NOT
REST
REST
is an architectural style
REST
gives a coordinated set of
constraints
REST Constraints
● Client-Server model
● Stateless
● Cacheable
● Layered System
● Uniform Interface
○ Identification of resources
○ Manipulation of resources through these
representations
○ Hypermedia as the engine of application state
Identification of RESOURCES
We are talking about RESOURCES
Well designed URIs
RESOURCES
/api/booking-engine
/api/hotels
/api/hotels?city=Todi
/api/hotels/12356/rooms
✗
✓
✓
✓
Booking engine APIs
● Check the hotel availability
● Show the room detail
● Book a room
● Check the room availability
● Modify a booking
● Cancel a booking
Check the Hotel availability - RPC
POST /booking-engine-api
{
"action": "findRoom",
"params": {
"hotel": 12456,
"interval": {
"checkin": "2015-10-01",
"checkout": "2015-10-09"
},
"pax": 3
}
}
HTTP/1.1 200 OK
Date: Sun, 27 Sep 2015 10:00:45 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
{
"rooms": [
{
"id": 567,
"beds": ["single", "double"],
"amenities": [...]
},
...
]
}
Check the Hotel availability - REST
GET /api/hotels/12456/rooms?checkin=2015-
10-01&checkout=2015-10-09&pax=3
HTTP/1.1 200 OK
Date: Sun, 27 Sep 2015 10:00:45 GMT
{
"rooms": [
{
"id": 567,
"beds": ["single", "double"],
"amenities": [...]
},
...
]
}
Does not change until
next booking
LET’S CACHE
HTTP CACHE
HTTP/1.1 200 OK
Date: Sun, 27 Sep 2015 10:00:45 GMT
Cache-Control: public, max-age=600
ETag: db87ju95dgtyg-12348765209
Expiration modelValidation model
I CAN’T CACHE IT
POST /booking-engine-api
{
"action": "findRoom",
"params": {
"interval": {
"checkin": "2015-10-01",
"checkout": "2015-10-09"
},
"pax": 3
}
"hotel": 12456
}
VERBS
What’s the difference
between GET and POST ?
GET
HEAD
PUT
POST PATCH
OPTIONS
DELETE
VERBS
GET
HEAD
PUT
POST PATCH
OPTIONS
DELETE
SAFE
GET
HEAD
PUT
POST PATCH
OPTIONS
DELETE
IDEMPOTENT
ERROR HANDLING
Check the Hotel availability
GET /api/hotels/12456/rooms?checkin=2015-10-01&checkout=2015-10-09&pax=3
HTTP/1.1 200 OK
Date: Sun, 27 Sep 2015 10:00:45 GMT
{
"error": "Hotel Not Found"
}
STATUS CODES
100 HTTP CONTINUE
101 HTTP SWITCHING PROTOCOLS
102 HTTP PROCESSING
201 HTTP CREATED
202 HTTP ACCEPTED
203 HTTP NON AUTHORITATIVE INFORMATION
204 HTTP NO CONTENT
205 HTTP RESET CONTENT
206 HTTP PARTIAL CONTENT
207 HTTP MULTI STATUS
208 HTTP ALREADY REPORTED
226 HTTP IM USED
300 HTTP MULTIPLE CHOICES
301 HTTP MOVED PERMANENTLY
302 HTTP FOUND
303 HTTP SEE OTHER
304 HTTP NOT MODIFIED
305 HTTP USE PROXY
306 HTTP RESERVED
307 HTTP TEMPORARY REDIRECT
308 HTTP PERMANENTLY REDIRECT
400 HTTP BAD REQUEST
401 HTTP UNAUTHORIZED
402 HTTP PAYMENT REQUIRED
403 HTTP FORBIDDEN
404 HTTP NOT FOUND
405 HTTP METHOD NOT ALLOWED
406 HTTP NOT ACCEPTABLE
407 HTTP PROXY AUTHENTICATION REQUIRED
408 HTTP REQUEST TIMEOUT
409 HTTP CONFLICT
410 HTTP GONE
411 HTTP LENGTH REQUIRED
412 HTTP PRECONDITION FAILED
413 HTTP REQUEST ENTITY TOO LARGE
414 HTTP REQUEST URI TOO LONG
415 HTTP UNSUPPORTED MEDIA TYPE
416 HTTP REQUESTED RANGE NOT SATISFIABLE
417 HTTP EXPECTATION FAILED
418 HTTP I AM A TEAPOT
422 HTTP UNPROCESSABLE ENTITY
423 HTTP LOCKED
424 HTTP FAILED DEPENDENCY
425 HTTP RESERVED FOR WEBDAV ADVANCED …
426 HTTP UPGRADE REQUIRED
428 HTTP PRECONDITION REQUIRED
429 HTTP TOO MANY REQUESTS
431 HTTP REQUEST HEADER FIELDS TOO LARGE
500 HTTP INTERNAL SERVER ERROR
501 HTTP NOT IMPLEMENTED
502 HTTP BAD GATEWAY
503 HTTP SERVICE UNAVAILABLE
504 HTTP GATEWAY TIMEOUT
505 HTTP VERSION NOT SUPPORTED
506 HTTP VARIANT ALSO NEGOTIATES EXPERIMENTAL
507 HTTP INSUFFICIENT STORAGE
...
200 HTTP OK SOAP is here
USE THE RIGHT STATUS CODE
GET /api/hotels/12456/rooms?checkin=2015-10-01&checkout=2015-10-09&pax=3
{...}
HTTP/1.1 200 OK
{"error": "Hotel Not Found"}
HTTP/1.1 404 Not Found
BE STANDARD
MIDDLEWARE
ex. MIDDLEWARE
ex. MIDDLEWARE
ex. MIDDLEWARE
ex. MIDDLEWARE
ex. MIDDLEWARE
var app = require('express')();
var logger = new (winston.Logger)({
transports: [
new (winston.transports.Console)({ level: 'info' })
]
});
app.use(function(req, res, next) {
logger.info("Received request: %s", JSON.stringify({
headers: req.headers,
method: req.method,
url: req.url
})
);
next();
});
var server = app.listen(3000);
ex. MIDDLEWARE
// File web/app.php
require_once __DIR__.'/../app/bootstrap.php.cache';
require_once __DIR__.'/../app/AppKernel.php';
require_once __DIR__.'/../app/AppCache.php';
use SymfonyComponentHttpFoundationRequest;
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
// wrap the default AppKernel with the AppCache one
$kernel = new AppCache($kernel);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
How REST
is
your API ?
Richardson Maturity Model
Level 0 - Plain Old XML
Level 1 - Resources
Level 2 - HTTP Verbs
Level 3 - Hypermedia Controls
HYPERMEDIA
HYPERMEDIA EXAMPLE
{
"links": [
{
"rel": "new",
"href": "http://mycompany.hotels/api/hotels/12456/room/new"
},
],
"rooms": [
{
"id": 567,
"beds": ["single", "double"],
"links": [
{
"rel": "self",
"href": "http://mycompany.hotels/api/hotels/12456/room/567"
},
{
"rel": "amenities",
"href": "http://mycompany.hotels/api/hotels/12456/room/567/amenities"
}
]
}, ...
]
}
THE RESPONSE FOR THE
CUSTOMER
# The Customer (from Android client)
GET /api/hotels/12456/room/new HTTP/1.1
Host: mycompany.hotels
HTTP/1.1 403 Forbidden
THE RESPONSE FOR THE ADMIN
# The Admin (From the SPA in the backoffice)
GET /api/hotels/12456/room/new HTTP/1.1
Host: mycompany.hotels
HTTP/1.1 200 OK
{
"links": {
"ref": "action",
"method": "POST"
"href": "http://mycompany.hotels/api/hotels/12456/room"
}
room: {
"beds": {
"multiple": true,
"options": {
"single": {
"label": "Single"
},
"double": {
"label": "Double"
}
},
}
}
}
HATEOAS
GETHEAD
PUT
POST
PATCH
OPTIONS
DELETE
VERBS
new
edit
remove
Haters gonna HATEOAS
HATEOAS ISN’T A SILVER BULLET
The documentation is important,
but instead of explaining what to
look for and where, should explain
how to look and how to interpret
the resources.
WITHSTAND BREAKING CHANGES
“The foolish and the dead alone never
change their opinions”
- James Russell Lowell -
API VERSIONING
Versioning an interface is just a
"polite" way to kill deployed clients.
— Roy Fielding.
WRONG WAY #1
Versioning the url
GET /api/v2/your/resource/id
Host: yoursite.com
WRONG WAY #2
Versioning by header
GET /api/your/resource/id
Host: yoursite.com
X-api-version: 2
WRONG WAY #3
Versioning by content type
GET /api/your/resource/id
Host: yoursite.com
Accept: application/vnd.mycorp.bookings.v2+json
Vary: Accept
Utopia is not a destination
but a direction
Questions ?
Thank You!

More Related Content

What's hot

Angular Tutorial Freshers and Experienced
Angular Tutorial Freshers and ExperiencedAngular Tutorial Freshers and Experienced
Angular Tutorial Freshers and Experiencedrajkamaltibacademy
 
OAuth Hacks A gentle introduction to OAuth 2 and Apache Oltu
OAuth Hacks A gentle introduction to OAuth 2 and Apache OltuOAuth Hacks A gentle introduction to OAuth 2 and Apache Oltu
OAuth Hacks A gentle introduction to OAuth 2 and Apache OltuAntonio Sanso
 
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
[CB16] Esoteric Web Application Vulnerabilities by Andrés RianchoCODE BLUE
 
What's new in Rails 4
What's new in Rails 4What's new in Rails 4
What's new in Rails 4Fabio Akita
 
Like a Genie from a Lamp: Headless JavaScript Unit Testing with Jasmine and P...
Like a Genie from a Lamp: Headless JavaScript Unit Testing with Jasmine and P...Like a Genie from a Lamp: Headless JavaScript Unit Testing with Jasmine and P...
Like a Genie from a Lamp: Headless JavaScript Unit Testing with Jasmine and P...Rob Friesel
 
Djangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django applicationDjangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django applicationMasashi Shibata
 
Detecting headless browsers
Detecting headless browsersDetecting headless browsers
Detecting headless browsersSergey Shekyan
 
In The Brain of Cagatay Civici: Exploring JavaServer Faces 2.0 and PrimeFaces
In The Brain of Cagatay Civici: Exploring JavaServer Faces 2.0 and PrimeFaces In The Brain of Cagatay Civici: Exploring JavaServer Faces 2.0 and PrimeFaces
In The Brain of Cagatay Civici: Exploring JavaServer Faces 2.0 and PrimeFaces Skills Matter
 
Pocket Authentication with OAuth on Firefox OS
Pocket Authentication with OAuth on Firefox OSPocket Authentication with OAuth on Firefox OS
Pocket Authentication with OAuth on Firefox OSChih-Hsuan Kuo
 

What's hot (14)

Angular Tutorial Freshers and Experienced
Angular Tutorial Freshers and ExperiencedAngular Tutorial Freshers and Experienced
Angular Tutorial Freshers and Experienced
 
OAuth Hacks A gentle introduction to OAuth 2 and Apache Oltu
OAuth Hacks A gentle introduction to OAuth 2 and Apache OltuOAuth Hacks A gentle introduction to OAuth 2 and Apache Oltu
OAuth Hacks A gentle introduction to OAuth 2 and Apache Oltu
 
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
[CB16] Esoteric Web Application Vulnerabilities by Andrés Riancho
 
What's new in Rails 4
What's new in Rails 4What's new in Rails 4
What's new in Rails 4
 
Look, ma! no clients!
Look, ma! no clients!Look, ma! no clients!
Look, ma! no clients!
 
Like a Genie from a Lamp: Headless JavaScript Unit Testing with Jasmine and P...
Like a Genie from a Lamp: Headless JavaScript Unit Testing with Jasmine and P...Like a Genie from a Lamp: Headless JavaScript Unit Testing with Jasmine and P...
Like a Genie from a Lamp: Headless JavaScript Unit Testing with Jasmine and P...
 
Djangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django applicationDjangoアプリのデプロイに関するプラクティス / Deploy django application
Djangoアプリのデプロイに関するプラクティス / Deploy django application
 
Detecting headless browsers
Detecting headless browsersDetecting headless browsers
Detecting headless browsers
 
In The Brain of Cagatay Civici: Exploring JavaServer Faces 2.0 and PrimeFaces
In The Brain of Cagatay Civici: Exploring JavaServer Faces 2.0 and PrimeFaces In The Brain of Cagatay Civici: Exploring JavaServer Faces 2.0 and PrimeFaces
In The Brain of Cagatay Civici: Exploring JavaServer Faces 2.0 and PrimeFaces
 
Index chrome
Index chromeIndex chrome
Index chrome
 
Pocket Authentication with OAuth on Firefox OS
Pocket Authentication with OAuth on Firefox OSPocket Authentication with OAuth on Firefox OS
Pocket Authentication with OAuth on Firefox OS
 
Intro to Silex
Intro to SilexIntro to Silex
Intro to Silex
 
Api
ApiApi
Api
 
PhpSpec extension points
PhpSpec extension pointsPhpSpec extension points
PhpSpec extension points
 

Similar to The dark side of the app

An introduction to Laravel Passport
An introduction to Laravel PassportAn introduction to Laravel Passport
An introduction to Laravel PassportMichael Peacock
 
RefCard RESTful API Design
RefCard RESTful API DesignRefCard RESTful API Design
RefCard RESTful API DesignOCTO Technology
 
HTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & socketsHTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & socketsRemy Sharp
 
Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example
Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example
Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example Anna Klepacka
 
RESTful API - GDG Tech Talk - Novembro de 2014
RESTful API - GDG Tech Talk - Novembro de 2014RESTful API - GDG Tech Talk - Novembro de 2014
RESTful API - GDG Tech Talk - Novembro de 2014Marlon Carvalho
 
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram VaswaniCreating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswanivvaswani
 
How to build Simple yet powerful API.pptx
How to build Simple yet powerful API.pptxHow to build Simple yet powerful API.pptx
How to build Simple yet powerful API.pptxChanna Ly
 
RoR Workshop - Web applications hacking - Ruby on Rails example
RoR Workshop - Web applications hacking - Ruby on Rails exampleRoR Workshop - Web applications hacking - Ruby on Rails example
RoR Workshop - Web applications hacking - Ruby on Rails exampleRailwaymen
 
Petr Dvořák: Mobilní webové služby pohledem iPhone developera
Petr Dvořák: Mobilní webové služby pohledem iPhone developeraPetr Dvořák: Mobilní webové služby pohledem iPhone developera
Petr Dvořák: Mobilní webové služby pohledem iPhone developeraWebExpo
 
Velocity EU 2014 — Offline-first web apps
Velocity EU 2014 — Offline-first web appsVelocity EU 2014 — Offline-first web apps
Velocity EU 2014 — Offline-first web appsandrewsmatt
 
Integrating WordPress With Web APIs
Integrating WordPress With Web APIsIntegrating WordPress With Web APIs
Integrating WordPress With Web APIsrandyhoyt
 
Firefox OS workshop, JSFoo, India
Firefox OS workshop, JSFoo, IndiaFirefox OS workshop, JSFoo, India
Firefox OS workshop, JSFoo, IndiaRobert Nyman
 
API Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API DocumentationAPI Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API DocumentationRouven Weßling
 
High Availability by Design
High Availability by DesignHigh Availability by Design
High Availability by DesignDavid Prinzing
 
The Future of the Web - Cold Front conference 2016
The Future of the Web - Cold Front conference 2016The Future of the Web - Cold Front conference 2016
The Future of the Web - Cold Front conference 2016Robert Nyman
 
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013Kiril Iliev
 
Securing RESTful Payment APIs Using OAuth 2
Securing RESTful Payment APIs Using OAuth 2Securing RESTful Payment APIs Using OAuth 2
Securing RESTful Payment APIs Using OAuth 2Jonathan LeBlanc
 
Web Services, for DevDays Belfast
Web Services, for DevDays BelfastWeb Services, for DevDays Belfast
Web Services, for DevDays Belfastchrismcclelland
 

Similar to The dark side of the app (20)

Develop webservice in PHP
Develop webservice in PHPDevelop webservice in PHP
Develop webservice in PHP
 
An introduction to Laravel Passport
An introduction to Laravel PassportAn introduction to Laravel Passport
An introduction to Laravel Passport
 
RefCard RESTful API Design
RefCard RESTful API DesignRefCard RESTful API Design
RefCard RESTful API Design
 
HTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & socketsHTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & sockets
 
Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example
Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example
Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example
 
RESTful API - GDG Tech Talk - Novembro de 2014
RESTful API - GDG Tech Talk - Novembro de 2014RESTful API - GDG Tech Talk - Novembro de 2014
RESTful API - GDG Tech Talk - Novembro de 2014
 
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram VaswaniCreating REST Applications with the Slim Micro-Framework by Vikram Vaswani
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
 
How to build Simple yet powerful API.pptx
How to build Simple yet powerful API.pptxHow to build Simple yet powerful API.pptx
How to build Simple yet powerful API.pptx
 
RoR Workshop - Web applications hacking - Ruby on Rails example
RoR Workshop - Web applications hacking - Ruby on Rails exampleRoR Workshop - Web applications hacking - Ruby on Rails example
RoR Workshop - Web applications hacking - Ruby on Rails example
 
Petr Dvořák: Mobilní webové služby pohledem iPhone developera
Petr Dvořák: Mobilní webové služby pohledem iPhone developeraPetr Dvořák: Mobilní webové služby pohledem iPhone developera
Petr Dvořák: Mobilní webové služby pohledem iPhone developera
 
- Webexpo 2010
- Webexpo 2010- Webexpo 2010
- Webexpo 2010
 
Velocity EU 2014 — Offline-first web apps
Velocity EU 2014 — Offline-first web appsVelocity EU 2014 — Offline-first web apps
Velocity EU 2014 — Offline-first web apps
 
Integrating WordPress With Web APIs
Integrating WordPress With Web APIsIntegrating WordPress With Web APIs
Integrating WordPress With Web APIs
 
Firefox OS workshop, JSFoo, India
Firefox OS workshop, JSFoo, IndiaFirefox OS workshop, JSFoo, India
Firefox OS workshop, JSFoo, India
 
API Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API DocumentationAPI Days Paris - Automatic Testing of (RESTful) API Documentation
API Days Paris - Automatic Testing of (RESTful) API Documentation
 
High Availability by Design
High Availability by DesignHigh Availability by Design
High Availability by Design
 
The Future of the Web - Cold Front conference 2016
The Future of the Web - Cold Front conference 2016The Future of the Web - Cold Front conference 2016
The Future of the Web - Cold Front conference 2016
 
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
 
Securing RESTful Payment APIs Using OAuth 2
Securing RESTful Payment APIs Using OAuth 2Securing RESTful Payment APIs Using OAuth 2
Securing RESTful Payment APIs Using OAuth 2
 
Web Services, for DevDays Belfast
Web Services, for DevDays BelfastWeb Services, for DevDays Belfast
Web Services, for DevDays Belfast
 

More from Simone Di Maulo

On fuctional programming, high order functions, ML
On fuctional programming, high order functions, MLOn fuctional programming, high order functions, ML
On fuctional programming, high order functions, MLSimone Di Maulo
 
Processing asyncrono dei dati - Symfony2 ❤ Message Queuing
Processing asyncrono dei dati - Symfony2 ❤ Message QueuingProcessing asyncrono dei dati - Symfony2 ❤ Message Queuing
Processing asyncrono dei dati - Symfony2 ❤ Message QueuingSimone Di Maulo
 

More from Simone Di Maulo (6)

Orm hero
Orm heroOrm hero
Orm hero
 
PHP Generators
PHP GeneratorsPHP Generators
PHP Generators
 
Docker cqrs react
Docker cqrs reactDocker cqrs react
Docker cqrs react
 
Fast api
Fast apiFast api
Fast api
 
On fuctional programming, high order functions, ML
On fuctional programming, high order functions, MLOn fuctional programming, high order functions, ML
On fuctional programming, high order functions, ML
 
Processing asyncrono dei dati - Symfony2 ❤ Message Queuing
Processing asyncrono dei dati - Symfony2 ❤ Message QueuingProcessing asyncrono dei dati - Symfony2 ❤ Message Queuing
Processing asyncrono dei dati - Symfony2 ❤ Message Queuing
 

Recently uploaded

"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 

Recently uploaded (20)

"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 

The dark side of the app

  • 1.
  • 4. SIMONE DI MAULO Backend Developer @Kataskopeo.com aka @toretto460 Pugger since 2012
  • 6.
  • 8. TECH TALKS PHP Fast API by @toretto460 ZendFramework by @lorenzoferrara Laravel by @malatestafra MongoDB by @kekko … take a look at http://roma.grusp.org/
  • 10. THE DARK SIDE OF THE APP
  • 12. APIs
  • 13. i have a product i have a service
  • 19. Booking engine requirements ● A user should be able to find a hotel so that he can check the availability. ● A user should be able to show a list of room with details so that he can choose one of them. ● A user should be able to find a hotel for the given check-in/check-out date so that he can make a reservation by choosing a free room.
  • 20. Booking engine APIs ● Check the hotel availability ● Show the room detail ● Book a room ● Check the room availability ● Modify a booking ● Cancel a booking
  • 21. RPC Exposing the booking functionality as function calls that accept parameters.
  • 22. RPC - Style POST /booking-engine Host: my-hotel.com { "action": "findHotelsByCity", "args": { "city": "Todi", "order_by": "distance" } }
  • 23. RPC - Style HTTP/1.1 200 OK { "hotels": [ { "id": "dahu5942hfki58-fjaau7645-lo987", "name": "Hotel Europa", "coordinates": { "lat": ..., "long": ...} }, { "id": "dr594dahty71013-jfuh628fh47ft37", "name": "Hotel Asia", "coordinates": { "lat": ..., "long": ...} } ] }
  • 24. RPC - Style POST /booking-engine Host: my-hotel.com { "action": "getAvailability", "args": { "interval": { "checkin": "2015-09-26", "checkout": "2015-09-27" }, "hotel_id": "dahu5942hfki58-fjaau7645-lo987" } }
  • 25. There is no contract between client and server
  • 29. SOAP is the key ● a structured definition - WSDL ✓ ● Transactions ✓ ● WS-Security ✓
  • 30. SOAP - Request POST /FindHotelByCity.asmx HTTP/1.1 Host: my-hotel.com Content-Type: text/xml; charset=utf-8 SOAPAction: "http://my-hotel.com/FindHotelByCity" <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://my- hotel.com/"> <SOAP-ENV:Body> <ns1:HotelsToFind> <ns1:City>Todi</ns1:City> </ns1:HotelsToFind> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
  • 31. SOAP - Response HTTP/1.1 200 OK Cache-Control: private, max-age=0 <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3. org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <HotelList> <Hotel id="w3dhfu8272dlo-ldo8364j"> <Name>Hotel Europa</Name> <Coordinates lat=".." lon=".."><Coordinates> </Hotel> <Hotel id="w3dhfu8272dlo-ldo8364j"> <Name>Hotel Europa</Name> <Coordinates lat=".." lon=".."><Coordinates> </Hotel> </HotelList> </soap:Body> </soap:Envelope>
  • 32. is SOAP the key ? ● Documentation NOT SO READABLE ● Tunneling over HTTP POST BAD ● Non standard Errors BAD ● Impossible to CACHE REALLY BAD
  • 33. Use a contract don’t expose the domain logic
  • 36. IS SOAP THE KEY?
  • 38. REST
  • 40. REST gives a coordinated set of constraints
  • 41. REST Constraints ● Client-Server model ● Stateless ● Cacheable ● Layered System ● Uniform Interface ○ Identification of resources ○ Manipulation of resources through these representations ○ Hypermedia as the engine of application state
  • 42. Identification of RESOURCES We are talking about RESOURCES Well designed URIs
  • 44. Booking engine APIs ● Check the hotel availability ● Show the room detail ● Book a room ● Check the room availability ● Modify a booking ● Cancel a booking
  • 45. Check the Hotel availability - RPC POST /booking-engine-api { "action": "findRoom", "params": { "hotel": 12456, "interval": { "checkin": "2015-10-01", "checkout": "2015-10-09" }, "pax": 3 } } HTTP/1.1 200 OK Date: Sun, 27 Sep 2015 10:00:45 GMT Cache-Control: max-age=0, no-cache, no-store Pragma: no-cache { "rooms": [ { "id": 567, "beds": ["single", "double"], "amenities": [...] }, ... ] }
  • 46. Check the Hotel availability - REST GET /api/hotels/12456/rooms?checkin=2015- 10-01&checkout=2015-10-09&pax=3 HTTP/1.1 200 OK Date: Sun, 27 Sep 2015 10:00:45 GMT { "rooms": [ { "id": 567, "beds": ["single", "double"], "amenities": [...] }, ... ] }
  • 47. Does not change until next booking
  • 49. HTTP CACHE HTTP/1.1 200 OK Date: Sun, 27 Sep 2015 10:00:45 GMT Cache-Control: public, max-age=600 ETag: db87ju95dgtyg-12348765209 Expiration modelValidation model
  • 50. I CAN’T CACHE IT POST /booking-engine-api { "action": "findRoom", "params": { "interval": { "checkin": "2015-10-01", "checkout": "2015-10-09" }, "pax": 3 } "hotel": 12456 }
  • 56. Check the Hotel availability GET /api/hotels/12456/rooms?checkin=2015-10-01&checkout=2015-10-09&pax=3 HTTP/1.1 200 OK Date: Sun, 27 Sep 2015 10:00:45 GMT { "error": "Hotel Not Found" }
  • 57. STATUS CODES 100 HTTP CONTINUE 101 HTTP SWITCHING PROTOCOLS 102 HTTP PROCESSING 201 HTTP CREATED 202 HTTP ACCEPTED 203 HTTP NON AUTHORITATIVE INFORMATION 204 HTTP NO CONTENT 205 HTTP RESET CONTENT 206 HTTP PARTIAL CONTENT 207 HTTP MULTI STATUS 208 HTTP ALREADY REPORTED 226 HTTP IM USED 300 HTTP MULTIPLE CHOICES 301 HTTP MOVED PERMANENTLY 302 HTTP FOUND 303 HTTP SEE OTHER 304 HTTP NOT MODIFIED 305 HTTP USE PROXY 306 HTTP RESERVED 307 HTTP TEMPORARY REDIRECT 308 HTTP PERMANENTLY REDIRECT 400 HTTP BAD REQUEST 401 HTTP UNAUTHORIZED 402 HTTP PAYMENT REQUIRED 403 HTTP FORBIDDEN 404 HTTP NOT FOUND 405 HTTP METHOD NOT ALLOWED 406 HTTP NOT ACCEPTABLE 407 HTTP PROXY AUTHENTICATION REQUIRED 408 HTTP REQUEST TIMEOUT 409 HTTP CONFLICT 410 HTTP GONE 411 HTTP LENGTH REQUIRED 412 HTTP PRECONDITION FAILED 413 HTTP REQUEST ENTITY TOO LARGE 414 HTTP REQUEST URI TOO LONG 415 HTTP UNSUPPORTED MEDIA TYPE 416 HTTP REQUESTED RANGE NOT SATISFIABLE 417 HTTP EXPECTATION FAILED 418 HTTP I AM A TEAPOT 422 HTTP UNPROCESSABLE ENTITY 423 HTTP LOCKED 424 HTTP FAILED DEPENDENCY 425 HTTP RESERVED FOR WEBDAV ADVANCED … 426 HTTP UPGRADE REQUIRED 428 HTTP PRECONDITION REQUIRED 429 HTTP TOO MANY REQUESTS 431 HTTP REQUEST HEADER FIELDS TOO LARGE 500 HTTP INTERNAL SERVER ERROR 501 HTTP NOT IMPLEMENTED 502 HTTP BAD GATEWAY 503 HTTP SERVICE UNAVAILABLE 504 HTTP GATEWAY TIMEOUT 505 HTTP VERSION NOT SUPPORTED 506 HTTP VARIANT ALSO NEGOTIATES EXPERIMENTAL 507 HTTP INSUFFICIENT STORAGE ... 200 HTTP OK SOAP is here
  • 58. USE THE RIGHT STATUS CODE GET /api/hotels/12456/rooms?checkin=2015-10-01&checkout=2015-10-09&pax=3 {...} HTTP/1.1 200 OK {"error": "Hotel Not Found"} HTTP/1.1 404 Not Found
  • 65. ex. MIDDLEWARE var app = require('express')(); var logger = new (winston.Logger)({ transports: [ new (winston.transports.Console)({ level: 'info' }) ] }); app.use(function(req, res, next) { logger.info("Received request: %s", JSON.stringify({ headers: req.headers, method: req.method, url: req.url }) ); next(); }); var server = app.listen(3000);
  • 66. ex. MIDDLEWARE // File web/app.php require_once __DIR__.'/../app/bootstrap.php.cache'; require_once __DIR__.'/../app/AppKernel.php'; require_once __DIR__.'/../app/AppCache.php'; use SymfonyComponentHttpFoundationRequest; $kernel = new AppKernel('prod', false); $kernel->loadClassCache(); // wrap the default AppKernel with the AppCache one $kernel = new AppCache($kernel); $request = Request::createFromGlobals(); $response = $kernel->handle($request); $response->send(); $kernel->terminate($request, $response);
  • 68. Richardson Maturity Model Level 0 - Plain Old XML Level 1 - Resources Level 2 - HTTP Verbs Level 3 - Hypermedia Controls
  • 70. HYPERMEDIA EXAMPLE { "links": [ { "rel": "new", "href": "http://mycompany.hotels/api/hotels/12456/room/new" }, ], "rooms": [ { "id": 567, "beds": ["single", "double"], "links": [ { "rel": "self", "href": "http://mycompany.hotels/api/hotels/12456/room/567" }, { "rel": "amenities", "href": "http://mycompany.hotels/api/hotels/12456/room/567/amenities" } ] }, ... ] }
  • 71. THE RESPONSE FOR THE CUSTOMER # The Customer (from Android client) GET /api/hotels/12456/room/new HTTP/1.1 Host: mycompany.hotels HTTP/1.1 403 Forbidden
  • 72. THE RESPONSE FOR THE ADMIN # The Admin (From the SPA in the backoffice) GET /api/hotels/12456/room/new HTTP/1.1 Host: mycompany.hotels HTTP/1.1 200 OK { "links": { "ref": "action", "method": "POST" "href": "http://mycompany.hotels/api/hotels/12456/room" } room: { "beds": { "multiple": true, "options": { "single": { "label": "Single" }, "double": { "label": "Double" } }, } } }
  • 76. HATEOAS ISN’T A SILVER BULLET The documentation is important, but instead of explaining what to look for and where, should explain how to look and how to interpret the resources.
  • 77. WITHSTAND BREAKING CHANGES “The foolish and the dead alone never change their opinions” - James Russell Lowell -
  • 79. Versioning an interface is just a "polite" way to kill deployed clients. — Roy Fielding.
  • 80. WRONG WAY #1 Versioning the url GET /api/v2/your/resource/id Host: yoursite.com
  • 81. WRONG WAY #2 Versioning by header GET /api/your/resource/id Host: yoursite.com X-api-version: 2
  • 82. WRONG WAY #3 Versioning by content type GET /api/your/resource/id Host: yoursite.com Accept: application/vnd.mycorp.bookings.v2+json Vary: Accept
  • 83. Utopia is not a destination but a direction