Barra finale nell'API RESTful


60

Ho avuto un dibattito su cosa fare con una barra finale in un'API RESTful.

Diciamo che ho una risorsa chiamata cani e risorse subordinate per i singoli cani. Possiamo quindi fare quanto segue:

GET/PUT/POST/DELETE http://example.com/dogs
GET/PUT/POST/DELETE http://example.com/dogs/{id}

Ma cosa facciamo con il seguente caso speciale:

GET/PUT/POST/DELETE http://example.com/dogs/

La mia opinione personale è che questo sta dicendo inviare una richiesta a una singola risorsa cane con id = null. Penso che l'API dovrebbe restituire un 404 per questo caso.

Altri dicono che la richiesta sta accedendo alla risorsa cani, ovvero la barra finale viene ignorata.

Qualcuno conosce la risposta definitiva?


2
Ho pensato che il modo RESTful fosse di distinguere tra cane / id e cani (intendendo tutti i cani).
pdr,

Dal libro RESTful Web Services - risorse subordinate: risorse esistenti in relazione a qualche altra risorsa "genitore", ovvero cani / {id} Un database abilitato al web può esporre una tabella come risorsa e le singole righe del database come risorse subordinate .
Gaz_Edge,

Sta accedendo alla risorsa del cane, la barra finale deve essere ignorata, il che significa che dovrebbe ottenere una risposta proibita per tentare di eliminare qualcosa a cui non dovrebbe essere applicata la cancellazione. Immagino che anche 404 sia accettabile. Ma importa?
Benjamin Gruenbaum,

Non seguo - chi ha detto che non puoi cancellare i cani? Se elimini i cani, elimina se stesso e tutti i singoli cani. Ecco perché penso che consentire chiamate ai cani / sia rischioso. Che cosa succede se il client intendesse eliminare un singolo cane, ma accidentalmente lasciato fuori da {id}. Il risultato sarebbe che tutti i cani sarebbero eliminati. Molto più sicuro supporre che stia chiedendo {id} null e restituisca 404
Gaz_Edge,

Tratterei dogse dogs/come equivalente. Per me è chiaro che dogs/è una directory che contiene i singoli cani. È meno chiaro cosa dogssia, ma lo tratterei come equivalente, proprio come la maggior parte dei server web accetta gli accessi alle directory senza il trailing /.
CodesInChaos,

Risposte:


50

Niente di tutto ciò è autorevole (poiché REST non ha un significato esatto). Ma dall'articolo originale su REST un URL completo (che non termina in /) nomina una risorsa, mentre uno che termina in una barra "/" è un gruppo di risorse (probabilmente non è formulato in questo modo).

Un GET di un URL con una barra alla fine dovrebbe elencare le risorse disponibili.

GET http://example.com/dogs/          /* List all the dogs resources */

Un PUT su un URL con una barra dovrebbe sostituire tutte le risorse.

PUT http://example.com/dogs/          /* Replace all the dogs resources */

Un CANC su un URL con una barra dovrebbe eliminare tutte le risorse

DELETE http://example.com/dogs/       /* Deletes all the dogs resources */

Un POST su un URL con una barra dovrebbe creare una nuova risorsa a cui è possibile accedere successivamente. Per essere conforme, la nuova risorsa dovrebbe trovarsi in questa directory (anche se molte architetture RESTful imbrogliano qui).

POST http://example.com/dogs/        /* Creates a new dogs resource (notice singular) */

eccetera.

La pagina wiki sull'argomento sembra spiegarlo bene:

Vedi esempio https://en.wikipedia.org/wiki/Representational_state_transfer#Applied_to_Web_services .


Si adatta anche al normale percorso / modello url, in cui le directory sono spesso scritte con un finale/
CodesInChaos

4
Quindi cosa dovrebbe accadere se si accede a un gruppo di risorse senza il trascinamento /?
oberlies,

