Comment décrire un changement architectural qui enfreint intentionnellement les normes REST?


37

Je propose des modifications à un projet de logiciel très mal architecturé qui souffre d'une multitude de problèmes. À un niveau élevé, le projet utilise Angular sur le système frontal et utilise diverses API REST. ce qui est génial (je ne vois pas la nécessité de changer notre technologie ou nos outils). Le problème est que la base de code est disproportionnellement plus grande dans l'interface utilisateur que les API côté serveur. Une grande partie de la logique métier réside dans l'interface utilisateur, les API REST étant de simples interfaces de base de données CRUD avec la couche d'interface utilisateur.

Par exemple, un POST au client créera un enregistrement client, tandis qu'un PUT modifiera ce client. Pas beaucoup plus, et pas beaucoup moins. Cependant, notre logique métier est plus exigeante que cela. Le processus général de création d'un client fait bien plus que d'insérer 1 enregistrement de base de données. Il fournira des données dans d'autres tables nécessaires, effectuera certaines validations et calculs, etc. Je préférerais effectuer un seul appel POST / PUT qui encapsule tout ce comportement, allégeant ainsi la charge du client consommateur.

Donc, mon point de vue est que cette orchestration globale devrait vivre sur le serveur (où nous avons le contrôle total, les journaux, etc.), pas l'interface utilisateur, mais un contre-argument est que cette approche ne serait plus RESTful. Par conséquent, je ne sais pas comment décrire au mieux cette approche lorsque ma recommandation est de continuer avec la pile de technologies existante, mais de mettre en œuvre des changements fondamentaux dans les emplacements auxquels le code appartient.


44
Confiner votre API à CRUD demande simplement de la rendre "RESTful" est un compromis médiocre.
Robert Harvey

38
@EsbenSkovPedersen: meilleur ami pour toujours?
Robert Harvey

5
Au lieu de vous demander si votre service est conforme à REST (presque aucun ne le fait), je m'inquiéterais davantage de la conformité à la spécification HTTP . La plupart des api avec lesquelles j'ai travaillé ne respectent pas non plus les spécifications, mais c'est un objectif plus réalisable et plus intéressant.
aaaaaa

7
@aaaaaa, la raison pour laquelle presque aucun service n'est conforme à REST est que personne ne peut décider de ce qu'est REST. Le seul point d'accord que j'ai trouvé est "tout le monde fait le mal".
Mark

16
- "Comment décrire un changement architectural qui enfreint intentionnellement les normes REST?" - DÉSASSURANCE . ( Désolé pour un commentaire non professionnel, il était plus fort que moi. )
luk32

Réponses:


49

Je ne sais pas comment décrire au mieux cette approche lorsque ma recommandation est de continuer avec la pile de technologies existante, mais de mettre en œuvre des changements fondamentaux dans les emplacements auxquels le code appartient.

Service oriented architecture.

Vous proposez de redéfinir votre système afin que vos règles métier et vos données se trouvent au même endroit. C'est effectivement la définition d'un service ; voir le discours d'Udi Dahan sur la recherche des limites de service .

Encadré: comme l'a noté Eric, cela n'a rien à voir avec "REST". Il n'y a absolument aucune raison pour que vous ne puissiez pas placer une API REST (c'est-à-dire une API qui réponde aux contraintes du style architectural REST ) devant votre service. Mais cela peut ne pas être évident pour les personnes qui comprennent REST signifie un mappage des opérations de base de données aux méthodes HTTP.

Il peut être intéressant d'investir ou non dans la modification de la compréhension de REST par votre public.


