Quale azione HTTP e quale valore di ritorno dovrebbero essere usati sull'azione della risorsa

0

Ho una domanda su come dovrei implementare una nuova azione per una risorsa sul mio livello API.

Ho un Timesheet che viene utilizzato dalle persone per farci sapere quante ore hanno lavorato a un lavoro. Questa scheda attività ha uno stato:

  • Apri (ancora in corso)
  • Inviato (sarà esaminato da un dipartimento)
  • Rifiutato (Rifiutato dal dipartimento, l'utente deve correggere la scheda attività e inviare di nuovo)
  • Approvato (approvato dal dipartimento)
  • ... alcuni altri che renderebbero l'intera cosa troppo complicata

La nostra API ATTUALMENTE ha la possibilità di cambiare lo stato, che viene utilizzato dal nostro front-end premendo un pulsante (non è importante, è solo per disegnare un'immagine).

L'endpoint corrente è POST (website)/api/timesheets/{id}/submit dove l'ID è l'id della scheda attività. L'API è abbastanza intelligente da controllare se la scheda attività può essere inviata e in quale stato deve essere modificata (ci sono altri stati che non sono menzionati qui).

Al termine, la nostra API corrente restituisce l'intero modello della scheda attività con lo stato aggiornato e il SubmittedDate .

Ho lavorato alla creazione di una v2 dell'API e ora sto pensando se dovrei ancora usare POST e cosa dovrei restituire dalla chiamata API.

Motivi per cui dubito di POST :

  • Non non crea una nuova risorsa
  • PATCH sarebbe una misura migliore dal momento che stiamo aggiornando una risorsa esistente, ma non stiamo inviando un corpo di richiesta all'API.

Motivi per cui dubito del valore restituito:

  • Restituzione di NOTHING ( 200 OK o 204 No content )
    • POST può (per linee guida) restituire 200 OK o 204 No content se la risorsa non può essere trovata con un URI. La mia risorsa può quindi questo non ha senso?
      • D'altra parte, non stiamo seguendo realmente le linee guida se ho un submit di endpoint poiché lo stato cambia. Ma non voglio nemmeno che il chiamante decida quale dovrebbe essere il nuovo stato poiché l'API lo decide da solo e ha anche alcune azioni di follow-up.
    • Il mio front-end ora dovrebbe fare una chiamata a GET api/timesheets/{id} per ottenere nuovi dati, che è forse un po 'uno spreco?
  • Restituzione del nuovo stato e data di rifiuto
    • Ciò significherebbe che il valore di ritorno della mia API è stato creato appositamente per il nostro front-end e che altri client che utilizzano la mia API non avrebbero bisogno di questo specifico valore di ritorno.
  • Restituzione dell'intero modello
    • Spreco di spazio dal momento che è necessario utilizzare un paio di proprietà.
    • In StackOverflow ho trovato una discussione in cui menzionano che l'utilizzo di POST e un valore di ritorno potrebbero portare a problemi di memorizzazione nella cache. Usiamo una nuova versione di Angular e qualcuno del mio team ha detto che anche se qualcuno lascia la pagina e la inserisce di nuovo, il GET verrà sempre eseguito. Non posso dire se è vero al 100%.

Qualcuno può aiutarmi a decidere quale azione HTTP dovrebbe essere utilizzata (con alcuni motivi per cui) e cosa dovrebbe essere restituito:)?

Grazie mille!

    
posta S. ten Brinke 04.10.2018 - 17:59
fonte

2 risposte

0

La mia raccomandazione sarebbe quella di attenersi al POST, poiché il POST non è solo per la creazione di nuove risorse. Da RFC 7231 : (sottolineatura mia)

The POST method requests that the target resource process the representation enclosed in the request according to the resource's own specific semantics. For example, POST is used for the following functions (among others):

  • Providing a block of data, such as the fields entered into an HTML form, to a data-handling process;

  • Posting a message to a bulletin board, newsgroup, mailing list, blog, or similar group of articles;

  • Creating a new resource that has yet to be identified by the origin server; and

  • Appending data to a resource's existing representation(s).

Per quanto riguarda la risposta:

Probabilmente non vorrete richiedere al client di inviare una richiesta GET solo per aggiornare l'interfaccia utente, a meno che non sia necessario: il tempo di andata e ritorno extra, è un'altra opportunità per potenziali bug da manifestare e in realtà non ha alcun aspetto positivo. I problemi che menzioni che richiederebbero un GET per seguire il POST sono per lo più rilevanti per l'invio di moduli, in cui solitamente si desidera restituire un reindirizzamento per evitare di rompere il pulsante Indietro. Questo significa che vorrete includere tutti gli stati che l'endpoint modifica e il client non può capire da solo nella risposta.

Il POST sull'endpoint modifica potenzialmente due proprietà della risorsa: lo stato e la data inoltrata e l'azione può avere esito positivo o negativo.

Se ha esito positivo:

  • Lo stato sarà sempre Inviato, che il cliente conosce già ricevendo una risposta 20* invece di una risposta 40* .
  • La data inviata sarà l'ora corrente, che il cliente conosce in modo approssimativo. Se la precisione è importante, vorrai includere questo valore nel corpo della risposta. Se non importa se il valore visualizzato sul client è di un paio di secondi, puoi facilmente utilizzare l'ora sul lato client.

Se fallisce:

  • Dovrai inviare abbastanza informazioni per permetterti di presentare la causa del fallimento all'utente (come una doppia presentazione o qualsiasi altro problema). Il messaggio di errore è probabilmente il modo migliore per farlo.
  • Lo stato non verrà modificato, ma potrebbe essere una buona idea inviarlo anche se esiste una sorta di condizione di competizione, in cui si verifica l'errore perché un altro client ha già modificato lo stato.
  • Idem per la data inviata.

Quindi suggerisco di restituire un 204 se la data inoltrata non deve essere precisa e una 200 contenente la data inviata (sia come stringa di data formattata ISO o come oggetto JSON {"SubmittedDate": "ISO formatted date string"} ) se lo fa. In caso di fallimento, probabilmente vorrai avere qualcosa come {"ErrorMessage": "Human readable error message", "Status": "Submitted", "SubmittedDate": "ISO formatted date string"} .

    
risposta data 05.10.2018 - 13:05
fonte
0

The current endpoint is POST (website)/api/timesheets/{id}/submit where the ID is the id of the timesheet. The API is smart enough to check if the timesheet cán be submitted and to which status it should be changed (there are some more statuses that are not mentioned here).

Questo non è RESTful perché inserisce un verbo nel modello di risorsa e quindi si affida a un altro verbo in HTTP per cambiarlo. È in effetti una chiamata a una procedura remota che dice "cambia lo stato di questa scheda attività su inviato".

REST desidera un'interfaccia in cui la richiesta esatta identifica il dato esatto su cui si desidera operare. I servizi Web in generale codificherebbero questo in un URI; in particolare il tuo caso lo renderebbe figlio della risorsa scheda attività: /api/timesheets/{id}/status . Quella singola risorsa può essere manipolata usando qualunque dei verbi HTTP appropriati. GET , PUT e PATCH avrebbero senso qui; POST e DELETE non lo farebbero perché esiste una sola risorsa di stato che deve esistere finché dura la scheda attività. *

È ancora possibile eseguire tutti i controlli durante una modifica per determinare se il nuovo stato è appropriato e restituire uno stato di 200 se tutto è andato a buon fine o un 409 (conflitto) e un messaggio di errore appropriato se il la risorsa era in uno stato in cui non lo è.

* Nota a margine: prestare particolare attenzione al fatto che i requisiti per il proprio sistema di schede attività includano o meno la traccia di controllo sopra menzionata. Ciò avrà un effetto sul tuo modello di risorse, e quegli effetti sono più facili da progettare in precedenza piuttosto che dopo. Invece di avere una singola risorsa di stato, devi POST a /api/timesheets/{timesheet-id}/statuses e recuperare un URI con la posizione di quello nuovo (ad esempio /api/timesheets/{timesheet-id}/statuses/3 ). POST è appropriato qui perché il modello è diverso e tu stai creando nuove risorse. Se stai seguendo le linee guida di HATEOAS, i dati delle risorse della scheda attività includeranno un URI da utilizzare nell'interfaccia utente che mostra dove ottenere lo stato corrente (anche se è già incluso nei dati restituiti) e dove POST new quelli.

    
risposta data 03.01.2019 - 14:25
fonte

Leggi altre domande sui tag