Perché un piccolo vocabolario fisso è visto come un vantaggio per i servizi RESTful?

13

Quindi, un servizio RESTful ha un set fisso di verbi nel suo vocabolario. Un servizio web RESTful prende questi dai metodi HTTP. Ci sono alcuni presunti vantaggi nella definizione di un vocabolario fisso, ma in realtà non capisco il punto. Forse qualcuno può spiegarlo.

Perché è un vocabolario fisso come descritto da REST meglio di definire dinamicamente un vocabolario per ogni stato? Ad esempio, la programmazione orientata agli oggetti è un paradigma popolare. RPC è descritto per definire interfacce fisse, ma non so perché la gente supponga che RPC sia limitato da questi punti di contatto. Potremmo specificare dinamicamente l'interfaccia proprio come un servizio RESTful descrive dinamicamente la sua struttura del contenuto.

Il REST dovrebbe essere vantaggioso in quanto può crescere senza estendere il vocabolario. I servizi RESTful crescono in modo dinamico aggiungendo più risorse. Cosa c'è di così sbagliato nell'estendere un servizio specificando in modo dinamico un vocabolario per oggetto? Perché non usiamo solo i metodi definiti nei nostri oggetti come vocabolario e i nostri servizi descrivono al cliente quali sono questi metodi e se hanno o meno effetti collaterali?

In sostanza ho la sensazione che la descrizione di una struttura di risorse lato server sia equivalente alla definizione di un vocabolario, ma siamo quindi costretti a usare il vocabolario limitato in cui interagire con queste risorse.

Un vocabolario fisso disaccoppia realmente le preoccupazioni del cliente dalle preoccupazioni del server? Sicuramente devo occuparmi di alcune configurazioni del server, questa è normalmente la posizione delle risorse nei servizi RESTful. Contrastare l'uso di un vocabolario dinamico sembra ingiusto perché dobbiamo in qualche modo ragionare in modo dinamico come capire in qualche modo questa configurazione. Un servizio RESTful descrive le transizioni che sei in grado di fare identificando la struttura dell'oggetto tramite hypermedia.

Semplicemente non capisco cosa rende un vocabolario fisso migliore di qualsiasi vocabolario dinamico che si descrive da sé, che potrebbe facilmente funzionare molto bene in un servizio simile a RPC. Questo è solo un pessimo ragionamento per il vocabolario limitante del protocollo HTTP?

riflessione

Solo per chiarire i miei pensieri un po 'meglio di quello che ho fatto. Supponiamo che tu stia progettando qualsiasi API generica, forse nemmeno con il web. Saresti felice se qualcuno dicesse che puoi usare solo questi nomi di metodo sui tuoi oggetti? REST non è limitato a HTTP, ma considera la situazione in cui ogni API che scrivi, rivolta verso il Web o altrimenti semplicemente consisteva in oggetti contenenti metodi GET POST PUT e DELETE. Quindi quel metodo object.foo che volevi definire non è possibile. Devi definire un nuovo oggetto chiamato foo e chiamare il suo metodo GET. Questo è essenzialmente il modo in cui funziona REST, e mi fa un po 'a disagio pensarci. Non hai una migliore comprensione generica di cosa fa foo, sei stato solo costretto a creare un nuovo oggetto per quello che è essenzialmente un metodo su un oggetto genitore. Inoltre la tua API non è meno complessa, hai solo una complessità dell'interfaccia nascosta creando più oggetti. I servizi web RESTful ci costringono ad adottare un'interfaccia che può o non può essere sufficiente nel contesto dell'API che stiamo esponendo. Forse c'è una buona ragione per farlo con le API web facing, ma una buona ragione per non adottare le interfacce standard per ogni oggetto in ogni API generica. Un esempio pratico sarebbe apprezzato.

    
posta Matt Esch 25.03.2012 - 01:43
fonte

7 risposte

2

