2014-11-11 13 views
5

ho una semplice API, che funziona così:modo RESTful ad accettare una scelta

  1. Un utente crea una richiesta (POST /requests)
  2. Un altro utente recupera tutte le richieste (GET /requests)
  3. poi aggiunge un'offerta di una richiesta (POST /requests/123/offers)
  4. utente originale può ora vedere tutte le offerte stati fatti per la richiesta (GET /requests/123/offers)

Quello che voglio fare è consentire all'utente iniziale di accettare una richiesta, ma non riesco a capire il modo migliore per farlo RESTfuly.

Devo farlo con il verbo PATCH? Come PATCH /requests/123 e richiede che il corpo della patch contenga un ID offerta valido?

+0

Direi che il POST sarebbe appropriato per accettare una richiesta, potresti usare PUT per creare richieste e offerte. – Shriike

risposta

7

Accettare un'offerta cinque volte dovrebbe avere lo stesso effetto di accettarla una volta. È idempotente. Quindi dovrebbe essere un PUT.

Si potrebbe voler prendere in considerazione la scelta di un nome diverso per le "richieste". Quando faccio GET /requests/123, richiedo una risposta che è una richiesta? Questo potrebbe essere un po 'di confusione per i clienti.

Inoltre, cercare di evitare di annidare i propri identificativi di risorsa. Questo può creare problemi per te in seguito. Un'offerta non deve essere necessariamente "sotto" la richiesta corrispondente. Cosa succede quando in seguito vuoi avere offerte corrispondenti a più richieste?

Una buona regola è, se si prenderebbe in considerazione "Gizmo" un'entità in un entity-relationship model, dovrebbe essere una radice a livello di URI, come in GET /gizmos/17, non GET /widgets/54/gizmos/17. Un errore comune è quello di dire "Ogni Gizmo ha esattamente un widget correlato, quindi dovrei annidare gli URI Gizmo come estensioni degli URI dei widget."

Di seguito ho un suggerimento su come sarebbero le operazioni. Potresti voler sostituire alcuni dei riferimenti ID con gli URI, ma dipende da te.

POST /requests   ---> 201 Created 
           Location: /requests/123 

GET /requests    ---> 200 OK 
           [ 
            { 
             "requestId": 123, 
             "offersUri": "/offers?requestId=123", 
             ... 
            }, 
            ... 
           ] 

POST /offers    ---> 201 Created 
{        Location: /offers/456 
    "requestId": 123, 
    "amount": 300, 
    ... 
} 

GET /offers?requestId=123 ---> 200 OK 
           [ 
            { 
             "requestId": 123, 
             "amount": 300, 
             ... 
            } 
           ] 

PUT /offers/456/approval ---> 204 No Content 
PUT /offers/456/approval ---> 204 No Content 
PUT /offers/456/approval ---> 204 No Content 
+1

Grazie per aver menzionato gli identificatori di annidamento. Questo è troppo comune per un errore quando le persone sono alle prime armi nell'architettura REST. –

+0

Grazie! La tua risposta sembra la strada da percorrere. L'unica domanda che ho è sulla lista delle offerte. Come andrei a fornire un modo semplice per recuperare tutte le offerte per una richiesta? Dovrebbe esserci un parametro url per il filtraggio in 'GET/offers? Request = 123' o dovrei fornire un parametro per incorporare questi dati nella richiesta' GET/request/123? Embedded = true', che sostituirà offerIds con le offerte effettive ? –

+1

@JanisPeisenieks 'GET/offerte? RequestId = 123' sembra ragionevole per me. Evita il tuo ultimo suggerimento, 'GET/request/123? Embedded = true'. Una risorsa dovrebbe collegarsi alle sue risorse correlate - non incorporarle. In effetti, potresti anche considerare di rendere la risorsa di richiesta simile a questa, invece di quanto suggerito sopra: '{" requestId ": 123," offersUri ":"/offers? RequestId = 123 "}' –

1

A seconda della natura dell'Accettazione.

Se Acceptance è un semplice attributo di un'offerta, POST l'offerta con l'Acceptance impostato su True.

Se l'accettazione è più complessa e quindi una risorsa a sé stante, metterei un'accettazione nell'offerta (PUT /requests/123/offers/acceptance).

Se esiste una cosa come un rifiuto, o una richiesta di chiarimento dell'offerta, potrei considerare la risorsa rilevante come una risposta, non un'accettazione, e PUT che (put /requests/123/offers/response).

+0

Non degno di un downvote, ma sembra che si inseriscano molti dati di azione nell'URI che violano la separazione del principio di identificazione e trasformazione di REST. –

+0

Non riesco a vedere come trattare una risposta come un documento o risorsa separato costituisce un'azione di codifica nell'URI.Le opzioni che ho offerto (nel caso in cui una risposta sia modellata come un oggetto complesso) sono Accettazione e Risposta, non * Accetta * e * Risponde * (che risentirebbe di un'azione confusa con l'oggetto). In effetti, in un sistema RFQ formale è del tutto possibile che la risposta debba essere modellata separatamente. –

+0

Immagino di vedere REST come una combinazione di risorse e rappresentazioni e il tuo modello sembra utilizzare solo risorse. Se lo stato di un'offerta (accettato/rifiutato) non è una rappresentazione, non so cosa sia. –

Problemi correlati