32
Cela ne vaut pas non plus la peine d’investir dans REST. Si vous lisez la thèse de Roy Fielding (ou Comment j'ai expliqué REST à ma femme ), le véritable objectif de REST est de fournir une représentation canonique des ressources sur Internet, afin que des machines disparates sur Internet disposent d'un moyen standard de les manipuler. . Une application privée peut même ne pas avoir besoin de cette capacité.
Robert Harvey

29

REST n'est pas CRUD. Ce "contre-argument" est basé sur une compréhension fondamentalement erronée de ce qu'est REST. Je n'ai rien vu dans votre message qui indique que votre modification rendrait votre API plus ou moins RESTful.


6
Eh bien, non, ce n'est pas une correspondance parfaite avec CRUD, mais il marche et parle et chante très bien comme CRUD, du moins de la façon dont la plupart des gens l’interprètent.
Robert Harvey

11
@ RobertHarvey Je pense que c'est le problème (mal) comprendre.
JimmyJames

4
@ JimmyJames: C'est un malentendu omniprésent. Il existe une forte volonté de rendre les choses "reposantes" quand la plupart des gens ne comprennent même pas quels sont les avantages ou comment ces avantages s’appliqueraient à eux.
Robert Harvey

4
@ RobertHarvey Je pense que vous dites que si REST est mal choisi, alors REST ne devrait pas être un objectif. OK mais la façon dont je vois les choses, appeler cela 'not REST', c'est de la connerie et je suis un grand partisan de l'appeler de la connerie à la connerie. Les mots ont besoin d'un sens commun pour être utiles.
JimmyJames

5
@RobertHarvey Accordée, mais cela ne se produira pas tant qu'il y aura suffisamment de personnes qui voudront corriger ces utilisations abusives du terme. Je ne suis pas prêt à jeter l'éponge.
JimmyJames

24

Une autre chose à garder à l’esprit est la suivante: Ne pas valider votre côté serveur de règles d’entreprise, signifie que vous faites implicitement confiance à tout ce qui arrive, par exemple une demande POST, est valide.

Cela signifie par exemple que, si votre application angulaire peut vérifier si le client a une tranche d’âge valide et s’assure que les utilisateurs légitimes obtiennent le retour correct, toute personne connaissant l’URL de votre API peut faire une requête POST contenant des valeurs non légitimes qui ne plus être validé.

Ma suggestion serait donc de déplacer vos règles commerciales vers l'API, de la laisser valider l'entrée et de renvoyer les erreurs appropriées (ou peut-être simplement des codes indiquant ce qui s'est mal passé) dans le corps de la réponse. Ces codes peuvent ensuite être utilisés par votre application front-end pour indiquer ce qui a mal tourné.


5
C’est de loin la réponse la plus utile: l’API est la surface d’attaque, pas l’entrée du client. Toute demande d'API peut être usurpée. Ainsi, tout ce qui peut être fait avec l'API pure est ce qu'un script malin et malfaisant peut faire. Le logiciel client peut être utilisé pour offrir une meilleure expérience utilisateur, mais c'est le serveur qui doit appliquer les règles.
cmaster

10

Pour ajouter aux autres bonnes réponses ici:

Votre interface, REST ou autre, ne doit pas être contrainte en fonction d'hypothèses sur les détails de la mise en œuvre. Ceci est totalement antithétique à la notion de services en tant que couche d'abstraction.

L'un des principaux avantages de l'utilisation des services est que les détails de la mise en œuvre peuvent être modifiés sans que les clients aient à faire quoi que ce soit. D'après ce que vous avez décrit, il semble qu'il n'y ait pas de véritable couche d'abstraction. Les détails de la mise en œuvre ont été exposés via HTTP. Rien dans REST ne dit que cela soit nécessaire, utile ou souhaitable. En fait, je pense que je pourrais affirmer que certaines parties de la définition de REST signifient qu'il s'agit en fait d'une implémentation non-RESTful.

Ce que vous suggérez, c'est comment une couche de service appropriée devrait être conçue. Si quelqu'un vous dit que vous ne pouvez pas le faire parce que ce n'est pas reposant, c'est dommage. Vous pouvez être assuré que quelqu'un qui vous dit que ne sait rien à propos de REST.

Sur la base de votre question, vous avez une ressource appelée client. Tout ce qui est nécessaire pour créer une ressource client valide peut et doit être traité dans une POSTressource de base client (ou alternativement / éventuellement dans un PUT vers une ressource client spécifique, si elle n'existe pas.) REST ne dit rien sur le nombre enregistrements de base de données que vous devez créer pour un appel donné. Comme l'a commenté Colin Young, il n'est pas du tout nécessaire de créer une base de données, la manière dont les services sont implémentés du point de vue de REST est totalement hors de propos.


3
REST ne dit rien sur les enregistrements de base de données, encore moins sur leur nombre. Je pouvais créer un service REST qui contrôlait une vanne d’eau et exposait une vanne d’eau, une réserve d’eau et des ressources au niveau du réservoir. Vous pourriez soutenir que les objets physiques eux-mêmes sont une "base de données", mais que cela étire un peu les choses.
Colin Young

@ColinYoung Oui, merci de nous aider à clarifier.
JimmyJames

3

Il y a quelques bonnes réponses ici, mais je ne suis pas sûr qu'elles vous aideront à convaincre vos collègues. Comme beaucoup l'ont fait remarquer, ce que vous suggérez n'est pas un changement de conception RESTful, et je pense que c'est essentiel pour les intégrer à votre proposition.

REST ne consiste pas à s'assurer que votre API ne permet que le stockage et la récupération de données. Il s’agit plutôt de modéliser des actions en tant que ressources. Votre API doit permettre de prendre des mesures (c'est une interface de programmation d' application , après tout). La question est de savoir comment modéliser ces actions.

Plutôt que de proposer un terme, les exemples sont probablement la meilleure façon de l'expliquer à vos collègues . De cette façon, vous pouvez montrer comment ils le font maintenant, quels problèmes cela cause, une solution qui résout le problème et comment il reste toujours RESTful.

Regardons votre objet client.

Problème:

L’UI POST un client, mais les tables suivantes n’ont pas encore été mises à jour. Que se passe-t-il si l'un des appels suivants échoue en raison d'une erreur dans votre code d'interface utilisateur (ou d'un plug-in de navigateur qui se comporte mal, etc.)? Vos données sont maintenant dans un état incohérent. Il pourrait même s'agir d'un état qui casse d'autres parties de votre API ou de votre interface utilisateur, sans parler de son invalidité. Comment récupérez-vous? Vous devez tester tous les états possibles pour vous assurer que cela ne casse pas quelque chose, mais il serait difficile de savoir ce qui est possible.

Solution:

Créez un point de terminaison API pour créer des clients. Vous savez que vous ne voulez pas avoir de point de terminaison "/ customer / create" ou même "/ create-customer", car create est un verbe qui violerait REST. Alors, nommez-le. "/ customer-creation" pourrait fonctionner. Désormais, lorsque vous POSTerez votre objet CustomerCreation, il enverra tous les champs nécessaires à la création complète d'un client. Le noeud final s'assurera que les données sont complètes et valides (en renvoyant 400 ou quelque chose si la validation échoue), et peuvent persister dans une seule transaction de base de données, par exemple.

Si vous avez également besoin d'un point d'extrémité pour obtenir des objets GET / client, c'est très bien. Vous pouvez avoir les deux. L'astuce consiste à créer des terminaux qui répondent aux besoins des consommateurs.

Avantages:

  1. Vous garantissez que vous ne vous retrouverez pas dans un mauvais état
  2. Il est en fait plus facile pour les développeurs d’interface utilisateur s’ils ne doivent pas "connaître" la commande des demandes, les problèmes de validation, etc.
  3. Ce n'est pas aussi bavard qu'une API, ce qui réduit la latence des requêtes réseau
  4. Il est plus facile de tester et de conceptualiser des scénarios (les données manquantes ou mal formées dans l'interface utilisateur ne sont pas réparties entre les demandes, certaines pouvant échouer).
  5. Il permet une meilleure encapsulation de la logique métier
  6. Facilite généralement la sécurité (car les utilisateurs peuvent modifier la logique métier et d'orchestration de l'interface utilisateur)
  7. Réduira probablement la duplication logique (plus probable que vous ayez plus de 2 utilisateurs d'API que plus de 2 API donnant accès aux mêmes données)
  8. Toujours 100% RESTful

Désavantages:

  1. C'est potentiellement plus de travail pour le développeur backend (mais peut-être pas à long terme)

Il peut être difficile pour les gens de comprendre ce paradigme et ses atouts s’ils ne l’ont pas essayé. J'espère que vous pourrez les aider à voir en utilisant un exemple de votre propre code.

Mon expérience personnelle est qu'une fois que les développeurs de mon équipe ont commencé à mettre en œuvre cette stratégie, ils en ont presque immédiatement constaté les avantages.

Une étude plus approfondie:

Cet article de thinkworks m'a vraiment aidé à concevoir des actions de modélisation en tant qu'objets à l'aide d'exemples pratiques: https://www.thoughtworks.com/insights/blog/rest-api-design-resource-modeling

Je suggérerais également de lire CQRS et Event Sourcing, car ils sont précisément concernés par ce type de problème (par exemple, divorcer votre API de la logique de persistance réelle). Je ne sais pas à quel point vos collègues seraient disposés à lire ce genre de chose, mais cela peut vous éclairer davantage et vous aider à leur expliquer.


" parce que créer est un verbe et violerait REST " - Absolument correct. En d'autres termes, il s'agirait de la 47.258.346e approche pour exécuter " RPC over REST ". Ce qui est quelque chose que j'attribuerais au moins "non naturel", car il utilise mal et décrit de manière erronée les approches RESTful (ils ont leurs cas d'utilisation, mais RPC n'en fait pas partie) et tend également à être inefficace.
jeudi
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.