1
@oberlies: dipende dal contesto. Non ci sono regole rigide e veloci solo buone pratiche. Ci sono sempre aspettative sulla regola e dovrebbe significare ciò che ti aspetti che significhi. Nell'esempio sopra: GET http://example.com/dogspuò restituire meta informazioni sui cani (non l'elenco stesso ma meta informazioni sull'elenco dei cani). Forse o forse è un errore.
Martin York,

1
As the last character within a URI’s path, a forward slash (/) adds no semantic value and may cause confusion. It’s better to drop them completely.Questo non è l'unico posto che suggerisce di non usare la barra di allenamento
Laiv,

@Laiv Non sono in disaccordo con il sentimento. Ma collega un riferimento più autorevole (che è un collegamento debole).
Martin York,

17
Does anyone know the definitive answer?

Non ce n'è uno in quanto non esiste un documento ufficiale su ciò che è necessario affinché un servizio sia considerato RESTful.

Detto questo, consentirei la barra finale semplicemente per facilità d'uso. Mentre tecnicamente parlando questo potrebbe essere visto come il tentativo di accedere a un cane con un ID null; Non vedo un utente fare questo salto se non l'hanno letto nella documentazione. Vedo un utente che tenta di scrivere codice sull'API e che include la barra finale semplicemente per abitudine e mi chiedo perché ottengano una risposta 404 quando desiderano un elenco di cani.


Che dire di DELETE example.com/dogs ?
Benjamin Gruenbaum,

poiché i cani sono i genitori di tutti i singoli cani, l'eliminazione dei cani eliminerà tutti i singoli cani e se stesso. Se non lo fai, il tuo ipermedio si
guasterà

@Gaz_Edge: In REST example.com/dogsè una risorsa completamente indipendente da qualsiasi risorsa example.com/dogs/X. Quindi un DELETE on example.com/dogsnon deve cancellare tutti i cani / * (sebbene possa farlo se questa è la semantica). Ma ELIMINA example.com/dogs/dovrebbe eliminare tutti i cani / *.
Martin York,

3
Direi ancora una volta che dal momento che non esiste un insieme definitivo di regole su ciò che è RESTful ciò che accade quando ELIMINA / cani o / cani / si baserebbe su ciò che ti aspetti dai consumatori della tua API. È probabile che vorrebbero davvero eliminare tutti i cani con una singola richiesta? In tal caso, implementalo in questo modo, altrimenti fornisci una risposta 405 Metodo non consentito.
Mike,

1
So che questo è un vecchio thread, ma recentemente mi sono chiesto di questo da solo. Per quel che vale, le OS X shell Bash ossequi foo, foo/e foo////in modo identico. Fondamentalmente sembra eliminare segmenti di percorso vuoti. Quindi, se segui lo stesso approccio con il tuo servizio REST dogse dogs/faresti riferimento alla stessa cosa.
Greg Brown,

2

Due strade.

Metodo 1

Utilizzare sempre le barre finali per qualsiasi risorsa che può contenere elementi secondari.

Basta considerare "GET" in una directory public_html con file.

Non possibile quando hello.html è un file:

/hello.html
/hello.html/youagain.html

Ma possibile quando hello.html è una directory:

/hello.html/     (actually /hello.html/index.html)
/hello.html/youagain.html

Quindi, se "hello.html" può mai avere figli, è sempre e per sempre "/hello.html/" e "/hello.html/index.html" (o semplicemente /hello.html/) è un elenco di questi bambini .

Metodo 2

Essere intelligenti".

$ find
.
./hello.html
./hello.html/index.html

Il comando find non si preoccupa del tipo di hello.html. Directory o file, a chi importa, è il nome di un oggetto. Quando scriviamo "cp youagain.html hello.html", cp può capire come gestire hello.html. cp è intelligente. Anche il tuo server web è intelligente. Ha una libreria di gestione dei percorsi. Ha il routing. Può stat e dirti se un nome è un oggetto o una directory. Può reindirizzare blah a blah / o persino fornire la stessa risposta per entrambi. Questo è fantastico !!! modo. Tanta tecnologia. Chi mai vorrebbe semplicemente concatenare stringhe di percorso quando potremmo fare tutto questo ???

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.