Come progettare endpoint API per pubblicare un oggetto figlio e ottenere tutti i figli di tutti i genitori?


12

Ad esempio ho entità: Cliente, Rapporto. Il cliente può avere molti report e penso che l'endpoint per una singola gestione dei report debba essere nidificato in questo modo:

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

Come per tutti i report di un client, è previsto l'enpoint:

/clients/{client_id}/reports

Ma come dovrebbe essere un endpoint per ottenere tutti i report di tutti i clienti per mantenere l'API coerente e ben progettata.

I miei approcci:

  1. (L'ho visto in alcune API di Google) usa "-" invece di esso e analizzalo come "tutto":

/clients/-/reports

Questo mantiene lo stesso formato dell'endpoint, ma sembra un po 'insolito, non riesce a trovare alcun rfc che suggerisce in questo modo.

  1. Crea un endpoint separato solo per tutti i report:

/reports

Ma per ottenere i rapporti del cliente è ancora:

/clients/{client_id}/reports

  1. Endpoint del refactor per rendere "client" non un genitore, ma solo un parametro di filtro:

/reports?client={client_id} - rapporti di un cliente

/reports - rapporti di tutto il cliente

In caso di aggiunta di un nuovo endpoint per la pubblicazione di un report per un client specifico, potrebbe sembrare brutto, poiché sarà una richiesta POST con un parametro nell'URL.

Ci sono altri suggerimenti di idee?


2
Potresti essere interessato domanda
Laiv

Risposte:


3

Ma come dovrebbe essere un endpoint per ottenere tutti i report di tutti i clienti per mantenere l'API coerente e ben progettata.

Prima di ogni altra cosa, ricorda che non esistono regole d'oro per la modellazione delle API RESTful. Tutto ciò che abbiamo sono le migliori pratiche e convenzioni. Detto questo, la risposta probabile è, come sempre, scegliere quella che soddisfa meglio le tue esigenze e in questo caso quella che esprime meglio il tuo modello.

Quindi controlla le tre opzioni dall'espressività.

# 1 La notazione "-"

Questa è un'idea brillante. Ci permette di esprimere la condizione a cui appartengono tuttireportsclients . Sta restringendo la "query" a un set specifico di report (quelli che si trovano all'interno del clientslimite).

Mantiene sempre la nozione di gerarchia (appartenenza), quindi se reportspuò essere trovata in posizioni diverse, questa notazione è molto importante. Per esempio:

  • Tutti i report che appartengono ai clienti /clients/-/reports
  • Tutti i report che appartengono ai dipartimenti /departments/-/reports
  • Tutti i report che appartengono ai dipendenti /employees/-/reports

Tuttavia, per recuperare tutti i report disponibili nel sistema, mantenere la gerarchia non fornisce alcun vantaggio prezioso rispetto all'opzione successiva.

# 2 URI diversi

Se non abbiamo bisogno di esprimere confini / contesti / gerarchia al momento del recupero di tutti i report disponibili , questo approccio mi sembra più ragionevole.

Il nuovo URI ( /reports) lascia inoltre aperta la possibilità di una gestione dei report . Tuttavia, non dobbiamo fornirgli un supporto completo RESTful se non lo riteniamo necessario. Ad esempio, hai dichiarato Make a separate endpoint just for all the reports. Va bene, devi solo implementare GETe forse alcuni filtri per le query e basta.

Nota che puoi ancora farlo /reports?client={client_id}. Avere URI diversi per la stessa risorsa va bene. Alcuni articoli che ho letto chiamerebbero questa robustezza .

# 3 Ripristino della gerarchia

Ho la sensazione che questo approccio non soddisfi le tue aspettative. Inoltre, penso che alla fine ti porterà al punto di partenza.

conclusioni

Si noti che # 1 e # 2 non si escludono a vicenda. Possiamo implementare entrambi. Data la situazione attuale e secondo le premesse del PO, implementerei solo il n. 2.


1: è equivalente a /clients/-/reportssuppongo


0

I modelli di progettazione dell'API di Google suggeriscono di utilizzare "-" in questo scenario.

GET /clients/-/reports

Fonte:

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


2
Che sia per me in disaccordo con l'onnipotente Google, ma penso che preferirei qualcosa del genere /client/{client_id}/report/{report_id}e/clients/report/{report_id}
Robert Harvey,

2
@RobertHarvey perché non solo /reports?
Laiv

@Laiv: ciò implicherebbe tutti i rapporti. Aggiorna la tua pagina; Ho fatto una modifica ninja.
Robert Harvey,

@RobertHarvey Voglio dire, perché non 2 diversi endpoint /clients...e /reports.
Laiv

1
@Laiv: OK, ma questo solleva la domanda "Quali parametri devo inserire nel corpo della richiesta?"
Robert Harvey,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.