Les services de type ressource sont très répandus, ils se cachent parmi nous sous l'appellation RESTful. Mais ils n'étaient pas là les premiers et leurs ancêtres ont 2-3 choses à nous apprendre. Par ailleurs, ils bénéficieront grandement d'un peu plus d'attention que de simplement les coller sur un framwork MVC. J'expliquerai les différentes couches les composants, les différents systèmes de requête/réponse et leur intégration avec ces fameux frameworks MVC que tout le monde adore.
3. Un service web, qu’est-ce?
• Partage des fonctions entre applications
• Permettre à des logiciels fonctionnant sur des environnements
disparates de communiquer
• Dé-couplage ?
• Fonctionnel
• Structurel (de données)
• Temporel
• Positionnel (URI)
Architecture services web de type ressource – Antoine Pouch 3
4. Les différents types
Les classiques
• CORBA
• DCOM
Les modernes
• RPC
• Message
• Ressource
Architecture services web de type ressource – Antoine Pouch 4
5. Les différents types d'API - RPC
• Une URL
• Une signature par méthode
• SOAP/XML/WSDL usuellement
Architecture services web de type ressource – Antoine Pouch 5
6. Les différents types d'API- Message
• Une URL
• Une signature pour toutes une famille de méthodes avec un
paramètre unique qui diffère
• SOAP/XML/WSDL usuellement
Architecture services web de type ressource – Antoine Pouch 6
7. Les différents types d'API- Ressource
• Une URL par ressource, par action
• Signatures proches, faciles à « deviner »
• Pas toutes REST!
Architecture services web de type ressource – Antoine Pouch 7
9. Interaction: Request/Response
• La plus simple
• Couplage temporel fort
• Mauvaise scalability
Architecture services web de type ressource – Antoine Pouch 9
10. Interaction: Request/Acknowledge
• Plus complexe
• Annule le couplage temporel
• Sous-type : Callback
• Complexe
• Sous-type : Poll
• Ne résout pas le problème de scalability, peut uniquement le déporter
Architecture services web de type ressource – Antoine Pouch 10
11. Interaction: Media Type Negotiation
• Extension
• Pas sémantiquement correct
• Header
• Parfait, fournit par spécification HTTP (Accept)
• Généralement pas de négociation, client
• Pattern: Response Handler
• Discovery: HEAD
Architecture services web de type ressource – Antoine Pouch 11
12. Interaction : Service Liés (hypermedia
control/HATEOAS)
• Découverte : OPTIONS
• Suites logiques retournées dans la réponse
• Permet aux clients d'avoir peu d'URI statiques à connaître
• Permet le changement, l'ajout de services, l'auto-documentation
• Mais attention aux clients qui « bookmarkent » !
• Parfois retournés dans le Link header : pas sémantiquement correct !
Et trop unidimensionnel.
Architecture services web de type ressource – Antoine Pouch 12
13. Intéraction : HAL
• Hypertext Application Language
• application/hal+json
Architecture services web de type ressource – Antoine Pouch 13
14. Avant HAL
{
"status": "This is my awesome status update!",
"user": "mwop"
}
Architecture services web de type ressource – Antoine Pouch 14
15. Avec HAL
{
"_links": {
"self": {"href": "http://example.com/api/status/1347"}
},
"id": "1347",
"timestamp": "2013-02-11 23:33:47",
"status": "This is my awesome status update!",
"_embedded": {
"user": {
"_links": {
"self": {"href": "http://example.com/api/user/mwop"}
},
"id": "mwop",
"name": "Matthew Weier O'Phinney",
"url": "http://mwop.net"
}
}
}
Architecture services web de type ressource – Antoine Pouch 15
17. Data Transfer Objects
• Pour éviter l'annotation des Domain Objects (Couplage Structurel Très
Fort, références circulaires)
• POPOs : manipulent types génériques ou autres DTOs
• Créés en entrée par un Request Mapper ou un déserialiseur
• Utilisés en sortie par un Response Mapper ou un sérialiseur
• Le Mapping peut être centralisés et formalisé en fichiers de
configuration
• Introduisent de la lourdeur
Architecture services web de type ressource – Antoine Pouch 17
18. Request Mapper
• Si besoin de plus qu'un simple Deserializer
• Injecté au Service Controller, ou avec une Factory
• Varient selon le client, le format d'entrée, la version
• Créént les DTOs
Architecture services web de type ressource – Antoine Pouch 18
19. Response Mapper
• Si besoin de plus qu'un simple Serializer
• Injecté au Service Controller, ou avec une Factory
• Varient selon le client, le format de sortie, la version
• Manipulent les DTOs
• Utiles par ex. pour une réponse JSON qui sera différente d'un XLS
(données moins agrégées)
• Introduisent de la lourdeur
Architecture services web de type ressource – Antoine Pouch 19
20. Interceptors
• Utilisés en entrée et sortie
• Entrée : Authentification, Autorisation, Caching,
• Sortie : Logging, Error handling
Architecture services web de type ressource – Antoine Pouch 20
21. Styles d'implémentation
• Transaction Script
• Fat fat controller, prévoir du copy-paste
• Datasource Adapter
• Souvent dérivé d'annotation sur Objets issus d'ORM
• Operation Script
• Classes centrales qui fournissent des opérations possibles sur le domaine
• Command Invoker
• Plus rien dans le service. Sauvegardable. Nécessaire pour Request/Ack.
• Workflow Connector
• Comme CI, mais contenu dans un Workflow Engine. Pour suites d'opérations.
Architecture services web de type ressource – Antoine Pouch 21
26. Integration dans les Frameworks
MVC (symfony2, ZF2)
Architecture services web de type ressource – Antoine Pouch 26
27. Generalités
• Décharge de responsabilité : Les méthodes/outils qui suivent sont selon la
communauté du framework la façon la meilleure/plus simple
d'implémenter REST mais vous pouvez toujours les modifier ou les oublier
• Le Routing est extrêmement simplifié
• Les intercepteurs sont intégrés : Events.
• Events génériques inclus : Authentication, Authorization, Logging
• Serializer et Deserializer disponibles
• Create/Update utilisent les Forms sf2 ou ZF2. Les aimez-vous?
• Par défaut, multiples actions dans un seul controlleur. Aimez-vous les
classes de 3000 lignes ?
Architecture services web de type ressource – Antoine Pouch 27
28. symfony2
• FOSRestBundle
• https://github.com/FriendsOfSymfony/FOSRestBundle
• NelmioApiDocBundle
• https://github.com/nelmio/NelmioApiDocBundle
• JMSSerializerBundle
• https://github.com/schmittjoh/JMSSerializerBundle
• L’enfer des configurations et des annotations
Architecture services web de type ressource – Antoine Pouch 28
29. Symfony - Routing
users:
type: rest
resource: AcmeHelloBundleControllerUsersController
class UsersController {
public function optionsUsersAction() {} // "options_users" [OPTIONS] /users
public function getUsersAction() {} // "get_users" [GET] /users
public function getUserAction($slug) {} // "get_user" [GET] /users/{slug}
public function editUserCommentAction($slug, $id) {} // "edit_user_comment" [GET]
/users/{slug}/comments/{id}/edit
}
Architecture services web de type ressource – Antoine Pouch 29
30. Symfony – Routing not simplified
/**
* List all notes.
*
* @ApiDoc(
* resource = true,
* statusCodes = {
* 200 = "Returned when successful"
* }
* )
*
* @AnnotationsQueryParam(name="offset", requirements="d+", nullable=true, description="Offset from which to start listing notes.")
* @AnnotationsQueryParam(name="limit", requirements="d+", default="5", description="How many notes to return.")
*
* @AnnotationsView()
*
* @param Request $request the request object
* @param ParamFetcherInterface $paramFetcher param fetcher service
*
* @return array
*/
public function getNotesAction(Request $request, ParamFetcherInterface $paramFetcher)
Architecture services web de type ressource – Antoine Pouch 30
31. Symfony – Préparation - Events partout
• Interceptors (Auth, Logging, etc.)
• FormatListener pour la négociation de format
• JMSSerializer très puissant (supporte les versions par ex.), peut être
étendu en Request Mapper. Ne pas utiliser les annotations Doctrine !
• BodyConverters qui servent de Request Mappers sinon (permet
injection de params dans controlleurs). Mais si on les utilise, il faut
faire le routing à la main. Et la validation par regexp ou classes
spécifiées dans les annotations, vraiment ?
Architecture services web de type ressource – Antoine Pouch 31
32. Symfony – Exécution
• Create et Update via des Forms
• Peuvent être affichés en HTML (Backoffice rapide)
• Mais il faut les aimer
Architecture services web de type ressource – Antoine Pouch 32
33. Symfony - rendering
• Gestion des exceptions dans controlleur à part, avec configuration des
exceptions vers statuts et messages. Lourd.
• ViewHandler (= Response Handler) : Couche de plus entre le
controlleur et la vue. Rend la vue agnostique au format (xml, json,
twig). Peut être étendu en ResponseMapper. Utilise JSMSerializer.
• Ne supporte pas les DTOs, mais extensible. Mais soyez prêts à
beaucoup de changements si vous sortez des sentiers battus.
Architecture services web de type ressource – Antoine Pouch 33
34. ZF2
• Support intégré! Mais faible. Ou qui laisse beaucoup de liberté.
• Apigility pour aller plus loin.
Architecture services web de type ressource – Antoine Pouch 34
35. ZF2 - Préparation
• Interceptors pour auth, logging, etc.
• Un controlleur par entité obligatoirement (encore ces controlleurs de
3000 lignes)
• AbstractRestfulController fournit un mapping très basique (mais
efficace) de verbes HTTP vers méthodes.
• Pas de Request Mappers, en fait, même pas de déserializer. Ne
parlons pas des DTOs.
Architecture services web de type ressource – Antoine Pouch 35
36. ZF2 – Exécution
• Create et Update via des Forms
• Peuvent être affichés en HTML (Backoffice rapide)
• Mais il faut les aimer
• Moins forcé de les utiliser que dans sf2
Architecture services web de type ressource – Antoine Pouch 36
37. ZF2 - rendering
• JsonModel. Peut être étendu en ResponseMapper, gère les DTOs avec
propriétés publiques.
• Et c’est tout.
Architecture services web de type ressource – Antoine Pouch 37
38. ZF2 - Apigility
• https://apigility.org
• Création d’API par formulaire ! REST ou SOAP.
• Génération de backoffice
• Auto-documentation
• Génération de sous-classes de contrôleurs vides à remplir pour
particulariser.
Architecture services web de type ressource – Antoine Pouch 38
39. Symfony et ZF2 – Manques
• DTOs
• Command Invokers. Aucune possibilité de faire du Request/Ack.
Même pas de Ack automatique.
• Trop d'accent mis sur couplage avec ORM
Architecture services web de type ressource – Antoine Pouch 39
40. Références
• Service Design Patterns par Robert Daigneau, 2012, Addison Wesley
• Richardson Maturity Level :
martinfowler.com/articles/richardsonMaturityModel.html
• Hypertext Application Language : stateless.co/hal_specification.html
• Integrating into ZF : www.slideshare.net/mikestowe/building-a-rest-api-
with-zend-framework-2
• Integrating into symphony : welcometothebundle.com/symfony2-
rest-api-the-best-2013-way/
Architecture services web de type ressource – Antoine Pouch 40