Considera una lingua in cui tutti i costrutti (come le funzioni) sono oggetti. Quindi i verbi RESTful stanno semplicemente chiamando convenzioni e dichiarazioni di assegnazione. Per JavaScript è possibile definire una sintassi fissa del verbo come INVOKE per chiamare una funzione, DELETE (uguale a delete in js) per l'eliminazione di un oggetto su un altro oggetto, SET per l'assegnazione di un valore e RETURN per la restituzione di un valore. Potremmo usare i verbi HTTP per indicare l'equivalente POST - invocare la funzione, PUT - assegnare il valore, GET - restituire un valore, - DELETE - cancellare un oggetto. Sono stato preso dall'idea che i metodi HTTP stessero effettivamente descrivendo metodi oggetto, interfacce oggetto reali, che non sono riuscito a vedere che potesse effettivamente descrivere concetti di livello più basso, come i costrutti linguistici di base che sono chiaramente fissi e finiti in tutto lingue sane. I verbi HTTP definiscono la sintassi di manipolazione dell'oggetto e la struttura dell'oggetto di livello superiore definisce i metodi API.

E ovviamente è utile per il routing / proxy di avere un vocabolario fisso su cui riflettere.

    
risposta data 23.08.2013 - 01:49
fonte
9

La terminologia "verbo" e "sostantivo" è un po 'sfortunata qui. Come hai già detto, puoi facilmente creare oggetti per la funzione. Tutti i linguaggi orientati agli oggetti tranne Java hanno quella trasformazione integrata e in Java si finisce sempre per farlo con molti oggetti con un singolo metodo e spesso uno chiamato "invoke", "execute", "apply" o somesuch (quindi sono i linguaggi di programmazione in cui la distinzione "verbo" / "sostantivo" in realtà non ha senso).

I "verbi" di REST sono più come classificare i tuoi metodi per getter, setter (deletatori, possono essere considerati tipi di setter) e altro. E cercando di fare tutto con getter e setter. La ragione di questo è:

  1. Semantica più semplice in caso di fallimento della comunicazione, dal momento che sia i getter che i setter sono idempotenti. Ottenere la risorsa due volte non ha alcun effetto aggiuntivo e non lo imposta sul valore che ha già.
  2. Definizione di una semantica che può essere utilizzata dal possibile proxy di cache che non comprende l'interfaccia specifica. I getter sono memorizzati nella cache e si sa che i setter invalidano la cache.

HTTP è stato progettato fin dall'inizio con entrambe le cache e la tolleranza agli errori in mente, quindi questi due punti portano ai suoi quattro metodi di base:

  • GET è un getter. Si presume che non modifichi lo stato del server e restituisca lo stesso valore ogni volta con la possibilità di specificare i criteri di scadenza e riconvalida.
  • PUT e DELETE sono il setter e il deleter (= setter con nil). Non sono normalmente usati nel contesto del web normale, ma hanno senso per REST.
  • POST è un generico "invoke" kitchen sink per il quale le cache non possono assumere nulla.

REST è un modello di progettazione che descrive come utilizzare i protocolli di rete raw o simili per implementare un'interfaccia che consenta una facile gestione dei guasti semplicemente riprovando e funzioni correttamente con i proxy di caching.

Non corrisponde facilmente alla normale API di programmazione orientata agli oggetti. Penso che sia in realtà una buona cosa. Le sfide dell'interfacciamento sulla rete, che è intrinsecamente inaffidabile e in cui i round-trip sono molto più lenti del trasferimento di una quantità moderata di dati richiedono un approccio di progettazione diverso rispetto all'API in-process, quindi quando appare diverso, le persone non cercano di applicare esperienza invalida dell'altro dominio più di tanto (questa è la rovina di SOAP, XML-RPC e simili: assomiglia a chiamate di procedure, ma non funziona come tale e finisce per essere un problema con cui lavorare).

    
risposta data 29.11.2012 - 10:11
fonte
2

L'idea essenziale è che la complessità sia espressa attraverso la rappresentazione della risorsa, e quindi non sono necessari verbi aggiuntivi. Come alcuni hanno messo - "In REST, i nomi sono buoni, i verbi sono cattivi."

Se guardi i quattro verbi di REST, possono essere mappati alle operazioni di base di CRUD, essenzialmente permettendoti di fare quello che vuoi con le tue risorse. Questo è -

POST - Create the resource

GET - Read the resource

PUT - Update the resource

DELETE - Delete the resource

