È RESTful di restituire una risorsa diversa dopo il POSTing per ottimizzare il client?

2

Ho una risorsa che accetta i dettagli della transazione come una risorsa secondaria.

GET  /resources/{resourceId}/                         # get resource
POST /resources/{resourceId}/                         # create resource
POST /resources/{resourceId}/resourceTransactions/    # post a resource transaction

Ora, quando si registra una transazione, la risorsa principale può essere cambiata a causa della transazione. Normalmente, vorrei semplicemente restituire la transazione della risorsa registrata, tuttavia vorrei ottimizzare l'esperienza per il client che consuma.

Opzioni

1. Nessuna modifica

Dopo il POST della transazione, la transazione viene restituita e il consumatore dell'API deve OTTENERE la risorsa principale per vedere le modifiche.

2. Restituisci la risorsa principale

Dopo il POST della transazione, la risorsa principale viene restituita al consumatore

3. Restituisce una proiezione della transazione con la risorsa principale incorporata nella proiezione

Dopo il POST della transazione, la transazione viene restituita, e al suo interno è una proiezione della risorsa principale

Mi piacerebbe avere una discussione su altre opzioni, così come i vantaggi e gli svantaggi delle opzioni che ho presentato quando ho utilizzato questo tipo di API.

    
posta Chad 29.04.2017 - 09:53
fonte

2 risposte

2

Il modo in cui hai indicato la domanda e le 3 opzioni possibili, potrebbe indurci a pensare che ci sia solo una possibilità possibile. In questo senso, possiamo anche supporre che il cliente sarà limitato ( accoppiato ) all'opzione scelta.

Tuttavia, c'è una quarta opzione. In pratica, permette ai clienti di scoprire le risorse associate .

I would like to optimize the experience for the consuming client.

Sii Hypermedia .

hateoas

Per brevità tralascio la definizione di HATEOAS e dei suoi principi.

Innanzitutto, dopo aver inserito la nuova risorsa, non restituiamo alcuna rappresentazione. Restituiamo solo uno stato HTTP 201 e informiamo la posizione (URL) della risorsa creata tramite le intestazioni HTTP.

Request:
HTTP/1.1 /resource/X/transactions
....

Response
HTTP/1.1 201 CREATED
Content-Length: xxxx
Content-Type: xxxx​/xxx
Location: http://hostname/resource/x/transactions

Il cliente gestirà la risposta e seguirà il collegamento informato nell'intestazione Posizione con una richiesta GET.

La rappresentazione di transactions può fornire il link alla risorsa genitrice che implementa Collegamenti .

{
    #Transaction collection
   "collection" : [ ...], 
   "links" : [
         { "rel":"self", "href":"http://hostname/resource/x/transactions"},
         { "rel":"resource", "href":"http://hostname/resource/x"}
     ]
}

I vantaggi si basano sul cliente ora hanno diverse scelte. Basta seguire i link. Riduciamo anche l'accoppiamento tra il client e le risposte API perché il client non ha bisogno di sapere come è l'URL.

L'implementazione di HATEOAS potrebbe implicare una profonda revisione del tuo attuale impianto. Se questa opzione è fuori discussione, puoi anche trasferire i link attraverso le intestazioni HTTP. Ad esempio, implementando la propria intestazione: x-links .

L'implementazione di nuove intestazioni è abbastanza comune nel mondo delle API REST. La convenzione afferma che dobbiamo usare il prefisso x - . Consulta questa domanda per ulteriori dettagli

Nota : Se c'è un proxy inverso davanti all'API, sono necessarie alcune modifiche nella configurazione del server Web per consentire il reindirizzamento di queste nuove intestazioni insieme alla richiesta .

Trade-off

Pro e amp; i contro dipendono dalle tue esigenze. Non c'è una soluzione adatta a tutte le dimensioni . Tuttavia, possiamo prevedere i trade-off.

1. No change

Questo approccio limita il modo in cui il cliente scala o cambia. Il motivo è che dobbiamo inserire gli URI con hardcode nel client. In questo modo, introduciamo anche vincoli nel flusso di lavoro. E, naturalmente, accoppiamento.

