2 votes

Développement de l'API Rest pour un projet hiérarchique complexe

Nous avons une solution BPM complexe. Nous souhaitons maintenant exposer la structure sous la forme d'un ensemble d'API de repos.

Nous avons une application, dans l'application nous avons des flux de travail, le flux de travail peut avoir des actions, l'action a des champs et les champs peuvent avoir des règles.

Ainsi, la première série d'API pour les champs ou les règles a été réalisée comme suit

[Obtenir] apps/1/workflows/1/actions/1/fields/4/rules

[Poster]

apps/1/workflows/1/actions/1/fields/3/rules

mais ce n'est pas très joli, cela peut devenir plus complexe, habituellement ce que j'ai lu c'est qu'il faut garder l'URI aussi simple que possible, il ne faut pas aller aussi loin.

Quelle devrait être l'uri préférée pour les éléments susmentionnés ?

Faut-il faire des champs et des règles des ressources séparées ? ou comment faire ? si on en fait des ressources séparées, comment obtenir le champ spécifique ? cela ne nécessitera-t-il pas beaucoup de paramètres, ce qui n'est pas une bonne approche ?

édité à nouveau

Ce que je voulais confirmer, c'est que si l'utilisation des URI profonds que j'ai mentionnée ci-dessus est une bonne norme (que certains pensent ne pas être une très bonne approche), comme vous l'avez mentionné, il s'agit plutôt d'un choix.

Et si je ne choisissais pas de faire des URI longs et que je m'en tenais à la version 1 au moins.

dans l'exemple d'URI ci-dessus, je dois donner l'identifiant de l'application, l'identifiant du flux de travail, l'identifiant de l'action et enfin l'identifiant du champ pour accéder au champ requis. il en sera ainsi tant que je n'aurai pas une sorte de hachage pour identifier cet URI spécifique.

apps/1/workflows/1/actions/1/fields/3/rules

devient

/55667788

Que se passe-t-il si je veux que les URI soient lisibles tout en étant petits ? Par exemple Fields/ renvoie tous les champs de l'application 1, du flux de travail 1, de l'action 1, mais comment fournir tous ces identifiants sans encombrer mon URI ? en le limitant à deux niveaux ? est-ce possible ou est-ce que je fais fausse route ?

8voto

AlexanderJohannesen Points 1665

Il y a beaucoup à dire sur ce sujet, mais je pense qu'il s'agit en particulier des modèles d'URI. Je pense que nous devons utiliser de meilleurs exemples. Si vous voulez que l'exemple d'URI soit (comme vous le dites dans votre question) ;

apps/1/workflows/1/actions/1/fields/4/rules

Je dirais alors que non, vous introduisez dans l'URI une sémantique qui n'est pas nécessaire, à savoir /workflows/ /actions/ /fields/ /rules/. Vous devriez indiquer un modèle d'URI pour cela, et je proposerais quelque chose comme ceci ;

{application}/{workflow}/{action}/{field}/{rule}

En principe, nous pouvons traduire un URI tel que celui-ci ;

/yalla/4356/open_portfolio

Into ;

application = 'yalla'
workflow = '4356'
action = 'open_portfolio'
field = ''
rule = ''

Il suffit de voir quelle méthode HTTP a été utilisée et d'appliquer des classes d'action en fonction de cela. Votre kilométrage variera.

Cependant, à ce stade, je me méfie un peu des {action} parce qu'en REST, nous nous efforçons de travailler avec une interface uniforme, mais je ne sais pas à quel type d'action vous faites référence. Il me semble qu'il s'agit d'un mode de pensée RPC plus traditionnel, dont j'essaierais de m'affranchir. Par exemple, si vous avez une structure RPC plus traditionnelle comme celle-ci ;

/yalla/4356/create_new_portfolio

vous brisez la sécurité garantie d'une opération GET (comme l'erreur classique d'utiliser /delete_user comme URI d'action et d'avoir ensuite un spider qui crawle votre site avec GET ...). A la place, je ferais ceci ;

/yalla/4356/portfolio

Pour cette ressource, j'utiliserai GET pour visualiser, PUT pour mettre à jour, POST pour créer et DELETE pour, eh bien, supprimer. En ce sens, la balise {action} du modèle d'URI devient un peu confuse. Que voulez-vous que l'API couvre ?

