Quell'API REST è davvero RPC? Roy Fielding sembra pensarla così


99

Molto di quello che pensavo di sapere su REST è apparentemente sbagliato e non sono solo. Questa domanda ha una lunga introduzione, ma sembra necessaria perché le informazioni sono un po 'sparse. La vera domanda arriva alla fine se hai già familiarità con questo argomento.

Dal primo paragrafo delle API REST di Roy Fielding devono essere guidate da ipertesto , è abbastanza chiaro che crede che il suo lavoro sia stato ampiamente interpretato male:

Sono frustrato dal numero di persone che chiamano qualsiasi interfaccia basata su HTTP un'API REST. L'esempio di oggi è l' API REST di SocialSite . Questo è RPC. Urla RPC. C'è così tanto accoppiamento in mostra che dovrebbe essere valutato X.

Fielding prosegue elencando diversi attributi di un'API REST. Alcuni di loro sembrano andare contro sia la pratica comune che i consigli comuni su SO e altri forum. Per esempio:

  • Un'API REST deve essere inserita senza alcuna conoscenza preliminare oltre l'URI iniziale (segnalibro) e un set di tipi di media standardizzati appropriati per il pubblico previsto (cioè, che dovrebbero essere compresi da qualsiasi client che potrebbe utilizzare l'API). ...

  • Un'API REST non deve definire nomi o gerarchie di risorse fisse (un ovvio accoppiamento di client e server). ...

  • Un'API REST dovrebbe dedicare quasi tutto il suo sforzo descrittivo alla definizione dei tipi di media utilizzati per rappresentare le risorse e guidare lo stato dell'applicazione, o nella definizione di nomi di relazione estesa e / o markup abilitato per ipertesto per i tipi di media standard esistenti. ...

L'idea di "ipertesto" gioca un ruolo centrale, molto più della struttura URI o del significato dei verbi HTTP. "Hypertext" è definito in uno dei commenti:

Quando io [Fielding] dico ipertesto, intendo la presentazione simultanea di informazioni e controlli in modo tale che l'informazione diventi l'affordance attraverso la quale l'utente (o l'automa) ottiene scelte e seleziona azioni. L'ipermedia è solo un'espansione di ciò che il testo significa includere ancore temporali all'interno di un flusso multimediale; la maggior parte dei ricercatori ha abbandonato la distinzione.

Non è necessario che l'ipertesto sia HTML su un browser. Le macchine possono seguire i collegamenti quando comprendono il formato dei dati e i tipi di relazione.

Immagino a questo punto, ma i primi due punti sopra sembrano suggerire che la documentazione API per una risorsa Foo che assomiglia alla seguente porta a uno stretto accoppiamento tra client e server e non ha posto in un sistema RESTful.

GET   /foos/{id}  # read a Foo
POST  /foos/{id}  # create a Foo
PUT   /foos/{id}  # update a Foo

Invece, un agente dovrebbe essere costretto a scoprire gli URI per tutti i Foos, ad esempio, inviando una richiesta GET contro / foos. (Questi URI possono risultare seguire lo schema sopra, ma non è questo il punto.) La risposta utilizza un tipo di media che è in grado di comunicare come accedere a ciascun elemento e cosa si può fare con esso, dando origine al terzo punto sopra . Per questo motivo, la documentazione API dovrebbe concentrarsi sulla spiegazione di come interpretare l'ipertesto contenuto nella risposta.

Inoltre, ogni volta che viene richiesto un URI a una risorsa Foo, la risposta contiene tutte le informazioni necessarie affinché un agente scopra come procedere, ad esempio accedendo alle risorse associate e padre tramite i loro URI, o agendo dopo la creazione / cancellazione di una risorsa.

La chiave dell'intero sistema è che la risposta consiste in un ipertesto contenuto in un tipo di supporto che a sua volta trasmette all'agente le opzioni per procedere. Non è diverso dal modo in cui funziona un browser per gli esseri umani.

Ma questa è solo la mia ipotesi migliore in questo particolare momento.

Fielding ha pubblicato un seguito in cui ha risposto alle critiche secondo cui la sua discussione era troppo astratta, priva di esempi e ricca di gergo:

Altri cercheranno di decifrare ciò che ho scritto in modi più diretti o applicabili a qualche preoccupazione pratica di oggi. Probabilmente non lo farò, perché sono troppo impegnato ad affrontare l'argomento successivo, a prepararmi per una conferenza, a scrivere un altro standard, a viaggiare in qualche luogo lontano o semplicemente a fare le piccole cose che mi fanno sentire di aver guadagnato il mio stipendio.

Quindi, due semplici domande per gli esperti REST là fuori con una mentalità pratica: come interpreti ciò che Fielding sta dicendo e come lo metti in pratica durante la documentazione / implementazione delle API REST?