2. Return the Main Resource

Dal mio punto di vista, questo approccio introduce confusione nella "conversazione" tra il client e l'API.

Se lavoriamo con transazioni potremmo aspettarci di continuare a lavorare con transazioni invece di un altro tipo di risorsa . Ma è principalmente un argomento basato sull'opinione pubblica.

Dal punto di vista del client Implica anche una seconda chiamata all'API per rivedere lo stato attuale delle transazioni dopo il POST.

Due viaggi attraverso il cavo potrebbero sembrare una cosa banale finché non ci troviamo di fronte alle Fallacies of the distributed computing .

Aggiunge anche i vincoli menzionati nell'opzione precedente.

3. Return a Projection of the Transaction with Main Resource embedded in the projection

Potrebbe essere utile se abbiamo restrizioni sulle chiamate API. Ridurre le chiamate all'API può aiutare a ridurre la concorrenza sul lato server.

Questo approccio è il più vicino a quello che ho suggerito. La differenza si basa sul fatto che HATEOAS implica più viaggi di rete.

Lo svantaggio, IMO, è che le rappresentazioni delle risorse diventano un po 'prolisse:

  • risorsa rep. + rappresentante incorporato delle transazioni

  • rep di transazioni. + rappresentante incorporato della risorsa genitore.

Forse, un altro inconveniente viene fornito con la sicurezza implanto. Se ci sono dei vincoli di accesso ai dati, questo introduce un sovraccarico sul lato server. Ma è pura speculazione. Dipende dalle politiche di accesso ai dati che dobbiamo implementare. Se del caso.

4. HATEOAS

Come ho già detto, implica più viaggi attraverso la rete. Più chiamate all'API potrebbero causare più lavoro per il server (dipende dalla tua strategia di caching).

Potrebbe aggiungere qualche difficoltà se c'è una gestione API davanti all'API. Dobbiamo assicurarci che tutti i link restituiti siano disponibili attraverso ogni possibile Gateway / Proxy in mezzo.

D'altra parte, i vantaggi sono: flessibilità in entrambi i lati (client e server), accoppiamento lento, integrazione più semplice.

Finalmente ..

il modo giusto per farlo è il modo migliore per soddisfare i tuoi requisiti funzionali e non funzionali. Sii flessibile, la soluzione potrebbe venire adottando uno o più di essi. O un'altra opzione non presentata qui.

    
risposta data 29.04.2017 - 12:59
fonte
0

Ci sono due opzioni che suggerirei. La prima opzione è POST / PATCH / PUT all'URI della risorsa direttamente per creare o aggiornare la risorsa:

POST/PATCH/PUT /resources/123/ HTTP/1.1

che restituisce direttamente la risorsa, con un collegamento alla risorsa di transazione:

HTTP/1.1 200 OK
Link: </resources/123/transaction/a089a6cc-e64f-40b9-a786-238f2a32cfbb>; rel=transaction

"representation of /resources/123"

Un altro tipo di relazione di link che potresti voler utilizzare potrebbe essere una sorta di rel=permalink per indicare che il link è per una versione specifica della risorsa.

La seconda opzione è di aggiornare indirettamente creando un oggetto transazione:

PUT /resources/123/transaction/a089a6cc-e64f-40b9-a786-238f2a32cfbb HTTP/1.1

che dovrebbe restituire una risposta con un'intestazione Content-Location e una rappresentazione della risorsa aggiornata nel corpo della risposta:

HTTP/1.1 201 Created
Content-Location: /resources/123

"representation of /resources/123"

Come da specifica HTTP, il Content-Location (da non confondere con Location intestazione che sono normalmente usati per i reindirizzamenti) dice al client che il corpo della risposta è la risorsa puntata dall'intestazione Content-Location .

Content-Location:

The Content-Location entity-header field MAY be used to supply the resource Location for the entity enclosed in the message when that entity is accessible from a Location separate from the requested resource’s URI.

    
risposta data 29.04.2017 - 16:56
fonte

Leggi altre domande sui tag