La première règle pour créer de bons URI est de créer des URI qui correspondent aux ressources de votre système, et non aux opérations et aux actions. Je créerais des ressources pour vos portefeuilles, mais pas les actions ; je les incorporerais dans mes GET/POST/PUT/DELETE.

Par ailleurs, je ne sais pas exactement à quel moment vous avez besoin de la granularité fine des {field} y {rule} mais c'est à vous de décider. Il se peut très bien que vous souhaitiez mettre à jour uniquement la valeur d'un champ, et il n'y a rien de mal à cela. C'est probablement ce que je soutiendrais moi-même, mais je soutiendrais également l'idée d'une remontée dans l'arbre de la structure, afin de pouvoir mettre à jour un champ ;

PUT /yalla/4356/portfolio/name?value=new_value

Mais aussi mettre à jour plusieurs champs ;

PUT /yalla/4356/portfolio?name=new_name&other=something

Et ainsi de suite, de haut en bas de la structure de l'arbre. Il s'agit d'une bonne pratique, car vous donnez à vos développeurs/utilisateurs la possibilité de choisir eux-mêmes comment ils souhaitent travailler avec votre API, ce qui est toujours un avantage.

Mise à jour : D'autres précisions suivent.

Puisque nous parlons de REST et d'une bonne utilisation des URI, rien ne dit que cette ressource ;

/yalla/4356/portfolio

Ne serait-ce pas aussi ;

/454A876D786F

Ces deux identifiants représentent exactement la même chose. Chaque ressource de votre système peut obtenir un identifiant canonique et un URI de ce type, et vous pouvez utiliser différents chemins dans la structure. Même ce champ spécifique ;

/yalla/4356/portfolio/53464/A4576456/title

Il peut également s'agir de l'URI ;

/3498756A8768976FF8976

Par ailleurs, en ce qui concerne la rigueur d'une telle contrainte sur les URI ;

{application}/{workflow}/{action}/{field}/{rule}

Ce n'est qu'un exemple. Voici plusieurs exemples pour vous aider à réfléchir ;

/apps/{application}/{workflow}/{action}/{field}/{rule}
/workflows/{workflow}/{action}/{field}/{rule}
/action/{action}
/id/{id}
/api/{application}/{api}/{version}/{resource}
/property/{property}
/forms/{form}/{field}

L'utilisateur sérieux de RESTafarian ne se préoccupera pas trop de la structure des URI. Il m'arrive souvent de choisir délibérément des identifiants non sémantiques pour des choses / entités / sujets, en utilisant beaucoup de

/3498756A8768976FF8976

pour toutes sortes de choses, y compris les relations entre les choses. L'URI ci-dessus peut être un thème, un sujet, une catégorie, une relation, un rôle, un champ, une action, un formulaire, une application, et ainsi de suite.

Je viens du monde des cartes thématiques (et vous pouvez voir l'une de mes réponses à un discours légèrement différent sur les et son fonctionnement ici ) dans lequel chaque chose dont vous parlez, chaque aspect de votre modèle, est représenté par un sujet, et tous les sujets ont des identifiants. (Je pourrais compliquer les choses et dire qu'il y a trois types d'identifiants : internes, locaux et externes, les deux derniers utilisant des URI, mais je ne suis pas sûr que cela explique grand-chose pour l'instant :) Par exemple, voici un sujet représentant une application ;

PUT /1234 name='My app'&type='application'

Cela signifie que je peux parler de mon application ou y faire référence en utilisant cet identifiant n'importe où dans mon système (vous devriez normalement avoir un cache de types à portée de main). Créez des identifiants uniques pour chaque petite chose, et l'interface RESTful sera beaucoup, beaucoup plus facile à gérer.

Pour ce qui est de votre dernière modification, je ne suis pas sûr de comprendre ce que vous demandez, donc il serait peut-être utile que vous donniez quelques exemples. Mais voulez-vous dire que vous avez fait de certaines de ces sous-propriétés des URI uniques à part entière ? Par exemple ;

/3498756A8768976FF8976