Di cos'altro hai bisogno?

    
risposta data 25.03.2012 - 05:33
fonte
1
  • Perché un programmatore professionista anticipa centinaia, se non migliaia di nomi di metodi in caso contrario. Ciò che sembra inutile in un piccolo più piccolo può essere un grosso problema in quanto l'applicazione diventa più grande.

  • Perché non c'è bisogno di standard sui nomi dei metodi quando sono già definiti.

  • Poiché l'obiettivo principale del codice è leggibile senza tali traduzioni aggiuntive.

  • Perché incoraggia e aiuta a identificare "quando" dovrebbe essere scomposta un'altra classe.

  • Quando prendi il codice è ragionevole e puoi effettivamente capire cosa e come fa molto più rapidamente.

  • Fornisce un vocabolario comune e quindi il livello di astrazione in modo che tu possa concentrarti su altri dettagli e vedere i modelli.

  • Semplifica la ricerca di bug in quanto è facile controllare il codice e gli approcci più comuni.

  • Quando lavori con più 'livelli' come uno nello sviluppo web, sapendo quali URL corrispondono a quali nomi di azioni sono molto utili per il debug.

Nel complesso non ne hai sempre bisogno, ma come la maggior parte degli standard, ha senso cercare di usarlo!

    
risposta data 25.03.2012 - 05:53
fonte
1

L'alternativa è qualcosa di orribile: WSDL (aka Web Service Definition Language), che è un modo (maldestro) per descrivere a livello di programmazione (in qualche modo) APIS arbitrario.

REST limita strongmente i verbi, spingendo quasi tutte le variazioni specifiche dell'applicazione nel carico utile del documento. Il vantaggio di farlo è che molte implementazioni client possono comunicare con molti servizi eterogenei. I client e i server potrebbero essere completamente sconosciuti l'uno all'altro, alcuni non ancora scritti.

C'è un podcast in cui Stefan Tilkov spiega bene REST .

    
risposta data 29.11.2012 - 08:47
fonte
1

Sì, api di riposo ha un set fisso di verbi, ma non deve essere limitato a (o includere GET, POST, PUT, DELETE). Guarderei GET, POST, PUT, DELETE come un'implementazione predefinita di REST che funziona per l'80% di tutti i sistemi là fuori.

Altri sistemi che stanno implementando più di operazioni di crudizzazione possono (e devono) implementare i propri verbi per le proprie API REST. Verbi come Pubblica, Consuma, Vota, Commenta, Cerca, Sfoglia possono essere aggiunti e implementati in un sistema REST. Mentre alcuni potrebbero dire che un vocabolario più ampio potrebbe renderlo più complicato, la mia risposta è che dipende. Se il tuo target di utenti sono responsabili tecnici che capiscono cos'è un POST, allora sì, potrebbe essere più complicato; tuttavia, se gli utenti target della tua API sono persone reali (ovvero persone che non codificano e non sanno cos'è un POST), allora i verbi reali sono molto più facili da usare. Infatti avere un insieme appropriato di verbi per la tua API ti aiuta a mantenere gli URL brevi (che è importante se vuoi che gli utenti li digitino in un browser. Se usi un vocabolario personalizzato, vorresti assicurarti che la tua API e i suoi verbi sono ben documentati. Quando usi una API REST personalizzata, devi assicurarti che le tue "azioni di sola lettura" come GET HTTP e "scrivi azioni" con POST.

Il social network per adolescenti, Piczo.com (potrebbe riposare in pace) includeva un'API REST estesa (compresi i verbi menzionati sopra) implementata in 7 lingue diverse!

    
risposta data 07.11.2014 - 01:56
fonte
0

Semplice è buono.

Ci sono casi in cui hai bisogno di verbi e complessità extra, ma la maggior parte dei problemi può essere ridotta a semplici azioni CRUD sulle risorse, e questo è ciò che REST tenta di promuovere. Quando si pensa alla maggior parte delle applicazioni Web, alla fine leggono e persistono i record in un archivio dati, che utilizzano le stesse azioni molto semplici.

object.foo () è tutto buono, ma cosa fa? Cosa sta restituendo? Sta modificando lo stato dell'oggetto o una qualsiasi delle sue dipendenze? Puoi chiamarlo due volte e ottenere lo stesso risultato o ti darà due valori diversi? Se hai anche object.bar (), devono essere chiamati in un ordine specifico?

C'è molta conoscenza richiesta nell'uso di un'API ricca e di solito hanno le proprie convenzioni (es. setFoo sta per mutare l'oggetto, getBar è probabilmente idempotente, dispose () o destroy () significa nessun'altra chiamata su lo stesso oggetto sarà possibile, ecc ...)

    
risposta data 23.08.2013 - 02:33
fonte

Leggi altre domande sui tag