Modifica: questa domanda è un esempio di quanto possa essere difficile imparare qualcosa se non hai un nome per ciò di cui stai parlando. Il nome in questo caso è "Hypermedia as the Engine of Application State" (HATEOAS).


26
John, Rich sta solo spiegando il cambiamento di mentalità che aveva. Non c'è niente di soggettivo o polemico al riguardo. Vota per rimanere aperto: questa è una delle migliori domande etichettate con "riposo" che ho visto su SO.
Keith Gaughan,

4
Keith, "spiegare il cambiamento di mentalità" è qualcosa che dovrebbe fare nel suo blog, non su SO.
John Saunders

13
Non sta spiegando il suo cambiamento di mentalità, sta chiedendo se la sua comprensione è accurata.
aehlke

4
Eccellente sintesi. Ho imparato di più da questa domanda che dalla maggior parte delle risposte.
Martin Konecny

Risposte:


21

Penso che la tua spiegazione lo copra principalmente. Gli URI sono identificatori opachi che, per la maggior parte, non dovrebbero essere comunicati oltre l'URI del segnalibro utilizzato dall'agente utente per accedere all'app.

Per quanto riguarda la documentazione, questa domanda è stata posta parecchie volte. Documenta il tuo tipo di media, insieme ai controlli del collegamento ipertestuale che contiene (link e moduli) e il modello di interazione se lo desideri (vedi AtomPub).

Se documenti gli URI o come costruirli, stai sbagliando.


È ancora vero? Esistono specifiche di risposta API come Ionspec che hanno intenzionalmente creato questi URI come parte della risposta.
Sean Pianka

Si Loro hanno. A quel punto si tratta di capire se quegli URI documentati sono solo punti di ingresso per l'applicazione, che sono garantiti per rimanere (alcuni di questi non sono rari e piuttosto utili) o se, poiché le persone vogliono la generazione di codice, quelli sono incorporati da una specifica direttamente nel codice, impedendo al server di far sapere al client come può fare le cose. Se il cliente pensa di sapere a causa di quel contratto, non sei nell'ipermedia, sei nel moderno modello di sapone openapi, con gli stessi problemi che avresti riscontrato 18 anni fa.
SerialSeb

Ciò che è vero è che molti linguaggi di documentazione API si sono sviluppati negli ultimi 11 anni, ma le basi non sono cambiate. Credo che il valore nella scoperta di quei collegamenti, o per lo meno nella scoperta del modello URI, sia nella creazione di codice client generico riutilizzabile che possa utilizzarli dinamicamente, consentendo a molte implementazioni sul lato server di riutilizzare lo stesso codice client. L'incorporamento dell'URI continua a rendere più difficili tali scenari, ma se usi questi formati, tendi ad accoppiare strettamente un client generato da quelle specifiche, quindi hai già perso quella caratteristica.
SerialSeb

8

La tua interpretazione mi sembra corretta. Credo che i vincoli di Fielding possano essere applicati praticamente.

Mi piacerebbe davvero vedere qualcuno pubblicare alcuni buoni esempi di come documentare un'interfaccia REST. Ci sono così tanti esempi poveri, avere alcuni validi a cui indirizzare gli utenti sarebbe molto prezioso.


2
Wow. Quella pagina del modello di risorsa mi ha fatto venire le lacrime agli occhi. Speriamo che questo inizi una tendenza.
Darrel Miller

È un peccato che questo sia fondamentalmente l' unico esempio di tale API sul web! Peggio ancora, non ci sono buoni esempi di codice client che segue il principio (che ho trovato).
jkp

1
@DarrelMiller Ma questi tipi di media non sono troppo "specifici"? Mi sembra che la loro API stia veramente usando un solo MIME: application/jsone che il Resource Model sia veramente le relazioni. Ho frainteso questo aspetto di REST? Ho anche letto una delle tue risposte SO che sembra indicare che quei contratti "un attributo" dovrebbero essere evitati ...
edsioufi

2
@RichApodaca Il tuo link è morto di dissenteria. web.archive.org/web/20170409132237/https://kenai.com/projects/…
forresthopkinsa

5

Stavo cercando un buon esempio di un'API scritta seguendo HATEOAS e ho avuto problemi a trovarne una (ho trovato sia l'API SunCloud che AtomPub difficili da applicare a una situazione API "normale"). Quindi ho provato a fare un esempio realistico sul mio blog che seguisse i consigli di Roy Fieldings su cosa significhi essere una corretta implementazione REST. Ho trovato molto difficile trovare l'esempio, nonostante il fatto che sia abbastanza semplice in linea di principio (solo confuso quando si lavora con un'API anziché con una pagina web). Capisco cosa Roy stava contestando e sono d'accordo, è solo un cambiamento nella mentalità da implementare correttamente per un'API.

