Modo RESTful di richiesta di risorse generate dal server

6

Voglio che un server sia un produttore di compiti che il cliente deve elaborare ed essere rinviato. Qual è l' method dell'HP corretto nell'approccio RESTful per creare e restituire una nuova risorsa?

Sembra sciocco, ma il modo naturale sembra essere GET /task/ , o più verosimilmente GET /new_task/ . Un'attività viene creata e restituita. Ma questo non sembra giusto. Anche POST non sembra naturale. Il cliente non vuole POST di dati. Lo richiede piuttosto.

Use Case:

Ad esempio. Voglio produrre alcuni compiti da svolgere, diciamo alcuni esercizi. Devono essere elaborati e rispediti. La mia idea è di fornire uri con il metodo GET , per ottenere un'attività. Salva sul server che è stata ottenuta un'attività e salva il timeout per questo. Tecnicamente un'attività può essere recuperata molte volte e GET non la modifica in alcun modo, quindi sembra addirittura idempotente. Se un utente POST s risponde, il server risponderà in modo diverso in base al timestamp salvato. Tuttavia, mi sembra che allo stesso tempo creo anche una nuova risorsa, ovvero (user; task; time-stamp) che semanticamente è "dato-compiti". Qual è la vista in questo caso?

Le mie idee:

  1. GET /resource/ e crea / genera e rimanda indietro. Diciamo:

    {
      "self": "http://super-service/resource/<new_id>",
      "data" : "Ipsum Lorem... Your random stuff."
    }
    

È davvero idempotente? Il "sé" non è in realtà un mirror di GET questo sembra controintuitivo per una richiesta GET .

  1. Un altro modo che posso immaginare è qualcosa come POST una richiesta per la risorsa da creare. E.g: POST /create_task/ che non penso sia una soluzione adeguata perché ha un verbo in URI. Ma si può risolvere il problema diciamo via: POST /task_request/ , quindi ora sto postando una richiesta per un compito, ma mi sembra di manipolare la semantica per renderla carina. Ancora non sono sicuro se corretto. I dati nella risposta potrebbero essere completamente non correlati a POST . Va bene? I nuovi dati possono essere una risposta (ad esempio dal caso 1).

Vorrei chiedere la motivazione dietro l'approccio proposto. Quindi posso capire e imparare il processo di pensiero.

    
posta luk32 31.03.2016 - 03:39
fonte

3 risposte

2

Se il server crea attività da solo, senza un trigger da parte dell'utente, e l'utente recupera tali attività in un secondo momento, sarebbe opportuno recuperare l'elenco completo delle attività con

GET /tasks/

o, per ottenere le attività dopo l'ultima verifica

GET /tasks/?created_after=20160331

Se, d'altra parte, il server crea una nuova attività in risposta a un'azione da parte dell'utente, quindi

POST /tasks/

sarebbe il modo giusto per creare una nuova attività. Non c'è nulla in REST che dice che il contenuto dell'attività appena creata deve provenire dall'utente. È infatti molto comune che almeno alcuni campi siano compilati dal server, a seconda di chi ha le conoscenze per riempire quei campi.
Nel tuo caso, la maggior parte o anche tutti i campi di un'attività verranno compilati dal server.

Se le attività sono correlate a un utente, puoi codificarlo anche nell'URL. Ad esempio

GET /users/{user_id}/tasks

per ottenere tutte le attività per un utente o

GET /users/{user_id}/tasks/{task_id}

per ottenere una singola attività specificata e

POST /users/{user_id}/tasks

per creare un'attività per un utente.

    
risposta data 31.03.2016 - 09:13
fonte
0

La tua esitazione è fondata. L'ho trovato un po 'difficile da seguire, ma credo che tu stia dicendo che stai considerando un endpoint tale che ogni volta che lo richiedi restituisca un nuovo risultato "fresco".

Hai ragione sul fatto che l'utilizzo di GET qui sarebbe male fino al punto di rompere le cose. Hai anche avuto un buon istinto con POST /task_request/ . Qualcosa di simile è ciò che vuoi fare. I client devono POST per alcuni URI come /task_request/ e dovrebbe restituire (in caso di successo) 201 Creato con l'intestazione Location impostata su un URI, ad esempio example.com/task/1234 . Può facoltativamente restituire il contenuto immediatamente, ma potrebbe essere meglio recuperarlo dalla posizione restituita (con un GET). Il fatto che la richiesta POST non possa avere un corpo non è un problema. Una volta che l'utente risponde all'esercizio, può essere inserito in un URI, preferibilmente uno che è stato specificato con i metadati per l'attività. (Quello che in realtà è l'URI non ha molta importanza in quel caso.)

I vantaggi di questo approccio sono che non stiamo abusando di un verbo HTTP in un modo che potrebbe interagire male con il caching. Non vuoi che qualcuno richieda una nuova attività per ottenere una versione memorizzata nella cache di una versione precedente, probabilmente quella che hanno appena terminato. Anche se non lo memorizzi nella cache, i livelli intermedi come le reti di distribuzione dei contenuti potrebbero decidere di memorizzarlo nella cache per te. Allo stesso modo, il cliente e gli intermediari possono decidere di rieseguire una richiesta GET per una serie di motivi che possono causare problemi o almeno creare rifiuti sul server. Un POST non verrà memorizzato nella cache e non verrà (ciecamente) rieseguito. Nel frattempo, la risorsa creata può essere recuperata e memorizzata nella cache quanto desiderato.

In generale, l'utilizzo di GET indica a clienti e intermediari che la richiesta può essere memorizzata nella cache e rieseguita. L'uso di PUT / DELETE indica a clienti e intermediari che la richiesta può essere rieseguita.

    
risposta data 31.03.2016 - 09:41
fonte
0

Penso che la risposta di Bart sia degna di nota. Ma, se il tuo componente lato server è nel business di assegnare attività direttamente a determinati client, proporrei una di queste altre opzioni:

GET /client/me
GET /users/me
GET /somethingElseUniqueTo/me

Che restituirebbe una proprietà task o tasks come parte di client oggetto. Possono anche essere stub:

{
  clientId: {id},
  tasks: [
    { taskId: {id} },
    { taskId: {id} }
  ],
  /* other stuff */
}

Di cui ottieni i dettagli completi all'indirizzo:

GET /tasks/{id}

E segna come in corso aggiornando un campo status e POST ing allo stesso URL.

    
risposta data 31.03.2016 - 15:54
fonte

Leggi altre domande sui tag