SlideShare a Scribd company logo
ABOUT REST &
SYMFONY
Maxence POUTORD
| | @_maxpou (https://twitter.com/_maxpou)  maxpou.fr (http://www.maxpou.fr/) 
maxence.poutord@gmail.com (mailto:maxence.poutord@gmail.com)
1 . 1
1 . 2
REVEALJS TIPS
ESC: slide overview
ALT + click: zoom
B: blackout
S: speaker notes
Print (then ctrl + p) (?print-pdf)
2 . 1
ABOUT ME
GET /speaker/maxpou HTTP/1.1
{
"name": "Maxence POUTORD",
"skills": ["Symfony2", "API", "NodeJS", "Software quality"],
"hobbies": ["motorbike", "cinema (Danish)", "cooking"],
"job": {
"job": "web consultant",
"company": "Conserto"
}
"_links": {
"self": { "href": "maxpou.fr/slides/slides/about-rest/" },
"blog": { "href": "maxpou.fr" },
"Twitter": { "href": "twitter.com/_maxpou" },
"mail": { "href": "maxence.poutord@gmail.com" }
}
}
REST:
REPRESENTATIONAL STATE TRANSFER
3 . 1
3 . 2
REST IN A NUTSHELL
So ware architectural style for World Wide Web apps
Introduced by Roy Thomas Fielding in 2000
PhD dissertation: Architectural Styles and the Design of Network-b
So ware Architectures
(http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_s
 REST is NOT a protocol!
3 . 3
REST CONSTRAINTS
Client–server: clients and servers are separated
Stateless: each request can be treated independently
Cache: client can cache response
Uniform Interface: client and server share a uniform
interface
Layered system: scalability (load balancing), security
(firewalls)
*Code-On-Demand (a.k.a. COD): client request code (flash,
java applet, js) from server and execute it!
* COD is the only one optional constraint in REST (because it's
reduce visibility & not every API need it)
3 . 4
RESOURCES AND REPRESENTATIONS
Resource: can be anything. Representation: Describe a
resource state
beer:
id: 42
shortName: Kwak
name: Pauwel Kwak
alcoholDegree: 8.4
color: amber
since: 1980
brewery: Bosteels Brewery
<beer id="42">
<short-name>Kwak</short-name>
<name>Pauwel Kwak</name>
<name>8,4</name>
<brewery id="51">
<name>Bosteels Brewery</name>
</brewery>
</beer>
About REST & Symfony
4 . 14 . 2
REST AND THE RICHARDSON
MATURITY MODEL (RMM)
martinfowler.com
(http://martinfowler.com/articles/richardsonMaturityModel.html)
5
LEVEL 0: SWAMP OF POX
HTTP tunnel request
Only POST/GET method
One entry point
/beer
/beer?action=list
/beer?action=get&id=3
/beer?action=delete&id=3
Example: SOAP and XML-RPC
6 . 1
LEVEL 1: RESOURCES
Identification of resources
1 URI = 1 resource
Example:
/breweries/51
/breweries/51/beers/42
6 . 2
ROUTE PATTERN (1/2):
/BEER/1 OR /BEERS/1?
Both of them are REST!
/hellomynameismaxenceandherearemybeers/1 works too!
But, plural noun should be used for collection names
6 . 3
ROUTE PATTERN (2/2): ADVICES
Avoid:
/beers/42/
/beers/42.json
/beers//limit/26
/ugly_name/42
/UglyName/42
Instead, prefer:
/ugly-name/42
/beers?color=blond
/beers?offset=12&limit=5&exclude=2,3&sort=-alcohol
"Cool URIs don't change"
— W3C
7 . 1
LEVEL 2: HTTP VERBS
Client use HTTP verbs
Example: GET, POST, PUT et DELETE...
Server use HTTP codes.
Represent a result of an action
Example: 200, 201, 403, 404, 500...
7 . 2
FOCUS: HTTP VERBS
Method Safe? Idempotent?
GET Yes Yes
HEAD Yes Yes
POST No No
PUT No Yes
PATCH No No
DELETE No Yes
Safe = cacheable
Idempotent = result independent on the number of executions
7 . 3
FOCUS: HTTP CODES 101
1XX Information
2XX Success
3XX Redirection
4XX Client Error
5XX Server Error
7 . 4
HTTP STATUS: THE BARE MINIMUM
200: OK
201: Created
204: No Content
206: Partial Content
301: Moved Permanently
400: Bad request
404: Not Found
500: Internal Server Error
List of HTTP status codes (Wikipedia)
(https://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
7 . 5
STILL LOST?
HTTP Status Codes Map (By Restlet) (http://restlet.com/http-
status-codes-map)
8 . 1
AM I RESTFUL IF I'M ONLY LEVEL 2
COMPLIANT?
8 . 2
WHY?
GET /beers
<beers>
<beer id="42">
<name>Pauwel Kwak</name>
<alcohol>8.4</alcohol>
</beer>
<beer id="101">
<name>Tripel Karmeliet</name>
<alcohol>8.4</alcohol>
</beer>
</beers>
 How can I interact with my Kwak?
8 . 3
WHAT DID ROY FIELDING SAID
If the engine of application state (and hence the API) is not being
driven by hypertext, then it cannot be RESTful and cannot be a
REST API. Period. [...]
Please try to adhere to them or choose some other buzzword for
your API.
Roy T. FIELDING - REST APIs must be hypertext-driven
(http://roy.gbiv.com/untangled/2008/rest-apis-must-be-
hypertext-driven)
9 . 1
LEVEL 3: HYPERMEDIA CONTROLS
(HATEOAS)
Hypertext As The Engine Of The Application State
Resources are self-describing/self-documenting
(discoverability)
Expose state and behavior: "the application state is
controlled and stored by the user agent"
Use links to describe HOW the service is used, and media
types to describe WHAT is expect
9 . 2
WITHOUT HATEOAS
<consumptions>
<consumption>
<beer id="42">
<name>Kwak</name>
</beer>
<formats>
<format qty="4">Pint</format>
</formats>
</consumption>
<consumption>
<beer id="101">
<name>Tripel Karmeliet</name>
</beer>
<formats>
<format qty="1">Half</format>
<format qty="0">Pint</format>
</formats>
</consumption>
</consumptions>
9 . 3
HATEOAS
<consumptions>
<consumption>
<beer id="42">
<name>Kwak</name>
<link rel="_self" href="/beers/42">
</beer>
<formats>
<format qty="8">
<name>Half</name>
<link rel="serve" href="/serve/beer/42?format=half">
</format>
</formats>
</consumption>
<consumption>
<beer id="101">
<name>Tripel Karmeliet</name>
<link rel="_self" href="/beers/101">
</beer>
<formats>
9 . 4
CONTENT NEGOTIATION
Before:
GET /fr/breweries/51.json
GET /en/breweries/51.xml
...
A er:
GET /breweries/51
Accept: application/json, application/xml;q=0.9, text/html;q=0.8,
text/*;q=0.7, */*;q=0.5
Accept-Language: fr, en;q=0.8, de;q=0.7
REST IS THE WEB!
9 . 5
10 . 1
CONGRATULATION!
10 . 2
WELL... MAYBE NOT!
JSON is not a hypermedia format
10 . 3
HAL+JSON example:
HAL (HYPERTEXT APPLICATION
LANGUAGE)
{
"_links": {
"self": { "href": "/beers?offset=1&limit=10" },
"next": { "href": "/beers?offset=11&limit=10" },
"ea:find": {
"href": "/beers{?id}",
"templated": true
}
}
}
10 . 4
JSON-LD
{
"@context": "http://schema.org",
"@type": "Brewery",
"name": "Bosteels Brewery",
"url": "http://bestbelgianspecialbeers.be",
"address": {
"@type": "PostalAddress",
"streetAddress": "Kerkstraat 96",
"addressLocality": "9255 Buggenhout",
"addressRegion": "Belgium"
}
}
LINKED DATA
10 . 5
10 . 6
Which hypermedia type?
OTHERS
Hydra + JSON-LD
SIREN
...

sookocheff.com/post/api/on-choosing-a-hypermedia-format/
(http://sookocheff.com/post/api/on-choosing-a-hypermedia-
format/)
FOCUS
11 . 1
REST = CRUD?
POST /contact
# mail body
11 . 2
VERSIONING
HTTP/1.1 200 OK
Content-Type: application/json; version=2
Location: /breweries/51
Deprecated call?
HTTP/1.1 406 NOT ACCEPTABLE
Content-Type: application/json
["application/json; version=1", "application/json; version=2", "application/xml; ver
11 . 3
11 . 4
CACHE
11 . 5
SECURITY
Authorization: OAuth
Authentication: OpenID
Both: OpenID Connect
Transport: TLS
OWASP REST Security Cheat Sheet
(https://www.owasp.org/index.php/REST_Security_Cheat_Shee
DEVELOPER EXPERIENCE
3:30:3 RULE (BY ORI PEKELMAN)
3 sec: WHAT
30 sec: WHERE
3 min: HOW
11 . 6
12 . 1
DOCUMENT APIS
12 . 2
RAML 1.0
/beers:
/{beerId}:
get:
description: Retrieve a specific beer
responses:
200:
body:
application/json:
example: |
{
"data": {
"id": "42",
"title": "Kwak",
"description": null,
"alcohol": 8.4
"_link": {
"_self": "http:/api.app.com/beers/42"
}
},
12 . 3
SWAGGER
Web API doc body format: FormData request format: json
GET /api/beers Bet all Beers entities
GET /api/beers/{id} Bet a Beer entity
GET /api/breweries Get all Breweries entities
POST /api/breweries Add a Brewery
GET /api/breweries/{id} Get a Brewery entity
PUT /api/breweries/{id} Update an existing Brewery (cannot create here, sorry)
Documentation auto-generated on Mon, 15 Feb 16 10:04:16 +0100
13 . 1
REST & PHP (SYMFONY2)
13 . 2
JMS SERIALIZER
In a nutshell:
(De-)serialize data of any complexity
Support XML, JSON, and YAML
Doctrine support
Custom exclusion strategies
 schmittjoh/serializer
(https://github.com/schmittjoh/serializer)
13 . 3
PROBLEM WITH MAPPING ENTITIES
13 . 4
DESIGN PATTERN: DATA TRANSFER
OBJECT
BeerDTO
name: String
brewery: StringBeers
name: String
Beers
Assembler
Brewery
name: String
location: String
alcohol: float
Data Transfer Object - Martin Fowler
(http://martinfowler.com/eaaCatalog/dataTransferObject.html)
13 . 5
FOSRESTBUNDLE
Toolbox
Automatic route generation
Content negotiation
Exceptions
Support (Symfony) Forms
API versioning
 FriendsOfSymfony/FOSRestBundle
(https://github.com/FriendsOfSymfony/FOSRestBundle)
13 . 6
FOSRESTBUNDLE: EXAMPLE
/**
* Get all Breweries entities
*
* @QueryParam(name="offset", requirements="d+", nullable=true,
* description="Offset from which to start listing breweries.")
* @QueryParam(name="limit", requirements="d+", nullable=true,
* description="How many breweries to return.")
*/
public function getBreweriesAction(ParamFetcher $paramFetcher)
{
$offset = $paramFetcher->get('offset');
$limit = $paramFetcher->get('limit');
$em = $this->getDoctrine()->getManager();
$breweries = $em ->getRepository('MaxpouBeerBundle:Brewery')
->findBy([], ['name' => 'ASC'], $limit, $offset);
return $breweries;
}
13 . 7
BAZINGAHATEOASBUNDLE
implementing representations for HATEOAS REST web
service
Exclusion strategies
Allows to configure links and embedded resources in XML,
YAML, PHP, or Annotations
 willdurand/BazingaHateoasBundle
(https://github.com/willdurand/BazingaHateoasBundle)
13 . 8
BAZINGAHATEOASBUNDLE: CODE
use HateoasConfigurationAnnotation as Hateoas;
/**
* BreweryDTO
* No business logic here
* @HateoasRelation("self", href = @HateoasRoute("api_get_brewerie", parameters =
*/
class BreweryDTO
{
private $id;
private $name;
/** @return UUID object id **/
public function getId()
{
return $this->id;
}
}
13 . 9
BAZINGAHATEOASBUNDLE: RESULT
GET breweries/6b9f3cfa-cc2c-11e5-8adf-2c4138ad20fa
{
"id": "6b9f3cfa-cc2c-11e5-8adf-2c4138ad20fa",
"name": "Bosteels brewery",
"_links": {
"self": {
"href": "/beerApp/web/app_dev.php/api/breweries/6b9f3cfa-cc2c-11e5-8adf-2c41
}
}
}
13 . 10
NELMIOAPIDOCBUNDLE
Generate a decent documentation
Swagger format
Support PHPDoc, JMS Serializer, FOSRestBundle, (SF) Forms
Export documentation (JSON, HTML, markdown)
Multiple documentation
Sandbox !
13 . 11
NELMIOAPIDOCBUNDLE: EXAMPLE
<?php
use NelmioApiDocBundleAnnotationApiDoc;
/**
* Get all Breweries entities
*
* @ApiDoc(
* statusCodes={
* 200="Returned when successful"
* })
* @QueryParam(name="offset", requirements="d+", nullable=true,
* description="Offset from which to start listing breweries.")
* @QueryParam(name="limit", requirements="d+", nullable=true,
* description="How many breweries to return.")
*/
public function getBreweriesAction(ParamFetcher $paramFetcher)
{
//...
}
13 . 12
SEE ALSO
Bundles:
friendsofsymfony/http-cache (Reverses proxies like varnish)
nelmio/cors-bundle (CORS)
hautelook/TemplatedUriRouter (RFC-6570)
dunglas/DunglasApiBundle (JSON-LD)
Examples:
gimler/symfony-rest-edition
liip/LiipHelloBundle
CONCLUSION
"REST isn’t what you think it is, and that’s OK"
14 . 1
PRAGMATISM OVER THEORY
14 . 2
USEFUL RESOURCES
15 . 1
15 . 2
By Leonard Richardson, Mike Amundsen, Sam Ruby
15 . 3
By Mark Masse
FURTHER READING
martinfowler.com/articles/richardsonMaturityModel.html
(http://martinfowler.com/articles/richardsonMaturityModel.htm
williamdurand.fr (http://williamdurand.fr)
RFC 2616 (hwww.ietf.org/rfc/rfc2616.txt)
https://groups.google.com/forum/#!forum/resting-with-symfony
(https://groups.google.com/forum/#!forum/resting-with-
symfony)
15 . 4
16 . 1
THANK YOU
QUESTIONS?

More Related Content

KEY
Rails Routing and URL design
hiq5
 
PDF
Facebook Open Stream API - Facebook Developer Garage Dhaka
Mohammad Emran Hasan
 
PDF
URL Design
Walter Ebert
 
PDF
funP 麻吉 開發者俱樂部十月份聚會
Nathan Chiu
 
PPT
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
Antonio Peric-Mazar
 
PDF
IBM WebSphere Portal Integrator for SAP - Escenario de ejemplo.
Dacartec Servicios Informáticos
 
PDF
feature flagging with rails engines v0.2
Enrico Teotti
 
PDF
Web Apps and more
Yan Shi
 
Rails Routing and URL design
hiq5
 
Facebook Open Stream API - Facebook Developer Garage Dhaka
Mohammad Emran Hasan
 
URL Design
Walter Ebert
 
funP 麻吉 開發者俱樂部十月份聚會
Nathan Chiu
 
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
Antonio Peric-Mazar
 
IBM WebSphere Portal Integrator for SAP - Escenario de ejemplo.
Dacartec Servicios Informáticos
 
feature flagging with rails engines v0.2
Enrico Teotti
 
Web Apps and more
Yan Shi
 

Similar to About REST & Symfony (20)

PDF
REST API Recommendations
Jeelani Shaik
 
PPTX
RESTful Services
Jason Gerard
 
PPT
Introduction to Google APIs
Siva Arunachalam
 
PDF
Creating Restful Web Services with restish
Grig Gheorghiu
 
PPT
RESTful SOA - 中科院暑期讲座
Li Yi
 
PDF
Doing REST Right
Kerry Buckley
 
PPTX
Real world RESTful service development problems and solutions
Bhakti Mehta
 
PDF
Don't screw it up! How to build durable API
Alessandro Cinelli (cirpo)
 
PPTX
Building Valuable Restful APIs - HRPHP 2015
Guillermo A. Fisher
 
PPTX
Rest APIs Training
Shekhar Kumar
 
PDF
Cwinters Intro To Rest And JerREST and Jersey Introductionsey
elliando dias
 
PDF
Rest web services
Paulo Gandra de Sousa
 
PPTX
An API Your Parents Would Be Proud Of
Jose Alfredo Alvarez Aldana
 
PDF
Restful风格ž„web服务架构
Benjamin Tan
 
PPTX
RESTful APIs in .NET
Greg Sohl
 
PDF
Crafting APIs
Tatiana Al-Chueyr
 
PDF
Build REST APIs like a Jedi with Symfony2
Almog Baku
 
PDF
REST APIs
Arthur De Magalhaes
 
PDF
WS-* vs. RESTful Services
Cesare Pautasso
 
PDF
Introduction to REST and Jersey
Chris Winters
 
REST API Recommendations
Jeelani Shaik
 
RESTful Services
Jason Gerard
 
Introduction to Google APIs
Siva Arunachalam
 
Creating Restful Web Services with restish
Grig Gheorghiu
 
RESTful SOA - 中科院暑期讲座
Li Yi
 
Doing REST Right
Kerry Buckley
 
Real world RESTful service development problems and solutions
Bhakti Mehta
 
Don't screw it up! How to build durable API
Alessandro Cinelli (cirpo)
 
Building Valuable Restful APIs - HRPHP 2015
Guillermo A. Fisher
 
Rest APIs Training
Shekhar Kumar
 
Cwinters Intro To Rest And JerREST and Jersey Introductionsey
elliando dias
 
Rest web services
Paulo Gandra de Sousa
 
An API Your Parents Would Be Proud Of
Jose Alfredo Alvarez Aldana
 
Restful风格ž„web服务架构
Benjamin Tan
 
RESTful APIs in .NET
Greg Sohl
 
Crafting APIs
Tatiana Al-Chueyr
 
Build REST APIs like a Jedi with Symfony2
Almog Baku
 
WS-* vs. RESTful Services
Cesare Pautasso
 
Introduction to REST and Jersey
Chris Winters
 
Ad

Recently uploaded (20)

PDF
Using Anchore and DefectDojo to Stand Up Your DevSecOps Function
Anchore
 
PDF
Advances in Ultra High Voltage (UHV) Transmission and Distribution Systems.pdf
Nabajyoti Banik
 
PDF
AI-Cloud-Business-Management-Platforms-The-Key-to-Efficiency-Growth.pdf
Artjoker Software Development Company
 
PDF
REPORT: Heating appliances market in Poland 2024
SPIUG
 
PDF
How Open Source Changed My Career by abdelrahman ismail
a0m0rajab1
 
PDF
Orbitly Pitch Deck|A Mission-Driven Platform for Side Project Collaboration (...
zz41354899
 
PDF
BLW VOCATIONAL TRAINING SUMMER INTERNSHIP REPORT
codernjn73
 
PDF
The Future of Mobile Is Context-Aware—Are You Ready?
iProgrammer Solutions Private Limited
 
PPTX
Applied-Statistics-Mastering-Data-Driven-Decisions.pptx
parmaryashparmaryash
 
PDF
Research-Fundamentals-and-Topic-Development.pdf
ayesha butalia
 
PDF
Economic Impact of Data Centres to the Malaysian Economy
flintglobalapac
 
PDF
A Strategic Analysis of the MVNO Wave in Emerging Markets.pdf
IPLOOK Networks
 
PDF
A Day in the Life of Location Data - Turning Where into How.pdf
Precisely
 
PDF
Automating ArcGIS Content Discovery with FME: A Real World Use Case
Safe Software
 
PDF
MASTERDECK GRAPHSUMMIT SYDNEY (Public).pdf
Neo4j
 
PDF
Data_Analytics_vs_Data_Science_vs_BI_by_CA_Suvidha_Chaplot.pdf
CA Suvidha Chaplot
 
PDF
The Future of Artificial Intelligence (AI)
Mukul
 
PPTX
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
 
PPTX
IT Runs Better with ThousandEyes AI-driven Assurance
ThousandEyes
 
PDF
Structs to JSON: How Go Powers REST APIs
Emily Achieng
 
Using Anchore and DefectDojo to Stand Up Your DevSecOps Function
Anchore
 
Advances in Ultra High Voltage (UHV) Transmission and Distribution Systems.pdf
Nabajyoti Banik
 
AI-Cloud-Business-Management-Platforms-The-Key-to-Efficiency-Growth.pdf
Artjoker Software Development Company
 
REPORT: Heating appliances market in Poland 2024
SPIUG
 
How Open Source Changed My Career by abdelrahman ismail
a0m0rajab1
 
Orbitly Pitch Deck|A Mission-Driven Platform for Side Project Collaboration (...
zz41354899
 
BLW VOCATIONAL TRAINING SUMMER INTERNSHIP REPORT
codernjn73
 
The Future of Mobile Is Context-Aware—Are You Ready?
iProgrammer Solutions Private Limited
 
Applied-Statistics-Mastering-Data-Driven-Decisions.pptx
parmaryashparmaryash
 
Research-Fundamentals-and-Topic-Development.pdf
ayesha butalia
 
Economic Impact of Data Centres to the Malaysian Economy
flintglobalapac
 
A Strategic Analysis of the MVNO Wave in Emerging Markets.pdf
IPLOOK Networks
 
A Day in the Life of Location Data - Turning Where into How.pdf
Precisely
 
Automating ArcGIS Content Discovery with FME: A Real World Use Case
Safe Software
 
MASTERDECK GRAPHSUMMIT SYDNEY (Public).pdf
Neo4j
 
Data_Analytics_vs_Data_Science_vs_BI_by_CA_Suvidha_Chaplot.pdf
CA Suvidha Chaplot
 
The Future of Artificial Intelligence (AI)
Mukul
 
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
 
IT Runs Better with ThousandEyes AI-driven Assurance
ThousandEyes
 
Structs to JSON: How Go Powers REST APIs
Emily Achieng
 
Ad

About REST & Symfony

  • 1. ABOUT REST & SYMFONY Maxence POUTORD | | @_maxpou (https://twitter.com/_maxpou)  maxpou.fr (http://www.maxpou.fr/)  [email protected] (mailto:[email protected])
  • 2. 1 . 1 1 . 2 REVEALJS TIPS ESC: slide overview ALT + click: zoom B: blackout S: speaker notes Print (then ctrl + p) (?print-pdf)
  • 3. 2 . 1 ABOUT ME GET /speaker/maxpou HTTP/1.1 { "name": "Maxence POUTORD", "skills": ["Symfony2", "API", "NodeJS", "Software quality"], "hobbies": ["motorbike", "cinema (Danish)", "cooking"], "job": { "job": "web consultant", "company": "Conserto" } "_links": { "self": { "href": "maxpou.fr/slides/slides/about-rest/" }, "blog": { "href": "maxpou.fr" }, "Twitter": { "href": "twitter.com/_maxpou" }, "mail": { "href": "[email protected]" } } }
  • 5. 3 . 1 3 . 2 REST IN A NUTSHELL So ware architectural style for World Wide Web apps Introduced by Roy Thomas Fielding in 2000 PhD dissertation: Architectural Styles and the Design of Network-b So ware Architectures (http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_s  REST is NOT a protocol!
  • 6. 3 . 3 REST CONSTRAINTS Client–server: clients and servers are separated Stateless: each request can be treated independently Cache: client can cache response Uniform Interface: client and server share a uniform interface Layered system: scalability (load balancing), security (firewalls) *Code-On-Demand (a.k.a. COD): client request code (flash, java applet, js) from server and execute it! * COD is the only one optional constraint in REST (because it's reduce visibility & not every API need it)
  • 7. 3 . 4 RESOURCES AND REPRESENTATIONS Resource: can be anything. Representation: Describe a resource state beer: id: 42 shortName: Kwak name: Pauwel Kwak alcoholDegree: 8.4 color: amber since: 1980 brewery: Bosteels Brewery <beer id="42"> <short-name>Kwak</short-name> <name>Pauwel Kwak</name> <name>8,4</name> <brewery id="51"> <name>Bosteels Brewery</name> </brewery> </beer>
  • 9. 4 . 14 . 2 REST AND THE RICHARDSON MATURITY MODEL (RMM) martinfowler.com (http://martinfowler.com/articles/richardsonMaturityModel.html)
  • 10. 5 LEVEL 0: SWAMP OF POX HTTP tunnel request Only POST/GET method One entry point /beer /beer?action=list /beer?action=get&id=3 /beer?action=delete&id=3 Example: SOAP and XML-RPC
  • 11. 6 . 1 LEVEL 1: RESOURCES Identification of resources 1 URI = 1 resource Example: /breweries/51 /breweries/51/beers/42
  • 12. 6 . 2 ROUTE PATTERN (1/2): /BEER/1 OR /BEERS/1? Both of them are REST! /hellomynameismaxenceandherearemybeers/1 works too! But, plural noun should be used for collection names
  • 13. 6 . 3 ROUTE PATTERN (2/2): ADVICES Avoid: /beers/42/ /beers/42.json /beers//limit/26 /ugly_name/42 /UglyName/42 Instead, prefer: /ugly-name/42 /beers?color=blond /beers?offset=12&limit=5&exclude=2,3&sort=-alcohol "Cool URIs don't change" — W3C
  • 14. 7 . 1 LEVEL 2: HTTP VERBS Client use HTTP verbs Example: GET, POST, PUT et DELETE... Server use HTTP codes. Represent a result of an action Example: 200, 201, 403, 404, 500...
  • 15. 7 . 2 FOCUS: HTTP VERBS Method Safe? Idempotent? GET Yes Yes HEAD Yes Yes POST No No PUT No Yes PATCH No No DELETE No Yes Safe = cacheable Idempotent = result independent on the number of executions
  • 16. 7 . 3 FOCUS: HTTP CODES 101 1XX Information 2XX Success 3XX Redirection 4XX Client Error 5XX Server Error
  • 17. 7 . 4 HTTP STATUS: THE BARE MINIMUM 200: OK 201: Created 204: No Content 206: Partial Content 301: Moved Permanently 400: Bad request 404: Not Found 500: Internal Server Error List of HTTP status codes (Wikipedia) (https://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
  • 18. 7 . 5 STILL LOST? HTTP Status Codes Map (By Restlet) (http://restlet.com/http- status-codes-map)
  • 19. 8 . 1 AM I RESTFUL IF I'M ONLY LEVEL 2 COMPLIANT?
  • 20. 8 . 2 WHY? GET /beers <beers> <beer id="42"> <name>Pauwel Kwak</name> <alcohol>8.4</alcohol> </beer> <beer id="101"> <name>Tripel Karmeliet</name> <alcohol>8.4</alcohol> </beer> </beers>  How can I interact with my Kwak?
  • 21. 8 . 3 WHAT DID ROY FIELDING SAID If the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API. Period. [...] Please try to adhere to them or choose some other buzzword for your API. Roy T. FIELDING - REST APIs must be hypertext-driven (http://roy.gbiv.com/untangled/2008/rest-apis-must-be- hypertext-driven)
  • 22. 9 . 1 LEVEL 3: HYPERMEDIA CONTROLS (HATEOAS) Hypertext As The Engine Of The Application State Resources are self-describing/self-documenting (discoverability) Expose state and behavior: "the application state is controlled and stored by the user agent" Use links to describe HOW the service is used, and media types to describe WHAT is expect
  • 23. 9 . 2 WITHOUT HATEOAS <consumptions> <consumption> <beer id="42"> <name>Kwak</name> </beer> <formats> <format qty="4">Pint</format> </formats> </consumption> <consumption> <beer id="101"> <name>Tripel Karmeliet</name> </beer> <formats> <format qty="1">Half</format> <format qty="0">Pint</format> </formats> </consumption> </consumptions>
  • 24. 9 . 3 HATEOAS <consumptions> <consumption> <beer id="42"> <name>Kwak</name> <link rel="_self" href="/beers/42"> </beer> <formats> <format qty="8"> <name>Half</name> <link rel="serve" href="/serve/beer/42?format=half"> </format> </formats> </consumption> <consumption> <beer id="101"> <name>Tripel Karmeliet</name> <link rel="_self" href="/beers/101"> </beer> <formats>
  • 25. 9 . 4 CONTENT NEGOTIATION Before: GET /fr/breweries/51.json GET /en/breweries/51.xml ... A er: GET /breweries/51 Accept: application/json, application/xml;q=0.9, text/html;q=0.8, text/*;q=0.7, */*;q=0.5 Accept-Language: fr, en;q=0.8, de;q=0.7
  • 26. REST IS THE WEB!
  • 27. 9 . 5 10 . 1 CONGRATULATION!
  • 28. 10 . 2 WELL... MAYBE NOT! JSON is not a hypermedia format
  • 29. 10 . 3 HAL+JSON example: HAL (HYPERTEXT APPLICATION LANGUAGE) { "_links": { "self": { "href": "/beers?offset=1&limit=10" }, "next": { "href": "/beers?offset=11&limit=10" }, "ea:find": { "href": "/beers{?id}", "templated": true } } }
  • 30. 10 . 4 JSON-LD { "@context": "http://schema.org", "@type": "Brewery", "name": "Bosteels Brewery", "url": "http://bestbelgianspecialbeers.be", "address": { "@type": "PostalAddress", "streetAddress": "Kerkstraat 96", "addressLocality": "9255 Buggenhout", "addressRegion": "Belgium" } }
  • 32. 10 . 5 10 . 6 Which hypermedia type? OTHERS Hydra + JSON-LD SIREN ...  sookocheff.com/post/api/on-choosing-a-hypermedia-format/ (http://sookocheff.com/post/api/on-choosing-a-hypermedia- format/)
  • 33. FOCUS
  • 34. 11 . 1 REST = CRUD? POST /contact # mail body
  • 35. 11 . 2 VERSIONING HTTP/1.1 200 OK Content-Type: application/json; version=2 Location: /breweries/51 Deprecated call? HTTP/1.1 406 NOT ACCEPTABLE Content-Type: application/json ["application/json; version=1", "application/json; version=2", "application/xml; ver
  • 36. 11 . 3 11 . 4 CACHE
  • 37. 11 . 5 SECURITY Authorization: OAuth Authentication: OpenID Both: OpenID Connect Transport: TLS OWASP REST Security Cheat Sheet (https://www.owasp.org/index.php/REST_Security_Cheat_Shee
  • 38. DEVELOPER EXPERIENCE 3:30:3 RULE (BY ORI PEKELMAN) 3 sec: WHAT 30 sec: WHERE 3 min: HOW
  • 39. 11 . 6 12 . 1 DOCUMENT APIS
  • 40. 12 . 2 RAML 1.0 /beers: /{beerId}: get: description: Retrieve a specific beer responses: 200: body: application/json: example: | { "data": { "id": "42", "title": "Kwak", "description": null, "alcohol": 8.4 "_link": { "_self": "http:/api.app.com/beers/42" } },
  • 41. 12 . 3 SWAGGER Web API doc body format: FormData request format: json GET /api/beers Bet all Beers entities GET /api/beers/{id} Bet a Beer entity GET /api/breweries Get all Breweries entities POST /api/breweries Add a Brewery GET /api/breweries/{id} Get a Brewery entity PUT /api/breweries/{id} Update an existing Brewery (cannot create here, sorry) Documentation auto-generated on Mon, 15 Feb 16 10:04:16 +0100
  • 42. 13 . 1 REST & PHP (SYMFONY2)
  • 43. 13 . 2 JMS SERIALIZER In a nutshell: (De-)serialize data of any complexity Support XML, JSON, and YAML Doctrine support Custom exclusion strategies  schmittjoh/serializer (https://github.com/schmittjoh/serializer)
  • 44. 13 . 3 PROBLEM WITH MAPPING ENTITIES
  • 45. 13 . 4 DESIGN PATTERN: DATA TRANSFER OBJECT BeerDTO name: String brewery: StringBeers name: String Beers Assembler Brewery name: String location: String alcohol: float Data Transfer Object - Martin Fowler (http://martinfowler.com/eaaCatalog/dataTransferObject.html)
  • 46. 13 . 5 FOSRESTBUNDLE Toolbox Automatic route generation Content negotiation Exceptions Support (Symfony) Forms API versioning  FriendsOfSymfony/FOSRestBundle (https://github.com/FriendsOfSymfony/FOSRestBundle)
  • 47. 13 . 6 FOSRESTBUNDLE: EXAMPLE /** * Get all Breweries entities * * @QueryParam(name="offset", requirements="d+", nullable=true, * description="Offset from which to start listing breweries.") * @QueryParam(name="limit", requirements="d+", nullable=true, * description="How many breweries to return.") */ public function getBreweriesAction(ParamFetcher $paramFetcher) { $offset = $paramFetcher->get('offset'); $limit = $paramFetcher->get('limit'); $em = $this->getDoctrine()->getManager(); $breweries = $em ->getRepository('MaxpouBeerBundle:Brewery') ->findBy([], ['name' => 'ASC'], $limit, $offset); return $breweries; }
  • 48. 13 . 7 BAZINGAHATEOASBUNDLE implementing representations for HATEOAS REST web service Exclusion strategies Allows to configure links and embedded resources in XML, YAML, PHP, or Annotations  willdurand/BazingaHateoasBundle (https://github.com/willdurand/BazingaHateoasBundle)
  • 49. 13 . 8 BAZINGAHATEOASBUNDLE: CODE use HateoasConfigurationAnnotation as Hateoas; /** * BreweryDTO * No business logic here * @HateoasRelation("self", href = @HateoasRoute("api_get_brewerie", parameters = */ class BreweryDTO { private $id; private $name; /** @return UUID object id **/ public function getId() { return $this->id; } }
  • 50. 13 . 9 BAZINGAHATEOASBUNDLE: RESULT GET breweries/6b9f3cfa-cc2c-11e5-8adf-2c4138ad20fa { "id": "6b9f3cfa-cc2c-11e5-8adf-2c4138ad20fa", "name": "Bosteels brewery", "_links": { "self": { "href": "/beerApp/web/app_dev.php/api/breweries/6b9f3cfa-cc2c-11e5-8adf-2c41 } } }
  • 51. 13 . 10 NELMIOAPIDOCBUNDLE Generate a decent documentation Swagger format Support PHPDoc, JMS Serializer, FOSRestBundle, (SF) Forms Export documentation (JSON, HTML, markdown) Multiple documentation Sandbox !
  • 52. 13 . 11 NELMIOAPIDOCBUNDLE: EXAMPLE <?php use NelmioApiDocBundleAnnotationApiDoc; /** * Get all Breweries entities * * @ApiDoc( * statusCodes={ * 200="Returned when successful" * }) * @QueryParam(name="offset", requirements="d+", nullable=true, * description="Offset from which to start listing breweries.") * @QueryParam(name="limit", requirements="d+", nullable=true, * description="How many breweries to return.") */ public function getBreweriesAction(ParamFetcher $paramFetcher) { //... }
  • 53. 13 . 12 SEE ALSO Bundles: friendsofsymfony/http-cache (Reverses proxies like varnish) nelmio/cors-bundle (CORS) hautelook/TemplatedUriRouter (RFC-6570) dunglas/DunglasApiBundle (JSON-LD) Examples: gimler/symfony-rest-edition liip/LiipHelloBundle
  • 54. CONCLUSION "REST isn’t what you think it is, and that’s OK"
  • 55. 14 . 1 PRAGMATISM OVER THEORY
  • 56. 14 . 2 USEFUL RESOURCES
  • 57. 15 . 1 15 . 2 By Leonard Richardson, Mike Amundsen, Sam Ruby
  • 58. 15 . 3 By Mark Masse
  • 59. FURTHER READING martinfowler.com/articles/richardsonMaturityModel.html (http://martinfowler.com/articles/richardsonMaturityModel.htm williamdurand.fr (http://williamdurand.fr) RFC 2616 (hwww.ietf.org/rfc/rfc2616.txt) https://groups.google.com/forum/#!forum/resting-with-symfony (https://groups.google.com/forum/#!forum/resting-with- symfony)
  • 60. 15 . 4 16 . 1 THANK YOU QUESTIONS?