Dai un'occhiata: Esempio di API utilizzando Rest


4

L'unica eccezione per fornire istruzioni su come costruire URI è che è consentito inviare un modello di URI nella risposta ipertestuale, con i campi che devono essere sostituiti automaticamente dal client, utilizzando altri campi nell'ipertesto. Questo di solito non finisce per risparmiare molta larghezza di banda, poiché la compressione gzip gestirà le parti ripetute degli URI abbastanza bene da non preoccuparsene.

Alcune buone discussioni su REST e sui relativi HATEOAS:

Vantaggi dell'utilizzo (anche) di HATEOAS nelle API RESTFul

Come ottenere una tazza di caffè



4

La cosa che la maggior parte delle persone sbaglia è che (almeno credo) nel mondo REST non si documenta la propria "interfaccia Rest", ciò che si documenta è un tipo di supporto, indipendentemente dal proprio server o servizio.


2

Penso che nel corso degli anni in cui REST è stato disponibile ora, i tecnologi sono venuti a patti con il concetto di una risorsa e cosa è veramente o non è RESTful.

Secondo il Richardson Maturity Model, ci sono 4 livelli (0-3) che definiscono quanto sia RESTful la tua API, con 3 che significa un'API veramente RESTful, proprio come Roy Fielding voleva che fosse.

Il livello 0 è quando si dispone di un punto di ingresso URI, come SOAP.

Il livello 1 significa che l'API è in grado di distinguere tra diverse risorse e ha più di un punto di ingresso - odora ancora di SOAP.

Il livello 2 è quando usi i verbi HTTP - GET, POST, DELETE principalmente. Questo è il livello in cui REST entra davvero in scena.

Al livello 3, inizi a utilizzare i controlli ipermediali per rendere la tua API veramente RESTful.

Link suggeriti per ulteriori letture:


1

Assolutamente corretto. Noterei inoltre che i modelli URI vanno perfettamente bene all'interno di un'applicazione RESTful purché i modelli provengano da documenti ricevuti dal server (OpenSearch è un esempio adatto). Per i modelli URI, devi documentare dove vengono utilizzati e quali sono i segnaposto previsti nel modello, ma non i modelli stessi. Leggermente contrariamente a quanto ha detto Wahnfrieden, questa non è un'eccezione.

Ad esempio, al mio lavoro abbiamo un sistema di gestione del dominio interno e il documento di servizio specifica due modelli di URI: uno per produrre un URI migliore per una risorsa di dominio e un altro per costruire un URI per interrogare la disponibilità del dominio. È ancora possibile sfogliare la raccolta di domini per capire qual è l'URI di un determinato dominio, ma dato l'immenso numero di domini che gestisce, questo non sarebbe fattibile per il client, quindi dando loro un modo per indovinare quale sia il L'URI di una risorsa di dominio potrebbe essere una grande vittoria in termini di facilità di implementazione dal punto di vista del client e larghezza di banda dal punto di vista del server.

Alla tua domanda: la nostra documentazione normativa espone le risorse, l'effetto di vari metodi su tali risorse, i tipi di media di rappresentazione utilizzati e i loro schemi, e il tipo di risorse a cui puntano gli URI in quelle rappresentazioni.

Includiamo anche documentazione non normativa (informativa) a cui è allegato un disclaimer per non leggere troppo negli URI menzionati nel documento, che fornisce esempi di interazioni tipiche client-server. Questo mette la documentazione normativa piuttosto astratta in termini concreti.


1
Va bene fornire modelli URI come parte della tua API, fuori banda. PER FAVORE, NON fare riferimento a questo come REST, perché non lo è. È un'enorme quantità di accoppiamento, ed esattamente ciò che REST è stato fatto per evitare. Ma come dici tu, REST non è per tutte le applicazioni. Quindi non fingere che ogni applicazione sia REST.
aehlke

1
In realtà, sono d'accordo. Credo che sia quello che ho detto. Tuttavia, non vedo davvero alcun buon motivo per fornire modelli URI fuori banda.
Keith Gaughan

0

Supponiamo che GET /foos/createFormvenga invocato per ottenere i valori dei campi del modulo per i quali devono essere forniti quando andiamo a creare POST /foos. Ora questo particolare URL, cioè l'1 usato per creare foo, dovrebbe essere menzionato nella risposta per GET /foos/createFormcome un link di azione di invio secondo la proposta di Fielding, giusto?
Allora qual è il vantaggio di mappare le azioni ai noti verbi Http alle azioni, la cosa "convenzione su codice / configurazione" è annullata.

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.