REST può restituire il contenuto dopo il POST?


88

Sto usando RESTlet e ho creato una risorsa. Gestisco il POST sovrascrivendo il acceptRepresentationmetodo.

Il client dovrebbe inviarmi alcuni dati, quindi li memorizzo su DB, impostare la risposta su 201 (SUCCESS_CREATED) e devo restituire alcuni dati al client, ma il tipo di ritorno acceptRepresentationè void.

Nel mio caso, devo restituire un identificatore in modo che il client possa accedere a quella risorsa.

Ad esempio, se avessi una risorsa con URL /resourcee il client invia una richiesta POST, aggiungo una nuova riga nel DB e il suo indirizzo dovrebbe essere /resource/{id}. Devo inviare {id}.

Sto facendo qualcosa di sbagliato? I principi REST consentono di restituire qualcosa dopo il POST? Se sì, come posso farlo e in caso negativo qual è il modo per gestire questa situazione?


Vedi la risposta di Thom per come impostare il corpo della risposta dall'interno di acceptRepresentation ().
Avi Flax

Risposte:


96

REST dice solo che dovresti conformarti all'interfaccia uniforme. In altre parole, dice che dovresti fare ciò che POST dovrebbe fare secondo le specifiche HTTP . Ecco la citazione da quella specifica che è rilevante,

Se una risorsa è stata creata sul server di origine, la risposta DOVREBBE essere 201 (Created) e contenere un'entità che descrive lo stato della richiesta e fa riferimento alla nuova risorsa, e un'intestazione Location (vedere la sezione 14.30).

Come puoi vedere da questo, hai due posti dove puoi indicare al cliente dove risiede la risorsa appena creata. L'intestazione Location dovrebbe avere un URL che punta alla nuova risorsa e puoi anche restituire un'entità con i dettagli.

Non sono sicuro di quale sia la differenza tra l'override di acceptRepresentation () e l'override di post (), ma questo esempio mostra come restituire una risposta da un POST.


2
@ del-boy: vedi la risposta di Thom su come impostare il corpo della risposta dall'interno di acceptRepresentation ().
Avi Flax

1
La citazione delle specifiche HTTP non proibisce una risposta, se guardi nella Sezione 6 è chiaro su questo: è consentito: Request and Response messages MAY transfer an entity if not otherwise restricted by the request method or response status code. An entity consists of entity-header fields and an entity-body, although some responses will only include the entity-headers.
MikeF

@ MikeF Non era mia intenzione dedurre che un corpo di risposta non fosse consentito. La parte delle specifiche che ho citato dice specificamente "e contiene un'entità". Avrei dovuto essere più chiaro nel mio testo.
Darrel Miller

16

Rinuncerei a inviare qualsiasi cosa nel corpo della risposta. Basta impostare Location: sull'URL (completo) della risorsa appena creata.

La tua descrizione suggerisce che questa è esattamente la semantica che tu:

  1. POSTARE una cosa per crearla
  2. Rispondi con abbastanza per sapere due cose:
    1. Che la creazione è avvenuta (il 201)
    2. Dove trovare la nuova cosa (l'intestazione Posizione)

Qualsiasi altra cosa è superflua.


Non che Wikipedia sia sempre una buona fonte, ma che afferma anche "[...] Per fornire informazioni sulla posizione di una risorsa appena creata. In questa circostanza, l'intestazione Location dovrebbe essere inviata con un codice di stato HTTP 201 o 202 . "
Arjan

1
Il POST può eseguire la logica che crea una o più risorse. Il risultato dell'elaborazione potrebbe essere richiesto dal cliente. Quindi, restituirlo nella risposta evita la necessità di effettuare una o più chiamate GET all'API. I dati creati / modificati dal metodo POST potrebbero non essere (e spesso non lo sono) superflui per il cliente.
Paulo Merson

10

Due domande diverse:

Il pattern dell'applicazione REST supporta la restituzione dei dati in un POST?

Non penso che REST lo neghi esplicitamente, ma il trattamento preferito è spiegato nella risposta di Darrel.

Il framework RESTlet consente la restituzione dei dati in un POST?

Sì, anche se restituisce void, in una classe che estende Resource, hai pieno accesso all'oggetto oggetto Response tramite il metodo getResponse (). Quindi puoi chiamare getResponse (). SetEntity () con tutti i dati che desideri.


6

Emetterlo in qualsiasi formato richiesto. Potrebbe essere:

<success>
    <id>5483</id>
</success>

O:

{ "type": "success", "id": 5483 }

Dipende da cosa fai di solito. Se non si aspettano i dati, dovrebbero semplicemente ignorarli, ma qualsiasi cliente che desideri gestirli correttamente dovrebbe essere in grado di farlo.


Ok, ho due formati possibili (html e xml). So come gestire il tipo di formato richiesto, ma non so come aggiungere dati alla risposta. rappresenta il metodo restituisce la rappresentazione, quindi restituisco solo quello che voglio, ma acceptRepresentation è un metodo void, quindi non posso restituire alcun dato ...
del-boy

1

Se rispondi 201 Created con un corpo di entità, piuttosto che un reindirizzamento Location, allora è una buona idea includere un'intestazione Content-Location che punta alla risorsa che viene rappresentata nella risposta.

Ciò eviterà una potenziale confusione, in cui un cliente potrebbe (giustificatamente) presumere che l'entità di risposta rappresenti effettivamente un nuovo stato del "creatore" e non la risorsa creata.

> POST /collection
> ..new item..

< 201 Created
< Location: /collection/1354
< Content-Location: /collection/1354
< <div class="item">This is the new item that was created</div>

3
Penso che Content-Location abbia uno scopo diverso. La specifica HTTP dice che Content-Location non è definita per POST e PUT. L'intestazione Location viene utilizzata con 201-Create. La restituzione di una posizione non esegue automaticamente un reindirizzamento, è necessario un codice di risposta 3XX per questo.
Darrel Miller

1
L'intestazione della posizione viene utilizzata (in una risposta 201) per indicare dove si trova la risorsa creata; non è rilevante per il corpo dell'entità della risposta che accompagna. Il punto era che: se si desidera includere la risorsa creata nella risposta 201 stessa (anziché dirigere / reindirizzare il client a un altro URI), un'intestazione della posizione del contenuto sarebbe una buona idea. Questo probabilmente sta "piegando un po 'le regole", ma è più efficiente che richiedere un altro ciclo di richiesta / risposta per ottenere lo stato della nuova risorsa per il client.
Mike

Ha senso per me. Non ho mai usato l'intestazione Content-Location prima d'ora.
Darrel Miller

se il client è un essere umano con un browser, non ha senso restituire 201 con l'intestazione Location. L'utente non saprà cosa farne. se il cliente è un robot, può essere programmato per sapere come gestirlo, come un GET di follow-up sulla posizione.
irreputabile

3
@irreputable: credo che REST fosse pensato per la progettazione di API, dove A non sta per un agente utente che cerca un po 'di HTML da visualizzare.
Hermes
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.