Comment concevoir des points de terminaison API pour publier un objet enfant et pour obtenir tous les enfants de tous les parents?

12

Par exemple, j'ai des entités: Client, Rapport. Le client peut avoir de nombreux rapports et je pense que le point de terminaison d'une seule gestion de rapport devrait être imbriqué comme ceci:

/clients/{client_id}/reports/{report_id}

Comme pour tous les rapports d'un client, le point final est attendu:

/clients/{client_id}/reports

Mais à quoi devrait ressembler un point de terminaison pour obtenir tous les rapports de tous les clients pour garder l'API cohérente et bien conçue.

Mes approches:

  1. (Je l'ai vu dans certaines API Google) utilisez "-" à la place et analysez-le comme "tous":

/clients/-/reports

Cela garde le format du point de terminaison le même, mais semble un peu inhabituel, ne peut trouver aucun rfc qui suggère cette façon.

  1. Créez un point de terminaison distinct uniquement pour tous les rapports:

/reports

Mais pour obtenir les rapports du client, c'est toujours:

/clients/{client_id}/reports

  1. Refactoriser les points de terminaison pour faire du "client" non un parent, mais juste un paramètre de filtre:

/reports?client={client_id} - rapports d'un client

/reports - rapports de tous les clients

En cas d'ajout d'un nouveau point de terminaison pour publier un rapport pour un client spécifique, il peut sembler laid, car il s'agira d'une demande POST avec un paramètre dans l'URL.

Y a-t-il d'autres suggestions d'idées?

Yann
la source
2
Vous pourriez être intéressé question
Laiv

Réponses:

3

Mais à quoi devrait ressembler un point de terminaison pour obtenir tous les rapports de tous les clients pour garder l'API cohérente et bien conçue.

Avant toute chose, n'oubliez pas qu'il n'y a pas de règles d'or pour la modélisation des API RESTful. Tout ce que nous avons, ce sont des bonnes pratiques et des conventions. Cela étant dit, la réponse probable est, comme d'habitude, de choisir celle qui répond le mieux à vos besoins et dans ce cas celle qui exprime le mieux votre modèle.

Vérifiez donc les trois options de l'expressivité.

# 1 La notation "-"

C'est une idée brillante. Il nous permet d'exprimer la condition à laquelle tout reportsappartientclients . Cela réduit la "requête" à un ensemble spécifique de rapports (ceux situés à l'intérieur de la clientsfrontière).

Il garde la notion de hiérarchie (appartenance) tout le temps, donc si elle reportspeut être trouvée à différents endroits, cette notation fait toute la différence. Par exemple:

  • Tous les rapports qui appartiennent aux clients /clients/-/reports
  • Tous les rapports appartenant aux départements /departments/-/reports
  • Tous les rapports qui appartiennent aux employés /employees/-/reports

Cependant, pour récupérer tous les rapports disponibles dans le système, le maintien de la hiérarchie n'offre aucun avantage précieux par rapport à l'option suivante.

# 2 URI différents

Si nous n'avons pas besoin d'exprimer les limites / contextes / hiérarchie au moment de récupérer tous les rapports disponibles , cette approche me semble plus raisonnable.

Le nouvel URI ( /reports) laisse également ouverte la possibilité d'une gestion des rapports . Cependant, nous n'avons pas à lui fournir un support RESTful complet si nous ne le jugeons pas nécessaire. Par exemple, vous l'avez déclaré Make a separate endpoint just for all the reports. C'est bien, vous n'avez qu'à implémenter GETet peut-être quelques filtres pour les requêtes et c'est tout.

Notez que vous pouvez toujours le faire /reports?client={client_id}. Avoir un URI différent pour la même ressource est bien. Certains articles que j'ai lus appelleraient cette robustesse .

# 3 Rétablir la hiérarchie

J'ai l'impression que cette approche ne répond pas à vos attentes. De plus, je pense que cela vous amènera finalement au point de départ.

Conclusions

Notez que # 1 et # 2 ne s'excluent pas mutuellement. Nous pouvons implémenter les deux. Étant donné la situation réelle et selon les locaux du PO, je ne mettrais en œuvre que le n ° 2.


1: c'est équivalent à /clients/-/reportsje suppose

Laiv
la source
0

Les modèles de conception d'API de Google suggèrent d'utiliser «-» dans ce scénario.

GET /clients/-/reports

La source:

https://cloud.google.com/apis/design/design_patterns#list_sub-collections

wfg4
la source
2
Loin de moi l'idée d'être en désaccord avec le tout-puissant Google, mais je pense que je préférerais quelque chose comme /client/{client_id}/report/{report_id}et/clients/report/{report_id}
Robert Harvey
2
@RobertHarvey pourquoi pas seulement /reports?
Laiv
@Laiv: Cela impliquerait tous les rapports. Actualisez votre page; J'ai fait un montage ninja.
Robert Harvey
@RobertHarvey Je veux dire, pourquoi pas 2 points de terminaison différents /clients...et /reports.
Laiv
1
@Laiv: OK, mais cela soulève simplement la question "Quels paramètres dois-je mettre dans le corps de la demande?"
Robert Harvey