Lorsque vous obtiendrez cette ressource, vous recevrez une réponse. Je ne suis pas sûr de la représentation que vous utilisez, il pourrait s'agir de XML ou de JSON, ou encore de HTML avec des métadonnées intégrées, mais choisissons XML parce que l'exemple sera simple ;

<response>
   <resource id="3498756A8768976FF8976">
      <type id="field" />
      <alias uri="some/other/path" />
      <alias uri="and/another/example" />
      <relationships>
         <parent id="4563456456" type="form" />
         <child id="5784567345" type="rule" />
         <child id="3457698786" type="rule" />
      </relationships>
   </resource>
</response>

Sans en savoir trop sur les exigences de votre système, voici un exemple où le champ (qui est le champ <resource> avec son identifiant), que vous pouvez contourner (et même si je dis que l'identifiant est "type", je parle en réalité d'un autre identifiant ambigu comme 3459867354 qui représentent 'field', et la même chose pour les autres identifiants dont le nom est épelé ; ce ne sont en fait que des identifiants épelés pour faciliter la compréhension :), et il a quelques alias. Vous mettez en correspondance les relations, et nous pouvons voir que ce champ appartient à un certain formulaire, et qu'il a également deux règles attachées. Vous pouvez ensuite interroger n'importe lequel de ces identifiants pour obtenir des métadonnées sur leur appartenance, leur nature et leur fonction.

Vous pouvez bien sûr l'étendre avec de la documentation directement dans la représentation XML, des exemples, des conseils, l'utilisation, des statistiques, et tout ce dont vous pensez que les gens ont besoin.

Mais je dois dire quelques mots sur la création d'un système RESTful. Les clients REST doivent être capables de comprendre les formulaires, donc si je demande une représentation XHTML (par opposition à XML ci-dessus), elle peut contenir des actions disponibles pour moi ;

<html>
    <body>
       <form action="/apps/1234" method="get">
          <input type="submit" title="View 1234 application" />
       </form>
       <form action="/apps/1234/567" method="get">
          <input type="submit" title="View 1234 applications' portfolio" />
       </form>
       <form action="/apps/1234" method="post">
          <input type="text" name="query" title="What to search for?" />
          <input type="submit" title="Search application 1234" />
       </form>
    </body>
</html>

Un client REST peut utiliser et parcourir automatiquement une application complète sur cette base. Il y a des tonnes de choses intéressantes à dire à ce sujet, bien sûr, mais je crains de passer en mode roman, et peut-être de sortir du cadre de votre question, mais il suffit de dire que si vous vous concentrez sur une myriade de formulaires comme interface de votre application, vous n'avez même pas à vous soucier des modèles d'URI ; il suffit de pointer vers une ressource, d'obtenir les formulaires XHTML, et votre API devrait être assez facile à utiliser et complètement auto-documentée.

Deuxième édition :

J'évite toujours les pluriels pour l'accès structuré aux éléments. Par exemple, j'utiliserais ;

/product/345634

pour un produit spécifique, et utilisez simplement ;

/product

pour une liste de tous les produits. Par exemple, pour créer un nouveau produit, vous envoyez un POST à /product, et vous devriez obtenir un /product/{new_id} en retour en cas de succès. Si vous le souhaitez, vous pouvez également faire ;

/product/3456345
/products

Mais je ne le recommande pas. En ce qui concerne les deux niveaux par rapport à n'importe quel type de niveau, je ne pense pas qu'il faille s'inquiéter outre mesure de l'encombrement. Les URI qui se trouvent en profondeur dans le système sont rarement, voire jamais, interprétés par les humains. Est-il vraiment important que vos URI soient longs ?

Ceci étant dit, vous pouvez bien sûr faire ;

/field
/workflow
/action
/application

pour accéder aux collections de ces types. Encore une fois, quelles sont les exigences des personnes pour lesquelles vous créez cette API ? Si c'est uniquement pour des raisons esthétiques, c'est-à-dire pour votre propre opinion sur les URI encombrants, je dirais que vous vous inquiétez de la mauvaise chose. Les URI courts ne rendent pas nécessairement votre API plus facile à comprendre. J'opterais pour la structure complète dont j'ai parlé au début de cette réponse.

Quoi qu'il en soit, j'espère que cela vous aidera un peu, et n'hésitez pas à clarifier et je vous expliquerai plus en détail.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X