Services web
     RESTful


   Raphaël Rougeron
Conférence PHPQuébec 2009
A propos de moi

    Raphaël Rougeron <goldoraf@gmail.com>



          depuis... bien longtemps !



    Expert technol...
Avant-propos




     Je n'ai rien contre SOAP !
Principes de SOAP

    SOAP = RPC via HTTP



    Remote Procedure Call



    Invocation de méthodes d'objets distants
...
Principe du web




  L'hypertexte permet la navigation au sein de
        nuages de données distribuées
La complexité de SOAP
La simplicité du web




          HTTP, URI, (X)HTML
The web is agreement




                  http://www.flickr.com/photos/psd/1805709102/
quot;Il existe deux manières de concevoir un logiciel.
La première, c’est de le faire si simple qu’il est
évident qu’il ne...
quot;Things should be made as simple as possible,
               but not simpler.quot;
                                 Al...
HTTP


GET / HTTP/1.1
Host: www.google.fr
User-Agent: Mozilla/5.0 (Linux; ...
Accept: text/xml,application/xml,...
Accept-...
HTTP
    Méthode
                  Chemin

GET / HTTP/1.1
Host: www.google.fr
User-Agent: Mozilla/5.0 (Linux; ...
Accept: ...
HTTP


HTTP/1.x 200 OK
Connection: Keep-Alive
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Server: gws
Co...
HTTP

                   Code de réponse

HTTP/1.x 200 OK
Connection: Keep-Alive
Cache-Control: private
Content-Type: text...
REST




       Qu'est ce que REST ?
         3 définitions possibles
Representational State Transfer

    Thèse de Roy Fielding, 2000



    Un ensemble de critères de conception, bâti sur
...
Services / applications RESTful




         Ce dont nous allons parler :
  Une architecture web utilisant HTTP, URI, et
 ...
REST-RPC

    XML via HTTP sans SOAP



    Approche RPC



    Requêtes GET ou POST



    Egalement appelé quot;POXqu...
Principes (ou contraintes) REST
Ressources

Peuvent être n'importe quelle entité, physique ou
non !
    Un utilisateur



    Une conférence



    Une ...
URIs et adressabilité

Donner à chaque ressource un identifiant :
    http://example.com/users/fred



    http://example...
Absence d'état

    Chaque requête HTTP est isolée des autres



    Chaque requête comprend toutes les


    informatio...
Représentations

    XHTML



    XML



    JSON       L'idée est de retourner



            différentes représentati...
Représentations

GET /users/fred
Host: example.com
Accept: application/xml
…
<user>
  ....
</user>

GET /users/fred
Host: ...
Interface uniforme

 GET               Récupérer une information
 PUT               Modifier une ressource
               ...
Conception RESTful
                 ou
quot;Et si on refaisait l'API de Flickr ?quot;
Flickr

GET http://api.flickr.com/services/rest/
    ?method=flickr.photos.getRecent&extras=geo,tags
GET http://api.flickr...
Flickr v.2.0




          1. Définir les ressources
Flickr v.2.0

    Utilisateurs



    Photos



    Tags



    Commentaires

Flickr v.2.0




    2. Nommer les ressources par des URIs
Flickr v.2.0

http://api.flickr.com/users/fred
http://api.flickr.com/users/fred/photos/recent
http://api.flickr.com/users/...
Flickr v.2.0




        3. Exposer certaines méthodes
             de l'interface uniforme
Flickr v.2.0

                  Méthode      URI
                  GET          /users
                  POST         /use...
Flickr v.2.0
        Méthode         URI
        GET             /users/fred/photos/12345/tags
        POST            /us...
Flickr v.2.0




         4. Définir les représentations
Flickr v.2.0

    En entrée (POST, PUT) :



        XML
    


        URL-encoded
    



    En sortie :



       ...
Flickr

<photos page=quot;2quot; pages=quot;89quot; perpage=quot;10quot; total=quot;881quot;>
   <photo id=quot;2636quot; ...
Flickr v.2.0




        5. Définir les réponses HTTP :
        Déroulement normal/anormal
Flickr v.2.0

    GET : 200 OK | 404 Not found



    POST : 201 Created | 409 Conflict



    PUT, DELETE : 200 0K



...
Flickr v.2.0




           6. Implémenter le tout ?

        Il reste encore un problème...
HATEOS

Hypermedia as the engine of application state

quot;A REST API should be entered with no prior knowledge beyond
th...
Flickr



Exemple : construction des URIs vers les photos
Une documentation est nécessaire pour naviguer dans l'API !!!

h...
HATEOS




    Comment résoudre ce problème ?
Connexité



Ou relier les choses entre elles :

<order href=quot;http://example.com/orders/1234quot;>
  <client href=quot...
Connexité


L'exemple d'ATOM :
<?xml version=quot;1.0quot;?>
<entry xmlns=quot;http://www.w3.org/2005/Atomquot;>
    <titl...
URI Templates



Proposé à l'IETF par Joe Grégorio :

http://www.google.com/search?{-join|&|q,num}
http://www.google.com/n...
WADL


<resources base=quot;http://service.example.com/myservices/quot;>
   <resource path=quot;searchquot;>
     <method ...
Authentification
Authentification

    HTTP Basic



        Mot de passe en clair (base64)
    


        À n'utiliser qu'en HTTPS
    ...
WSSE Username Token

Serveur :
HTTP/1.1 401 Unauthorized
WWW-Authenticate: WSSE realm=quot;fooquot;, profile=quot;Username...
WSSE Username Token



<?php

$nonce = md5(uniqid(time()));
$date = date(DATE_ATOM);
$pwd   = 'pasecure';

$digest_pwd = b...
WSSE Username Token

    Simple à implémenter



    Rien à installer (sauf peut-être pecl_http...)



    N'envoie pas ...
Des exemples ?
Exemples
PHP et REST
PHP et REST

    Nombreux outils XML



    json_encode, json_decode



    Extension curl pour consommer les services
...
RESTful frameworks ?

    Tonic





    Konstrukt





    Recess





    WSO2

CakePHP
// app/config/routes.php
Router::mapResources('posts');
Router::parseExtensions();

// app/controllers/posts_contr...
Symfony

    De grands progrès en 1.2



    quot;Routes as first-class objectsquot;



    SfRequestRoute permet de pré...
Zend Framework

Zend_Rest_Server, un mauvais choix :
    seuls GET et POST sont supportés


    (REST-RPC)
    conçu pour...
Zend Framework

Une autre approche :
    Profiter de l'extensibilité des composants MVC



    Zend_Controller_Request_Ht...
Epilogue

    Soyez sceptiques



    Apprenez en plus sur REST



    Des problèmes restent à résoudre



    Retourne...
Prochain SlideShare
Chargement dans…5
×

Services web RESTful

8 159 vues

Publié le

Publié dans : Technologie, Sports
0 commentaire
3 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

Aucun téléchargement
Vues
Nombre de vues
8 159
Sur SlideShare
0
Issues des intégrations
0
Intégrations
61
Actions
Partages
0
Téléchargements
187
Commentaires
0
J’aime
3
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Services web RESTful

  1. 1. Services web RESTful Raphaël Rougeron Conférence PHPQuébec 2009
  2. 2. A propos de moi Raphaël Rougeron <goldoraf@gmail.com>  depuis... bien longtemps !  Expert technologies web chez  Contributeur d'  Framework Stato  http://stato-framework.org http://raphael-rougeron.com 
  3. 3. Avant-propos Je n'ai rien contre SOAP !
  4. 4. Principes de SOAP SOAP = RPC via HTTP  Remote Procedure Call  Invocation de méthodes d'objets distants  Héritage de CORBA, DCOM, mais plus lourd  Nécessite des outils (IDEs, génération WSDL) 
  5. 5. Principe du web L'hypertexte permet la navigation au sein de nuages de données distribuées
  6. 6. La complexité de SOAP
  7. 7. La simplicité du web HTTP, URI, (X)HTML
  8. 8. The web is agreement http://www.flickr.com/photos/psd/1805709102/
  9. 9. quot;Il existe deux manières de concevoir un logiciel. La première, c’est de le faire si simple qu’il est évident qu’il ne présente aucun problème. La seconde, c’est de le faire si compliqué qu’il ne présente aucun problème évident. La première méthode est de loin la plus complexe.quot; C.A.R. Hoare
  10. 10. quot;Things should be made as simple as possible, but not simpler.quot; Albert Einstein
  11. 11. HTTP GET / HTTP/1.1 Host: www.google.fr User-Agent: Mozilla/5.0 (Linux; ... Accept: text/xml,application/xml,... Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Cookie: SID=DQAAAHg.......
  12. 12. HTTP Méthode Chemin GET / HTTP/1.1 Host: www.google.fr User-Agent: Mozilla/5.0 (Linux; ... Accept: text/xml,application/xml,... Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3 Entêtes Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Cookie: SID=DQAAAHg....... Corps
  13. 13. HTTP HTTP/1.x 200 OK Connection: Keep-Alive Cache-Control: private Content-Type: text/html; charset=UTF-8 Server: gws Content-Length: 2614 Date: Wed, 12 Dec 2007 08:57:47 GMT Content-Encoding: gzip <html><head><meta http-equiv=quot;content-typequot; content=quot;text/html; charset=UTF-8quot;><title>Google</title>.....
  14. 14. HTTP Code de réponse HTTP/1.x 200 OK Connection: Keep-Alive Cache-Control: private Content-Type: text/html; charset=UTF-8 Entêtes Server: gws Content-Length: 2614 Date: Wed, 12 Dec 2007 08:57:47 GMT Content-Encoding: gzip <html><head><meta http-equiv=quot;content-typequot; content=quot;text/html; charset=UTF-8quot;><title>Google</title>..... Corps
  15. 15. REST Qu'est ce que REST ? 3 définitions possibles
  16. 16. Representational State Transfer Thèse de Roy Fielding, 2000  Un ensemble de critères de conception, bâti sur  4 principes simples L'architecture originale du web par l'un des  pères du protocole HTTP... ...définie a posteriori 
  17. 17. Services / applications RESTful Ce dont nous allons parler : Une architecture web utilisant HTTP, URI, et autres standards correctement
  18. 18. REST-RPC XML via HTTP sans SOAP  Approche RPC  Requêtes GET ou POST  Egalement appelé quot;POXquot;  Hélas beaucoup de services étiquettés REST tombent dans cette catégorie... http://api.flickr.com/services/rest/?method=flickr.photos.getRecent
  19. 19. Principes (ou contraintes) REST
  20. 20. Ressources Peuvent être n'importe quelle entité, physique ou non ! Un utilisateur  Une conférence  Une pièce mécanique  La dernière version d'un logiciel  Un pays 
  21. 21. URIs et adressabilité Donner à chaque ressource un identifiant : http://example.com/users/fred  http://example.com/conference/2009  http://example.com/products/1234  http://example.com/downloads/latest  http://example.com/wiki/Canada 
  22. 22. Absence d'état Chaque requête HTTP est isolée des autres  Chaque requête comprend toutes les  informations nécessaires au serveur pour y répondre : http://example.com/fr/users/me/profile Conséquences heureuses :  Mise en cache possible (proxies)  Performances  Scalability 
  23. 23. Représentations XHTML  XML  JSON L'idée est de retourner  différentes représentations PNG  d'une ressource en fonction PDF  des souhaits du client YAML  CSV  ... 
  24. 24. Représentations GET /users/fred Host: example.com Accept: application/xml … <user> .... </user> GET /users/fred Host: example.com Accept: text/x-vcard … BEGIN:VCARD … END:VCARD
  25. 25. Interface uniforme GET Récupérer une information PUT Modifier une ressource (ou la créer si on peut deviner son URI) POST Créer une sous-ressource DELETE Dois-je le préciser ? Sans oublier HEAD et OPTIONS...
  26. 26. Conception RESTful ou quot;Et si on refaisait l'API de Flickr ?quot;
  27. 27. Flickr GET http://api.flickr.com/services/rest/ ?method=flickr.photos.getRecent&extras=geo,tags GET http://api.flickr.com/services/rest/ ?method=flickr.photos.getInfo&photo_id=12345 POST http://api.flickr.com/services/rest/ ?method=flickr.photos.addTags POST http://api.flickr.com/services/rest/ ?method=flickr.photos.delete GET http://api.flickr.com/services/rest/ ?method=flickr.photos.comments.getList&photo_id=12345 POST http://api.flickr.com/services/rest/ ?method=flickr.photos.comments.add POST http://api.flickr.com/services/rest/ ?method=flickr.photos.comments.edit
  28. 28. Flickr v.2.0 1. Définir les ressources
  29. 29. Flickr v.2.0 Utilisateurs  Photos  Tags  Commentaires 
  30. 30. Flickr v.2.0 2. Nommer les ressources par des URIs
  31. 31. Flickr v.2.0 http://api.flickr.com/users/fred http://api.flickr.com/users/fred/photos/recent http://api.flickr.com/users/fred/photos/12345 http://api.flickr.com/users/fred/photos/12345/tags http://api.flickr.com/users/fred/photos/12345/comments
  32. 32. Flickr v.2.0 3. Exposer certaines méthodes de l'interface uniforme
  33. 33. Flickr v.2.0 Méthode URI GET /users POST /users GET /users/fred PUT /users/fred DELETE /users/fred Méthode URI GET /users/fred/photos GET /users/fred/photos/recent POST /users/fred/photos GET /users/fred/photos/12345 PUT /users/fred/photos/12345 DELETE /users/fred/photos/12345
  34. 34. Flickr v.2.0 Méthode URI GET /users/fred/photos/12345/tags POST /users/fred/photos/12345/tags PUT /users/fred/photos/12345/tags/toto DELETE /users/fred/photos/12345/tags/toto Méthode URI GET /users/fred/photos/12345/comments POST /users/fred/photos/12345/comments PUT /users/fred/photos/12345/comments/23 DELETE /users/fred/photos/12345/comments/23
  35. 35. Flickr v.2.0 4. Définir les représentations
  36. 36. Flickr v.2.0 En entrée (POST, PUT) :  XML  URL-encoded  En sortie :  XML  JSON  PNG|JPG|GIF 
  37. 37. Flickr <photos page=quot;2quot; pages=quot;89quot; perpage=quot;10quot; total=quot;881quot;> <photo id=quot;2636quot; owner=quot;47058503995@N01quot; secret=quot;a123456quot; server=quot;2quot; title=quot;test_04quot; ispublic=quot;1quot; isfriend=quot;0quot; isfamily=quot;0quot; /> <photo id=quot;2635quot; owner=quot;47058503995@N01quot; secret=quot;b123456quot; server=quot;2quot; title=quot;test_03quot; ispublic=quot;0quot; isfriend=quot;1quot; isfamily=quot;1quot; /> <photo id=quot;2633quot; owner=quot;47058503995@N01quot; secret=quot;c123456quot; server=quot;2quot; title=quot;test_01quot; ispublic=quot;1quot; isfriend=quot;0quot; isfamily=quot;0quot; /> <photo id=quot;2610quot; owner=quot;12037949754@N01quot; secret=quot;d123456quot; server=quot;2quot; title=quot;00_tallquot; ispublic=quot;1quot; isfriend=quot;0quot; isfamily=quot;0quot; /> </photos>
  38. 38. Flickr v.2.0 5. Définir les réponses HTTP : Déroulement normal/anormal
  39. 39. Flickr v.2.0 GET : 200 OK | 404 Not found  POST : 201 Created | 409 Conflict  PUT, DELETE : 200 0K  Rien ne va plus : 500 Internal server error ;) 
  40. 40. Flickr v.2.0 6. Implémenter le tout ? Il reste encore un problème...
  41. 41. HATEOS Hypermedia as the engine of application state quot;A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) and set of standardized media types that are appropriate for the intended audience (i.e., expected to be understood by any client that might use the API). From that point on, all application state transitions must be driven by client selection of server-provided choices that are present in the received representations or implied by the user’s manipulation of those representations.quot; Roy Fielding
  42. 42. Flickr Exemple : construction des URIs vers les photos Une documentation est nécessaire pour naviguer dans l'API !!! http://farm{farm-id}.static.flickr.com/{server-id}/{id}_{secret}.jpg http://farm{farm-id}.static.flickr.com/{server-id}/{id}_{secret}_[mstb].jpg http://farm{farm-id}.static.flickr.com/{server-id}/{id}_{o-secret}_o.(jpg|gif|png)
  43. 43. HATEOS Comment résoudre ce problème ?
  44. 44. Connexité Ou relier les choses entre elles : <order href=quot;http://example.com/orders/1234quot;> <client href=quot;http://example.com/clients/1234quot; /> <product href=quot;http://example.com/clients/1234quot; amount=quot;2quot; /> … </order>
  45. 45. Connexité L'exemple d'ATOM : <?xml version=quot;1.0quot;?> <entry xmlns=quot;http://www.w3.org/2005/Atomquot;> <title>Atom-Powered Blog</title> <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id> <updated>2008-12-13T18:30:02Z</updated> <author> <name>John Doe</name> </author> <content>Some text.</content> <link rel=quot;editquot; href=quot;http://example.com/edit/first-post.atomquot; /> <link rel=quot;alternatequot; type=quot;text/htmlquot; href=quot;http://example.com/first- post.htmlquot;/> </entry>
  46. 46. URI Templates Proposé à l'IETF par Joe Grégorio : http://www.google.com/search?{-join|&|q,num} http://www.google.com/notebook/feeds/{userID} /{prefix|/notebooks/|notebookID}{-opt|/-/|categories}{-listjoin|/| categories}?{-join|&|updated-min,updated-max,alt,start- index,max-results,entryID,orderby}
  47. 47. WADL <resources base=quot;http://service.example.com/myservices/quot;> <resource path=quot;searchquot;> <method name=quot;GETquot; id=quot;searchquot;> <request> <param name=quot;queryquot; type=quot;xsd:stringquot; style=quot;queryquot; required=quot;truequot;/> </request> <response> <representation mediaType=quot;application/xmlquot; element=quot;yn:ResultSetquot;/> <fault status=quot;400quot; mediaType=quot;application/xmlquot; element=quot;ya:Errorquot;/> </response> </method> </resource> </resources>
  48. 48. Authentification
  49. 49. Authentification HTTP Basic  Mot de passe en clair (base64)  À n'utiliser qu'en HTTPS  HTTP Digest  Nécessite un module Apache rarement activé  WSSE Username Token  Utilisé pour Atom  Algorithme SOAP ;) 
  50. 50. WSSE Username Token Serveur : HTTP/1.1 401 Unauthorized WWW-Authenticate: WSSE realm=quot;fooquot;, profile=quot;UsernameTokenquot; Client : GET /posts/recent HTTP/1.1 Host: example.com Content-Type: application/atom+xml Authorization: WSSE profile=quot;UsernameTokenquot; X-WSSE: UsernameToken Username=quot;fredquot;, PasswordDigest=quot;quR/EWLAV4xLf9Zqyw4pDmfV9OY=quot;, Nonce=quot;d36e316282959a9ed4c89851497a717fquot;, Created=quot;2003-12-15T14:43:07Zquot;
  51. 51. WSSE Username Token <?php $nonce = md5(uniqid(time())); $date = date(DATE_ATOM); $pwd = 'pasecure'; $digest_pwd = base64_encode(sha1($nonce.$date.$pwd));
  52. 52. WSSE Username Token Simple à implémenter  Rien à installer (sauf peut-être pecl_http...)  N'envoie pas les mots de passe en clair  Empêche les quot;replay attacksquot;  Facilement implémentable côté client Ajax 
  53. 53. Des exemples ?
  54. 54. Exemples
  55. 55. PHP et REST
  56. 56. PHP et REST Nombreux outils XML  json_encode, json_decode  Extension curl pour consommer les services  pecl_http peut aider (en-têtes)  Un gotcha : pas de $_PUT !  $params = array(); parse_str(file_get_contents('php://input'), $params);
  57. 57. RESTful frameworks ? Tonic  Konstrukt  Recess  WSO2 
  58. 58. CakePHP // app/config/routes.php Router::mapResources('posts'); Router::parseExtensions(); // app/controllers/posts_controller.php class PostsController extends AppController { var $components = array('RequestHandler'); function index() { $posts = $this->Posts->find('all'); $this->set(compact('posts')); } function view($id) { ... } function edit($id) { GET /posts PC::index() ... } GET /posts/123 PC::view(123) function delete($id) { POST /posts PC::add() ... } PUT /posts/123 PC::edit(123) } POST /posts/123 PC::edit(123) // app/views/posts/xml/index.ctp DELETE /posts/123 PC::delete(123) <posts> <?php echo $xml->serialize($posts); ?> </posts>
  59. 59. Symfony De grands progrès en 1.2  quot;Routes as first-class objectsquot;  SfRequestRoute permet de préciser les  méthodes HTTP et les représentations disponibles : article:   url:          /article/:id   class:        sfRequestRoute   requirements:     sf_method: get     sf_format: (?:xml|json|yaml)
  60. 60. Zend Framework Zend_Rest_Server, un mauvais choix : seuls GET et POST sont supportés  (REST-RPC) conçu pour retourner du XML, pas d'autre type  de représentation possible problablement déprécié en 2.0, à ne pas utiliser  pour de nouveaux projets
  61. 61. Zend Framework Une autre approche : Profiter de l'extensibilité des composants MVC  Zend_Controller_Request_Http supporte les  méthodes PUT, DELETE, HEAD, OPTIONS Utiliser le helper d'action ContextSwitch  Proposition de Luke Crouch :  Zend_Controller_Router_Route_Rest http://framework.zend.com/wiki/display/ZFPROP/Zend_Controller_Router_R oute_Rest+-+Luke+Crouch
  62. 62. Epilogue Soyez sceptiques  Apprenez en plus sur REST  Des problèmes restent à résoudre  Retournez à la nature... du web ! 

×