En comparant la structure REST [api] avec un modèle OO, je vois ces similitudes:
Tous les deux:
Sont orientés données
- REST = Ressources
- OO = Objets
Fonctionnement surround autour des données
- REST = entourer les VERBES (Get, Post, ...) autour des ressources
- OO = promouvoir le fonctionnement autour des objets par encapsulation
Cependant, les bonnes pratiques OO ne se tiennent pas toujours sur les API REST lorsque vous essayez d'appliquer le motif de façade par exemple: dans REST, vous n'avez pas 1 contrôleur pour gérer toutes les demandes ET vous ne cachez pas la complexité des objets internes.
Au contraire, REST favorise la publication des ressources de toutes les relations avec une ressource et autres sous au moins deux formes:
via les relations de hiérarchie des ressources (Un contact de l'id 43 est composé d'une adresse 453):
/api/contacts/43/addresses/453
via des liens dans une réponse json REST:
>> GET /api/contacts/43 << HTTP Response { id: 43, ... addresses: [{ id: 453, ... }], links: [{ favoriteAddress: { id: 453 } }] }
Pour en revenir à OO, le motif de conception de façade respecte un Low Coupling
entre un objetA et son « client objectB » et High Cohesion
pour cet objetA et sa composition d'objet interne ( objectC , objectD ). Avec l' objectA interface, cela permet à un développeur d'impact limite objectB des ObjectA changements internes (en ObjectC et objectD ), tant que le objectA api (opérations) sont toujours respectées.
Dans REST, les données (ressource), les relations (liens) et le comportement (verbes) sont éclatés en différents éléments et disponibles sur le Web.
En jouant avec REST, j'ai toujours un impact sur les changements de code entre mon client et mon serveur: parce que j'ai High Coupling
entre mes Backbone.js
demandes et Low Cohesion
entre les ressources.
Je n'ai jamais compris comment laisser mon Backbone.js javascript application
accord avec la découverte de " ressources et fonctionnalités REST " promu par les liens REST. Je comprends que le WWW est destiné à être servi par plusieurs serveurs et que les éléments OO ont dû être explosés pour être servis par de nombreux hôtes, mais pour un scénario simple comme "enregistrer" une page montrant un contact avec ses adresses, Je me retrouve avec:
GET /api/contacts/43?embed=(addresses) [save button pressed] PUT /api/contacts/43 PUT /api/contacts/43/addresses/453
ce qui m'a amené à déplacer l'action d'économie de responsabilité transactionnelle atomique sur les applications des navigateurs (puisque deux ressources peuvent être adressées séparément).
Dans cet esprit, si je ne peux pas simplifier mon développement (modèles de conception de façade non applicables), et si j'apporte plus de complexité à mon client (gestion de la sauvegarde atomique transactionnelle), quel est l'avantage d'être RESTful?
la source
PUT /api/contacts/43
cascade des mises à jour des objets internes? J'ai eu beaucoup d'API conçues comme ça (l'URL principale lit / crée / met à jour le "tout" et les sous-URL mettent à jour les morceaux). Assurez-vous simplement de ne pas mettre à jour l'adresse lorsqu'aucune modification n'est requise (pour des raisons de performances).Réponses:
Je pense que les objets ne sont construits correctement que sur des comportements cohérents et non sur des données. Je vais provoquer et dire que les données sont presque hors de propos dans le monde orienté objet. En fait, il est possible et parfois courant d'avoir des objets qui ne renvoient jamais de données, par exemple des "puits de journal", ou des objets qui ne renvoient jamais les données qui leur sont transmises, par exemple s'ils calculent des propriétés statistiques.
Ne confondons pas les PODS (qui ne sont guère plus que des structures) et les objets réels qui ont des comportements (comme la
Contacts
classe dans votre exemple) 1 .Les PODS sont essentiellement une commodité utilisée pour parler aux référentiels et aux objets métier. Ils permettent au code d'être sûr de type. Ni plus ni moins. Les objets métier, en revanche, fournissent des comportements concrets , comme valider vos données, les stocker ou les utiliser pour effectuer un calcul.
Ainsi, les comportements sont ce que nous utilisons pour mesurer la "cohésion" 2 , et il est assez facile de voir que dans votre exemple d'objet, il y a une certaine cohésion, même si vous ne montrez que des méthodes pour manipuler des contacts de haut niveau et aucune méthode pour manipuler des adresses.
Concernant REST, vous pouvez voir les services REST comme des référentiels de données. La grande différence avec la conception orientée objet est qu'il n'y a (presque) qu'un seul choix de conception: vous avez quatre méthodes de base (plus si vous comptez
HEAD
, par exemple) et bien sûr, vous avez beaucoup de latitude avec les URI afin que vous puissiez faire des astuces des trucs comme passer de nombreux identifiants et récupérer une structure plus grande. Ne confondez pas les données qu'ils transmettent avec les opérations qu'ils effectuent. La cohésion et le couplage concernent le code et non les données .De toute évidence, les services REST ont une cohésion élevée (chaque façon d'interagir avec une ressource est au même endroit) et un faible couplage (chaque référentiel de ressources ne nécessite pas la connaissance des autres).
Le fait fondamental reste cependant que REST est essentiellement un modèle de référentiel unique pour vos données. Cela a des conséquences, car il s'agit d'un paradigme construit autour d'une accessibilité facile sur un support lent, où le coût de la «conversation» est élevé: les clients souhaitent généralement effectuer le moins d'opérations possible, mais en même temps, ils ne reçoivent que les données dont ils ont besoin. . Cela détermine la profondeur d'une arborescence de données que vous allez renvoyer.
Dans une conception orientée objet (correcte), toute application non triviale effectuera des opérations beaucoup plus complexes, par exemple par la composition. Vous pourriez avoir des méthodes pour effectuer des opérations plus spécialisées avec les données - ce qui doit être le cas, car bien que REST soit un protocole API, OOD est utilisé pour créer des applications complètes destinées aux utilisateurs! C'est pourquoi la mesure de la cohésion et du couplage est fondamentale dans OOD, mais presque insignifiante dans REST.
Il devrait être évident maintenant que l'analyse de la conception de données avec des concepts OO n'est pas un moyen fiable de le mesurer: c'est comme comparer des pommes et des oranges!
En fait, il s'avère que les avantages d'être RESTful sont (principalement) ceux décrits ci-dessus: c'est un bon modèle pour les API simples sur un support lent. Il est très cacheable et partageable. Il a un contrôle fin sur le bavardage, etc.
J'espère que cela répond à votre question (assez multiforme) :-)
1 Ce problème fait partie d'un ensemble plus large de problèmes connus sous le nom de non -concordance d'impédance objet-relationnelle . Les partisans des ORM sont généralement dans le camp qui explore les similitudes entre l'analyse des données et l'analyse du comportement, mais les ORM ont récemment fait l'objet de critiques car ils ne semblent pas vraiment résoudre le problème d'impédance et sont considérés comme des abstractions qui fuient .
2 http://en.wikipedia.org/wiki/Cohesion_(computer_science)
la source
La réponse à "où est l'avantage d'être RESTful?" est analysé et expliqué en détail ici: http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
Cependant, la confusion dans cette question est qu'il ne s'agit pas des caractéristiques de REST et de la manière de les gérer, mais en supposant que la conception des URL que vous avez créées pour votre système d'exemple a quelque chose à voir avec RESTful. Après tout, REST indique qu'il existe des choses appelées ressources et un identifiant doit être fourni pour celles qui doivent être référencées, mais cela ne signifie pas que, par exemple, les entités de votre modèle ER doivent avoir une correspondance 1-1 avec les URL que vous avez créées (ni que les URL doivent coder la cardinalité des relations ER dans le modèle).
Dans le cas des contacts et des adresses, vous auriez pu définir une ressource qui représente conjointement ces informations comme une seule unité, même si vous souhaitez extraire et enregistrer ces informations dans, disons, différentes tables de bases de données relationnelles, chaque fois qu'elles sont PUT ou POSTed .
la source
C'est parce que les façades sont un «kludge»; vous devriez jeter un oeil à «abstraction api» et «chaînage api». L'API est une combinaison de deux ensembles de fonctionnalités: les E / S et la gestion des ressources. Localement, les E / S sont correctes mais dans une architecture distribuée (c.-à-d. Proxy, porte api, file d'attente de messages, etc.) les E / S sont partagées et ainsi les données et les fonctionnalités deviennent dupliquées et enchevêtrées. Cela conduit à une préoccupation architecturale transversale. Cela affecte tous les API existants.
La seule façon de résoudre ce problème est d'abstraire la fonctionnalité d'E / S de l'API à un gestionnaire pré / post (comme un gestionnaire HandlerIntercepter dans Spring / Grails ou un filtre dans Rails) afin que la fonctionnalité puisse être utilisée comme une monade et partagée entre des instances et des externes. outillage. Les données de demande / réponse doivent également être externalisées dans un objet afin de pouvoir être partagées et rechargées également.
http://www.slideshare.net/bobdobbes/api-abstraction-api-chaining
la source
Si vous comprenez votre service REST, ou en général tout type d'API, tout comme une interface supplémentaire exposée aux clients afin qu'ils puissent programmer votre ou vos contrôleurs à travers lui, cela devient soudainement facile. Le service n'est rien de plus qu'une couche supplémentaire au-dessus de votre logique biz.
En d'autres termes, vous n'avez pas à diviser la logique biz entre plusieurs contrôleurs, comme vous l'avez fait dans votre image ci-dessus, et plus important encore, vous ne devriez pas. Les structures de données utilisées pour échanger des données n'ont pas besoin de correspondre aux structures de données que vous utilisez en interne, elles peuvent être très différentes.
C'est l'état de l'art, et largement accepté, que c'est une mauvaise idée de mettre une logique biz dans le code de l'interface utilisateur. Mais chaque interface utilisateur n'est qu'une sorte d'interface (le I dans l'interface utilisateur) pour contrôler la logique biz derrière. Par conséquent, il semble évident que c'est également une mauvaise idée de mettre une logique biz dans la couche de service REST, ou toute autre couche d'API.
Sur le plan conceptuel, il n'y a pas beaucoup de différence entre l'interface utilisateur et l'API de service.
la source