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.