Progettazione dell'itinerario API per relazioni di entità opzionali

2

Supponiamo di avere entità di progetto e attività per un elenco di cose da fare. Se è necessario che le attività si trovino in un progetto, le rotte delle attività probabilmente avranno questo aspetto:

GET  /projects/{projectId}/tasks   returns all tasks for the specified project
POST /projects/{projectId}/tasks   creates a new task in the specified project

Ma non è altrettanto chiaro (per me) cosa fare se un'attività può essere indipendente (non parte di un Progetto). Vedo un paio di opzioni:

Hai due percorsi separati: uno per la creazione di un'attività legata al progetto e l'altra per un'attività indipendente

POST /projects/{projectId}/tasks   creates a new task in the specified project
POST /tasks                        creates a new free-standing task

Questo sembra ... ok. Ma non mi piace l'idea di dover selezionare condizionatamente una route API in base alle attività.

Avere un unico percorso e specificare un projectId opzionale nel payload o nei parametri di query

POST /tasks                        creates a new task
GET  /tasks?projectId={projectId}  gets all tasks within the specified project
GET  /tasks/{taskId}               gets the specified task, regardless of whether it's in a project

Questo sembra migliore. Mi piace l'uniformità di avere un unico endpoint che gestisca tutto questo. Con questo approccio, però, ci sono due modi per ottenere un'attività con Id:

GET  /tasks/{taskId}
GET  /tasks?id=taskId

Ho la sensazione che la prima opzione sia un po 'più standard, ma la seconda si allinea meglio con altri tipi di filtri che si potrebbero fare (per progetto, per nome, ecc.). È meglio supportare entrambi o forzare l'uno o l'altro?

Alcuni di questi approcci sono generalmente accettati? Ci sono altre opzioni che non ho considerato?

    
posta jacobsowles 30.09.2016 - 17:11
fonte

1 risposta

2

Tutti hanno difficoltà a creare la struttura URL delle API che stanno costruendo. Questo perché REST non dice come dovrebbero apparire gli URL. In REST non ti interessa nemmeno l'aspetto degli URL perché dovrebbero essere scoperti da una rappresentazione precedente (aka HATEOAS ).

REST o nessun REST, HATEOAS o nessun HATEOAS, penso che concentrarsi sulla struttura dell'URL della tua API sia importante perché ti aiuta a rendere la tua API più pulita, più facile da capire e da usare. Ma poiché diverse persone capiscono REST in modi diversi, diverse persone hanno anche opinioni diverse su come dovrebbero apparire gli URL.

La mia opinione personale :) è che questa versione è la migliore dal 3:

POST /tasks                        creates a new task
GET  /tasks?projectId={projectId}  gets all tasks within the specified project
GET  /tasks/{taskId} 

Il GET /tasks?id=taskId I lo includerebbe nello stesso bucket di GET /tasks?projectId={projectId} e non lo disabiliterà o costringerà le persone a utilizzare l'URL. Un parametro di query indica una sorta di ricerca o filtro. Qualcosa che può restituire zero, uno o più risultati. Solo perché id è speciale, non significa che debba essere escluso e sostituito con /tasks/{taskId} . Puoi mantenere entrambi e nella rappresentazione del risultato puoi anche avere un link con rel=self per puntare a /tasks/{taskId} .

Successivamente, penso che una risorsa dovrebbe avere un URI e /tasks/{taskId} è così, quindi di nuovo tenerlo. Inoltre, normalmente ti aspetteresti che chiamare /tasks?id=taskId con un ID errato restituisca un set di risultati vuoto, mentre /tasks/{taskId} restituirà un errore 404.

E infine, penso che questa versione sia più flessibile delle altre e avrà un impatto minore sulla tua API quando devi aggiungere elementi ad essa.

Solo i miei 2 centesimi dalla mia comprensione di REST.

    
risposta data 01.10.2016 - 14:47
fonte

Leggi altre domande sui tag