Best practice per chiamate API RESTful con variazioni

2

Come faccio a dare un nome agli endpoint dell'API che servono la stessa entità in modi diversi e aderiscono ancora alle linee guida dell'API RESTful?

Consideriamo che vorrei ottenere un cliente con ALL i suoi dettagli.

  • Espongo solo un endpoint GET all'indirizzo "/customer" .

Ora vorrei verificare se esiste un cliente con un particolare customerId .

  • Che cosa faccio ora? Come nomino l'endpoint?

Possibili soluzioni che ho pensato:

  • Espongo un altro GET endpoint all'indirizzo "/customerNameCheck" . Questo sembra SOAP-y.

  • Mantengo il GET endpoint all'indirizzo "/customer" che accetta un parametro aggiuntivo chiamato type che potrebbe assumere valori type="check"/type="fullCustomer" che determinerà il flusso di eventi sul server e servirà la risposta appropriata.

Entrambe le mie soluzioni sembrano violazioni delle convenzioni generali sui nomi.

Qualche idea?

    
posta Nik Kyriakides 30.06.2016 - 02:25
fonte

4 risposte

3

Un parametro fields può occuparsi di questo.

  • Nell'esempio fornito nella domanda potremmo semplicemente chiedere il campo customerID .

  • Se la risposta fornisce un risultato, esiste.

Da Best practice per la progettazione di un'API RESTful pragmatica di Vinay Sahni

Limiting which fields are returned by the API

The API consumer doesn't always need the full representation of a resource. The ability to select and choose returned fields goes a long way in letting the API consumer minimize network traffic and speed up their own usage of the API.

Use a fields query parameter that takes a comma separated list of fields to include.

Esempio:

GET /customer?fields=id,subject,customer_name,updated_at

    
risposta data 30.06.2016 - 02:37
fonte
4

Come per i commenti, l'URL per ottenere i dettagli di un cliente è /customer/{customerId} .

Per verificare se un ID cliente è già in uso senza recuperare tutti i dettagli, puoi richiedere lo stesso URL utilizzando una richiesta di HEAD .

    
risposta data 30.06.2016 - 06:51
fonte
2

Now I'd like to check if a customer with a particular customerId exists. What do I do now? How do I name the endpoint?

Non lo fai.

REST riguarda il trasferimento di stato. Trasferisci una rappresentazione della risorsa tra il client e il server (REpresentational State Transfer).

Non inserisci la logica specifica del dominio nel tuo schema URL. Una risorsa ha un URL, e questo è. Non si utilizzano URL per avviare le procedure di esecuzione sul server (ad es. Hey server controlla se questo cliente esiste)

Si sta spostando nel territorio RPC, ed è l'opposto di ciò che REST sta cercando di darti.

Why would i want ALL the details of the customer if all I want to know is if he exists or not?

REST non si occupa di "perché" il cliente desidera la risorsa. Non è per lo schema URL da gestire. Il client potrebbe desiderare la risorsa solo per vedere se esiste, potrebbe voler vedere se il cliente proviene da Washington, potrebbe volere che la risorsa veda se il cliente è entrato nell'ultimo anno, ecc. Ecc.

Il tuo schema URL non interessa. Questo è apposta, perché immagina se il tuo schema URL lo abbia fatto. Si finirebbe con lo schema URL che esprime una sorta di linguaggio di query specifico del dominio.

È molto più semplice ottenere la risorsa e lasciare che il cliente capisca quale conclusione tragga dallo stato attuale della risorsa.

Se hai una risorsa che è massiccia e il tuo cliente vorrebbe la rappresentazione di questa risorsa in un altro formato, puoi utilizzare le intestazioni Accept e Content-Type per negoziare tra il client e il server un formato che il client vuole. Ad esempio, potresti avere una rappresentazione del cliente che ha l'intero dato del cliente e uno che ha solo l'ID e il nome. Il client può dire che accetta questo formato breve e il server può restituirlo.

Per essere onesti, a meno che la tua risorsa non sia massiccia, non mi preoccuperei nemmeno di farlo.

    
risposta data 30.06.2016 - 15:56
fonte
1

Normalmente in REST si otterrebbe:

/customers -> List of customers (We include links here in HATEOS so in this JSON you will find link to /customers/123)
/customers/123 -> Full details of customer 123 (you can limit fields if you want)
/customers/9999 -> If this customer does not exist return error 404

Quindi, come vedete, non otterreste mai un collegamento a / customers / 9999 in / customers perché non esiste. Quindi non incontrerai un cliente scomparso molte volte.

Può succedere anche se, ad esempio, se si memorizza nella cache un collegamento al cliente 100 e viene eliminato. In questo caso il client API riceve un errore 404 che è un errore permanente e cancellerà la sua cache in modo che non si verifichi più.

La tua domanda:

How do I name API endpoints that serve the same entity in different ways and still adhere to the RESTful API guidelines?

In generale non lo farai. Quello che hai è una risorsa, diciamo un cliente in questo caso. Quella risorsa può essere rappresentata in più modi. Ad esempio, puoi fare:

/customers/123.json
/customers/123.xml
/customers/123.pdf

Stesso cliente, stesso URL, ma rappresentazione diversa. Puoi farlo utilizzando il rilevamento del tipo di contenuto in modo da non dover utilizzare le estensioni, se lo desideri.

Per lo stesso cliente desideri solo un singolo URL. Non più endpoint, non è una strategia per il futuro. REST lavora strongmente con i codici di errore per rispondere alla risposta giusta al tuo cliente. Questo è ciò che impedisce il bisogno di cose come:

I keep the GET endpoint at address "/customer" which accepts an extra parameter called type which could take values type="check"/type="fullCustomer" which will determine the flow of events on the server and serve the appropriate response.

Semplicemente non ne hai bisogno in REST.

    
risposta data 30.06.2016 - 10:13
fonte

Leggi altre domande sui tag