REST - Scambi tra la negoziazione del contenuto tramite l'intestazione Accetta contro le estensioni

40

Sto lavorando alla progettazione di un'API RESTful. Sappiamo di voler restituire JSON e XML per ogni risorsa data. Stavo pensando che avremmo fatto qualcosa di simile:

GET /api/something?param1=value1
Accept:  application/xml (or application/json)

Tuttavia, qualcuno ha buttato fuori le estensioni per questo, in questo modo:

GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

Quali sono i compromessi con questi approcci? È meglio fare affidamento sull'intestazione di accettazione quando un'estensione non è specificata, ma rispettare le estensioni quando specificato? C'è un inconveniente a questo approccio?

    
posta Brandon Linton 14.03.2012 - 03:50
fonte

4 risposte

38

Questo, "Tuttavia, filosoficamente - il primo approccio è l'unico approccio.", e questo "L'approccio REST corretto ufficiale è usare Accept: header." sono ampiamente percepiti per essere il caso, ma sono anche assolutamente errati .

Ecco un breve frammento di Roy Fielding (che ha definito REST) ...

"la sezione 6.2.1 non dice che dovrebbe essere la negoziazione del contenuto usato tutto il tempo. " cite

Quella particolare conversazione è nel contesto dell'intestazione "Accept-Language:", ma lo stesso vale per l'intestazione "Accept:", come chiarito più tardi nella sua risposta ...

"Non ho idea del motivo per cui le persone non possono vedere il secondo e il terzo link nella pagina principale

link

che punta alle due edizioni PDF. "

Ciò che intende è che non vi è alcun problema nell'usare endpoint diversi per rappresentazioni diverse degli stessi dati di origine. (In questo caso un endpoint .html e due diversi endpoint .pdf.)

Anche in una discussione simile, questa volta riguarda i vantaggi dell'utilizzo dei parametri di query rispetto all'utilizzo di estensioni di file per diversi tipi di media ...

"Ecco perché preferisco sempre le estensioni. Nessuna scelta ha nulla a che fare con REST. " cite

Anche in questo caso, è leggermente diverso rispetto alle estensioni Accept vs. filename, ma la posizione di Fielding è ancora chiara.

Risposta: non importa molto. I compromessi tra i due non sono molto significativi ed entrambi sono stili accettabili.

    
risposta data 18.10.2012 - 16:59
fonte
9

L'approccio ufficiale RESTful corretto è quello di usare Accept: header.

Tuttavia, devi fare attenzione a non rompere la cacheability, che è uno dei requisiti di REST. Devi avere Vary: Accept header e cache che lo capiscano. Nel mondo ideale lo avresti, ma nella vita reale il tuo millesimo potrebbe variare. Quindi la seconda soluzione non è così pulita, ma potrebbe essere più pratica.

Inoltre, si noti che alcuni browser molto vecchi erano soliti ignorare le intestazioni, basandosi invece sull'estensione.

    
risposta data 14.03.2012 - 15:25
fonte
9

Tecnicamente non ha molta importanza: il tuo server web sarà in grado di passare elaborarlo in modo appropriato come sembra. (Sto assumendo questo, ma non sembra uno showstopper).

Tuttavia, filosoficamente - il primo approccio è l'unico approccio. In REST, l'URL punta solo a un URI, che è solo una risorsa. Pensa per un momento questa risorsa uguale a oggetto nella programmazione orientata agli oggetti. parla a questa risorsa attraverso solo 4 metodi (ovvero GET / POST / PUT / DELETE -oppure se consentito dal trasporto) ma quel metodo non diventa descrizione dell'oggetto . Allo stesso modo, gli aspetti del valore di ritorno non sono l'URI. L'oggetto è ancora qualcosa e non qualcosa.xml o qualcosa.json

Supponiamo che se non vuoi usare l'intestazione Accept, ma se vuoi comunque essere veramente REST filosoficamente, non mi dispiacerà qualcosa del tipo:

GET /api/something?parm1=value1&return_type=xml

al contrario di

GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

Ma come ho detto, questa differenza è solo filosofica.

    
risposta data 14.03.2012 - 15:26
fonte
0

@vartec: Penso che tu abbia torto

Il corretto principio ufficiale RESTful dice che nulla deve essere nascosto nelle intestazioni HTTP in quanto è l'URI che è esposto o referenziato, qualsiasi dettaglio sulla richiesta / risposta dovrebbe essere fornito come parte dell'URI

Quindi raccomando vivamente di evitare l'uso dell'intestazione per dettagli che riguardano la richiesta & risposta, e attenersi a

 GET /api/something.xml?parm1=value1 (or /api/something.json?param1=value1)

Non sono in grado di trovare rapidamente i riferimenti, ma li posterò con loro (in realtà potresti riferirti al libro di pubblicazione O'Reilly "RESTful web services" ( link ) che conferma lo stesso

    
risposta data 16.03.2012 - 11:42
fonte

Leggi altre domande sui tag