Qual è lo schema migliore per aggiungere un elemento esistente a una raccolta nell'API REST?

18

Sto progettando un'API REST pragmatica e sono un po 'bloccato sul modo migliore per aggiungere entità esistenti a una raccolta. Il mio modello di dominio include un progetto che ha una raccolta di siti. Questa è una rigida relazione molti-a-molti e non ho bisogno di creare un'entità che modella esplicitamente la relazione (cioè ProjectSite).

La mia API consentirà ai consumatori di aggiungere un sito esistente a un progetto. Dove mi sto bloccando è che gli unici dati di cui ho veramente bisogno sono ProjectId e SiteId. La mia idea iniziale era:

1. POST myapi/projects/{projectId}/sites/{siteId}

Ma ho pensato anche a

2. POST myapi/projects/{projectId}/sites

con un'entità Sito inviata come contenuto JSON.

L'opzione 1 è semplice e funziona, ma non è del tutto corretta e ho altre relazioni che non possono seguire questo modello, quindi aggiunge incoerenza alla mia API.

L'opzione 2 si sente meglio ma porta a due preoccupazioni:

  • Devo creare un sito o generare un'eccezione se viene pubblicato un nuovo sito (SiteId = 0)?
  • Poiché ho bisogno solo di ProjectId e SiteId per creare la relazione, il sito potrebbe essere pubblicato con dati errati o mancanti per altre proprietà.

Una terza opzione consiste nel fornire un semplice endpoint unicamente per la creazione e l'eliminazione della relazione. Questo endpoint si aspetta un payload JSON contenente solo ProjectId e SiteId.

Che ne pensi?

    
posta Jamie Ide 12.03.2014 - 15:58
fonte

2 risposte

13

POST è il verbo "append" e anche il verbo "processing". PUT è il verbo "crea / aggiorna" (per identificatori conosciuti), e sembra quasi la scelta giusta qui, perché è noto l'intero URI di destinazione. projectId e siteId esistono già, quindi non è necessario "POST a una raccolta" per produrre un nuovo ID.

Il problema con PUT è che richiede che il corpo sia la rappresentazione della risorsa che stai trasmettendo. Ma l'intento qui è di aggiungere alla risorsa di raccolta "progetto / siti", piuttosto che aggiornare la risorsa del sito.

Cosa succede se qualcuno mette una rappresentazione JSON completa di un sito esistente? Dovresti aggiornare la raccolta e aggiornare l'oggetto? Potresti sostenerlo, ma sembra che non sia l'intento. Come hai detto,

the only data I really need are ProjectId and SiteId

Piuttosto, proverei a inviare il siteId alla raccolta, e fare affidamento sulla natura "append" e "process" di POST:

POST myapi/projects/{projectId}/sites

{'id': '...' }

Dato che stai modificando i siti raccolta risorse e non la risorsa del sito, questo è l'URI che desideri. POST può sapere "aggiungere / elaborare" e aggiungere l'elemento con quell'ID alla raccolta siti del progetto.

Questo lascia comunque la porta aperta alla creazione di nuovi siti per il progetto, arricchendo il JSON e omettendo l'id. "No id" == "crea da zero". Ma se l'URI della raccolta ottiene un ID e nient'altro, è abbastanza chiaro che cosa deve accadere.

Domanda interessante. :)

    
risposta data 13.03.2014 - 07:05
fonte
4

Usiamo il metodo Patch per cose come questa. Quello che vuoi fare è modificare un progetto esistente per aggiungervi un sito.

Quindi qualcosa del genere funzionerebbe

PATCH myapi/projects/{id} 

con l'entità del sito (i) come JSON / JSONArray nel corpo della richiesta.

In questo modo puoi utilizzare lo stesso URL per modificare diverse parti del Progetto se necessario: il codice nell'implementazione deve essere abbastanza intelligente da gestire questa modifica parziale della risorsa.

    
risposta data 12.03.2014 - 17:21
fonte

Leggi altre domande sui tag