GIVE ME SOME REST!
RESTFUL APIS MIT SYMFONY
Von /Paul Seiffert @seiffertp
// PAUL SEIFFERT
Softwarearchitekt bei SensioLabs Deutschland GmbH
REST?
REST!
Ressourcen ~ Objekte
HTTP Verben ~ Methoden
Links ~ Assoziationen
Repräsentationen ~ Views
ADDRESSIERBARKEIT
Jede Ressource hat eine Adresse (URI)
Beispiel:
http://example.com/movies/3
UNIFORM INTERFACE
MovieCollection
title: String
releaseDate: Date
Movie
character: String
Role
name: string
dateOfBirth: D...
GET /movies
HTTP/1.1 200 OK
Date: Mon, 14 Jul 2014 12:10:00 GMT
{
"movies": [
{
"title": "Indiana Jones and the Temple of ...
POST /movies
POST /movies HTTP/1.1
Content-Type: application/json
{
"movie": {
"title": "Indiana Jones and the Kingdom of ...
POST /movies
HTTP/1.1 201 Created
Date: Mon, 14 Jul 2014 12:15:01 GMT
Location: /movies/4
 
GET /movies/1
HTTP/1.1 200 OK
Date: Mon, 14 Jul 2014 12:10:00 GMT
{
"movie": {
"title": "Indiana Jones and the Temple of D...
PUT /movies/1
PUT /movies/1 HTTP/1.1
Content-Type: application/json
{
"movie": {
"title": "Indiana Jones and the Temple of...
PUT /movies/1
HTTP/1.1 204 No Content
Date: Mon, 14 Jul 2014 12:15:01 GMT
 
DELETE /movies/1
HTTP/1.1 204 No Content
Date: Mon, 14 Jul 2014 12:20:00 GMT
 
REST UND SYMFONY?
Symfony spricht HTTP (und somit auch REST) fließend!
ISN'T THERE A BUNDLE FOR REST??
ist super!
... für manche Projekte
FOSRestBundle
HERAUSFORDERUNGEN
"REST-Syntax"
Abbildung des Domain Models auf Ressourcen
Abbildung der Domain-Logik auf das Uniform Inte...
MUT ZUR EINFACHEN, SAUBEREN LÖSUNG!
Request
Application
Content Negotiation
Routing
Content Retrieval / Update
SerializationResponse
Security
SECURITY
Notwendiger Weise stateless
Im einfachsten Fall HTTP Basic Authentication
CONTENT-NEGOTIATION
GET / HTTP/1.1
Host: google.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/we...
ROUTING
/movies
Zeigt auf die Liste der Filme
/movies/1
Zeigt auf einen bestimmten Film
ROUTING
GET /movies
Gibt die Liste der Filme zurück
POST /movies
Legt einen neuen Film an
SERIALISIERUNG
Die Content-Negotiation bestimmt das Format
Das Routing bestimmt die Daten
SERIALISIERUNG
$result = new MovieResult(new Movie('Star Wars: A New Hope', '25 May 1977'));
$serializedContent = $seriali...
Request
Application
Content Negotiation
Routing
Content Retrieval / Update
SerializationResponse
Security
UND JETZT MIT SYMFONY!
Request
Application
Content Negotiation
Routing
Content Retrieval / Update
SerializationResponse
Request
Listener
View
Lis...
SECURITY
security:
firewalls:
api:
pattern: ^/
http_basic:
realm: "My Movie REST API"
stateless: true
access_control:
- { ...
NOCH MEHR SECURITY…
https://github.com/FriendsOfSymfony/FOSOAuthServerBundle
CONTENT NEGOTIATION
https://github.com/willdurand/Negotiation
<?php
$negotiator = new NegotiationFormatNegotiator();
$acce...
... IN EINEM REQUEST-LISTENER:
<?php
class FormatListener
{
public function onRequest(GetResponseEvent $event)
{
$request ...
FÜR SPRACHE UND CHARSET ANALOG.
ROUTING
movies_list:
pattern: /movies
methods: GET
defaults: { _controller: MoviesApiBundle:Movies:get }
movies_add:
patte...
DER CONTROLLER
Übersetzt aus HTTP-Logik in Applikations-Logik
Erstellt Responses oder gibt angeforderten Daten zurück
Arbe...
<?php
class MoviesController
{
public function getAction()
{
return $this->movieApiService->getMovieList();
}
public funct...
VOM CONTROLLER ZUM MODELL
Controller Service
Domain
Model
DTO Mapper
Validator
SERIALISIERUNG
https://github.com/schmittjoh/serializer
<?php
$serializer = $container->get('jms_serializer');
$serialized...
SERIALIZER MAPPING
MovieDto:
exclusion_policy: all
properties:
title:
expose: true
type: string
releaseDate:
expose: true
...
<?php
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentHttpKernelEventGetResponseForControllerResultEvent;
...
FRAGEN?
DANKE!
LITERATUR
Martin Fowler -
Richardson Maturity Model
Roy Fielding's Dissertation
"Architectural Styles and the Design of Ne...
Upcoming SlideShare
Loading in …5
×

Give me some REST - RESTful APIs mit Symfony

1,454 views

Published on

Webservices werden heute in vielen Bereichen der IT zur Integration unterschiedlicher Anwendungen verwendet. Die Klasse der REST-Webservices spielt dabei eine besondere Rolle, da REST sich auf die Grundlagen von HTTP stützt, einfach verständlich ist und relativ einfach in bestehende Anwendungen zu integrieren ist. Dieser Vortrag gibt einen Überblick über die Herausforderungen einer RESTful API und zeigt, wie diese mit der Hilfe von Symfony einfach gelöst werden können.

Diese Slides habe ich für meinen Vortrag auf der DWX 2014 genutzt.

Published in: Software
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,454
On SlideShare
0
From Embeds
0
Number of Embeds
12
Actions
Shares
0
Downloads
17
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Give me some REST - RESTful APIs mit Symfony

  1. 1. GIVE ME SOME REST! RESTFUL APIS MIT SYMFONY Von /Paul Seiffert @seiffertp
  2. 2. // PAUL SEIFFERT Softwarearchitekt bei SensioLabs Deutschland GmbH
  3. 3. REST?
  4. 4. REST! Ressourcen ~ Objekte HTTP Verben ~ Methoden Links ~ Assoziationen Repräsentationen ~ Views
  5. 5. ADDRESSIERBARKEIT Jede Ressource hat eine Adresse (URI) Beispiel: http://example.com/movies/3
  6. 6. UNIFORM INTERFACE MovieCollection title: String releaseDate: Date Movie character: String Role name: string dateOfBirth: Date Actor * 1 1 * 1 * GET /movies POST /movies GET /movies/1 PUT /movies/1 DELETE /movies/1
  7. 7. GET /movies HTTP/1.1 200 OK Date: Mon, 14 Jul 2014 12:10:00 GMT { "movies": [ { "title": "Indiana Jones and the Temple of Doom", "uri": "/movies/1" }, { "title": "Indiana Jones and the Last Crusade", "uri": "/movies/2" }, { "title": "Indiana Jones and the Temple of the Forbidden Eye", "uri": "/movies/3" } ] }  
  8. 8. POST /movies POST /movies HTTP/1.1 Content-Type: application/json { "movie": { "title": "Indiana Jones and the Kingdom of the Crystal Skull", "releaseDate": "22 May 2008" } }  
  9. 9. POST /movies HTTP/1.1 201 Created Date: Mon, 14 Jul 2014 12:15:01 GMT Location: /movies/4  
  10. 10. GET /movies/1 HTTP/1.1 200 OK Date: Mon, 14 Jul 2014 12:10:00 GMT { "movie": { "title": "Indiana Jones and the Temple of Doom", "releaseDate": "22 May 1984" }, "uri": "/movies/1" }  
  11. 11. PUT /movies/1 PUT /movies/1 HTTP/1.1 Content-Type: application/json { "movie": { "title": "Indiana Jones and the Temple of Doom", "releaseDate": "23 May 1984" } }  
  12. 12. PUT /movies/1 HTTP/1.1 204 No Content Date: Mon, 14 Jul 2014 12:15:01 GMT  
  13. 13. DELETE /movies/1 HTTP/1.1 204 No Content Date: Mon, 14 Jul 2014 12:20:00 GMT  
  14. 14. REST UND SYMFONY? Symfony spricht HTTP (und somit auch REST) fließend!
  15. 15. ISN'T THERE A BUNDLE FOR REST??
  16. 16. ist super! ... für manche Projekte FOSRestBundle
  17. 17. HERAUSFORDERUNGEN "REST-Syntax" Abbildung des Domain Models auf Ressourcen Abbildung der Domain-Logik auf das Uniform Interface Perfektionistisch sein! Pragmatisch sein!
  18. 18. MUT ZUR EINFACHEN, SAUBEREN LÖSUNG!
  19. 19. Request Application Content Negotiation Routing Content Retrieval / Update SerializationResponse Security
  20. 20. SECURITY Notwendiger Weise stateless Im einfachsten Fall HTTP Basic Authentication
  21. 21. CONTENT-NEGOTIATION GET / HTTP/1.1 Host: google.com Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8,de;q=0.6 HTTP/1.1 200 OK Content-Type: text/html Content-Language: en Content-Encoding: gzip HTTP/1.1 406 Not Acceptable
  22. 22. ROUTING /movies Zeigt auf die Liste der Filme /movies/1 Zeigt auf einen bestimmten Film
  23. 23. ROUTING GET /movies Gibt die Liste der Filme zurück POST /movies Legt einen neuen Film an
  24. 24. SERIALISIERUNG Die Content-Negotiation bestimmt das Format Das Routing bestimmt die Daten
  25. 25. SERIALISIERUNG $result = new MovieResult(new Movie('Star Wars: A New Hope', '25 May 1977')); $serializedContent = $serializer->serialize($result, 'json'); echo $serializedContend; { "movie": { "title": "Star Wars: A New Hope", "releaseDate": "25 May 1977" } }
  26. 26. Request Application Content Negotiation Routing Content Retrieval / Update SerializationResponse Security
  27. 27. UND JETZT MIT SYMFONY!
  28. 28. Request Application Content Negotiation Routing Content Retrieval / Update SerializationResponse Request Listener View Listener Symfony Routing Controller / Domain Logic Security Symfony Security
  29. 29. SECURITY security: firewalls: api: pattern: ^/ http_basic: realm: "My Movie REST API" stateless: true access_control: - { path: ^/, roles: ROLE_USER }
  30. 30. NOCH MEHR SECURITY… https://github.com/FriendsOfSymfony/FOSOAuthServerBundle
  31. 31. CONTENT NEGOTIATION https://github.com/willdurand/Negotiation <?php $negotiator = new NegotiationFormatNegotiator(); $acceptHeader = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'; $priorities = array('html', 'application/json', '*/*'); $format = $negotiator->getBestFormat($acceptHeader, $priorities); // $format == html
  32. 32. ... IN EINEM REQUEST-LISTENER: <?php class FormatListener { public function onRequest(GetResponseEvent $event) { $request = $event->getRequest(); $format = $this->negotiator->getBestFormat( $request->headers->get('Accept'), $this->availableFormats ); if (null === $format) { $format = $this->defaultFormat; } $request->attributes->set('_format', $format); } }
  33. 33. FÜR SPRACHE UND CHARSET ANALOG.
  34. 34. ROUTING movies_list: pattern: /movies methods: GET defaults: { _controller: MoviesApiBundle:Movies:get } movies_add: pattern: /movies methods: POST defaults: { _controller: MoviesApiBundle:Movies:post } movie_get: pattern: /movies/{id} methods: GET defaults: { _controller: MoviesApiBundle:Movie:get } movie_put: pattern: /movies/{id} methods: PUT defaults: { _controller: MoviesApiBundle:Movie:put } movie_delete: pattern: /movies/{id} methods: DELETE defaults: { _controller: MoviesApiBundle:Movie:delete }
  35. 35. DER CONTROLLER Übersetzt aus HTTP-Logik in Applikations-Logik Erstellt Responses oder gibt angeforderten Daten zurück Arbeitet (fast) format-agnostisch Und bitte mit !DTOs
  36. 36. <?php class MoviesController { public function getAction() { return $this->movieApiService->getMovieList(); } public function postAction(Request $request) { $movie = $this->serializer->deserialize( $request->getContent(), 'MovieDto', $request->attributes->get('_contentType') ); $this->movieApiService->addMovie($movie); $response = new Response('', 201); $response->headers->set( 'Location', $this->generateUrl('movie_get', ['id' => $movie->getId()]) ); return $response; } }
  37. 37. VOM CONTROLLER ZUM MODELL Controller Service Domain Model DTO Mapper Validator
  38. 38. SERIALISIERUNG https://github.com/schmittjoh/serializer <?php $serializer = $container->get('jms_serializer'); $serializedMovie = $serializer->serialize($movie, 'json'); $movie = $serializer->deserialize($serializedMovie, 'MovieDto', 'json');
  39. 39. SERIALIZER MAPPING MovieDto: exclusion_policy: all properties: title: expose: true type: string releaseDate: expose: true type: Date
  40. 40. <?php use SymfonyComponentHttpFoundationResponse; use SymfonyComponentHttpKernelEventGetResponseForControllerResultEvent; class ResponseSerializationListener { public function onView(GetResponseForControllerResultEvent $event) { $request = $event->getRequest(); $content = $this->serializer->serialize( $event->getControllerResult(), $request->attributes->get('_format') ); $event->setResponse(new Response($content)); } }
  41. 41. FRAGEN?
  42. 42. DANKE!
  43. 43. LITERATUR Martin Fowler - Richardson Maturity Model Roy Fielding's Dissertation "Architectural Styles and the Design of Network-based Software Architectures" Patterns of Enterprise Application Architecture

×