Come si inseriscono le ricerche in un'interfaccia RESTful?


137

Quando si progetta un'interfaccia RESTful, la semantica dei tipi di richiesta è considerata vitale per il progetto.

  • OTTIENI : elenca la raccolta o recupera l'elemento
  • PUT - Sostituisce la raccolta o l'elemento
  • POST : crea una raccolta o un elemento
  • ELIMINA - Bene, erm, elimina la raccolta o l'elemento

Tuttavia, questo non sembra coprire il concetto di "ricerca".

Ad esempio, nella progettazione di una suite di servizi Web che supportano un sito di ricerca di lavoro, potresti avere i seguenti requisiti:

  • Ottieni annunci di lavoro individuali
    • ARRIVARE adomain/Job/{id}/
  • Crea annuncio di lavoro
    • POST adomain/Job/
  • Aggiorna annuncio di lavoro
    • MESSA adomain/Job/
  • Elimina annuncio di lavoro
    • ELIMINA adomain/Job/

"Ottieni tutti i lavori" è anche semplice:

  • ARRIVARE adomain/Jobs/

Tuttavia, in che modo la "ricerca" di lavoro rientra in questa struttura?

Si potrebbe affermare che è una variante di "raccolta lista" e mettere in atto come:

  • ARRIVARE adomain/Jobs/

Tuttavia, le ricerche possono essere complesse ed è del tutto possibile produrre una ricerca che genera una lunga stringa GET. Cioè, facendo riferimento a una domanda SO qui , ci sono problemi che usano stringhe GET più lunghe di circa 2000 caratteri.

Un esempio potrebbe essere in una ricerca sfaccettata - continuando l'esempio "lavoro".

Potrei consentire la ricerca di aspetti: "Tecnologia", "Titolo professionale", "Disciplina", nonché parole chiave a testo libero, età del lavoro, luogo e stipendio.

Con un'interfaccia utente fluida e un gran numero di tecnologie e titoli di lavoro, è possibile che una ricerca comprenda un gran numero di scelte di sfaccettature.

Modifica questo esempio ai CV, piuttosto che ai lavori, porta ancora più sfaccettature e puoi facilmente immaginare una ricerca con un centinaio di sfaccettature selezionate o anche solo 40 sfaccettature ciascuna delle quali sono lunghe 50 caratteri (ad esempio, titoli di lavoro, nomi di università, Nomi dei datori di lavoro).

In tale situazione potrebbe essere desiderabile spostare un PUT o un POST per garantire che i dati di ricerca vengano inviati correttamente. Per esempio:

  • POST adomain/Jobs/

Ma semanticamente è un'istruzione per creare una collezione.

Si potrebbe anche dire che si esprime questo come la creazione di una ricerca:

  • POST adomain/Jobs/Search/

o (come suggerito da burninggramma sotto)

  • POST adomain/JobSearch/

Semanticamente può sembrare sensato, ma in realtà non stai creando nulla, stai facendo una richiesta di dati.

Quindi, semanticamente è un GET , ma GET non è garantito per supportare ciò di cui hai bisogno.

Quindi, la domanda è: cercare di mantenere il più fedele possibile alla progettazione RESTful, assicurandomi al contempo di rispettare i limiti di HTTP, qual è il design più appropriato per una ricerca?


3
Spesso intendo usare GET domain/Jobs?keyword={keyword} . Questo funziona bene per me :) La mia speranza è che il SEARCHverbo diventi uno standard. programmers.stackexchange.com/questions/233158/…
Knerd

Sì, posso vedere che per un esempio banale non c'è nessun problema. Ma nello strumento che stiamo costruendo in realtà non è così incredibile che finiremmo con una ricerca complessa che si traduce in una stringa GET più lunga di 2000 caratteri. Cosa poi?
Rob Baillie,

In realtà un ottimo punto. Che ne dici di specificare una tecnologia di compressione?
Knerd,

2
OTTENERE con un corpo è consentito dalle specifiche HTTP, può o meno essere supportato dal middleware (a volte no);) e non è favorito come pratica. Questo si verifica periodicamente su Stackexchange. stackoverflow.com/questions/978061/http-get-with-request-body
Rob

2
Ho finito con POST JobSearch per creare un'entità di ricerca effettiva e restituire un jobSearchId. Quindi OTTIENI lavori? JobSearch = jobSearchId restituisce la raccolta di lavori effettiva.
Cerad,

Risposte:


93

Non dimenticare che le richieste GET presentano alcuni vantaggi superiori rispetto ad altre soluzioni:

1) Le richieste GET possono essere copiate dalla barra degli URL, vengono digerite dai motori di ricerca, sono "amichevoli". Dove "amichevole" significa che normalmente una richiesta GET non deve modificare nulla all'interno dell'applicazione (idempotente) . Questo è il caso standard per una ricerca.

2) Tutti questi concetti sono molto importanti non solo dal punto di vista dell'utente e del motore di ricerca, ma dal punto di vista dell'architettura, dal punto di vista dell'API .

3) Se crei una soluzione alternativa con POST / PUT , avrai problemi a cui non stai pensando in questo momento. Ad esempio, nel caso di un browser, il pulsante torna indietro / aggiorna pagina / cronologia. Questi possono essere risolti ovviamente, ma sarà un'altra soluzione alternativa, quindi un altro e un altro ...

Considerando tutto ciò il mio consiglio sarebbe:

a) Dovresti essere in grado di adattarti al tuo GET usando una struttura di parametri intelligente . In casi estremi puoi anche optare per tattiche come questa ricerca su Google in cui ho impostato molti parametri eppure è un URL super breve.

b) Crea un'altra entità nella tua applicazione come JobSearch . Supponendo che tu abbia così tante opzioni, è probabile che dovrai archiviare anche queste ricerche e gestirle, quindi è sufficiente cancellare la tua applicazione. Puoi lavorare con gli oggetti JobSearch come intera entità, il che significa che puoi testarlo / usarlo più facilmente .


Personalmente proverei a combattere con tutti i miei artigli per farlo con a) e quando tutta la speranza è persa, tornerei indietro con le lacrime agli occhi all'opzione b) .


4
Per chiarimenti, questa domanda è destinata alla progettazione di servizi Web, non alla progettazione di siti Web. Quindi, mentre il comportamento del browser è di interesse per la portata più ampia dell'interpretazione della domanda, nel caso particolare descritto non ha alcuna conseguenza. (punto interessante però).
Rob Baillie,

@RobBaillie Sì, il browser era solo un caso d'uso. Volevo esprimere il fatto che la tua ricerca nel suo insieme è rappresentata da una stringa URL. Che ha molto conforto nell'usabilità insieme ad altri punti più avanti nella risposta.
p1100i,

Al punto b, si tratta di una semplice variante del mio riferimento a un POST a domain/Jobs/Search/, magari con domain/JobsSearch/, invece, o volevi dire qualcosa di diverso? Puoi chiarire?
Rob Baillie,

7
Perché ho l'impressione che REST sia abbastanza spesso parte del problema, piuttosto che parte della soluzione?
JensG,

1
"La richiesta GET non deve modificare nulla all'interno dell'applicazione (idempotente)" mentre GET è idempotente, la parola pertinente è " sicura " qui. Idempotente significa che fare GET su una risorsa due volte equivale a fare GET su quella risorsa una volta. PUT è anche idempotente, ma non sicuro, per esempio.
Jasmijn,

12

TL; DR: GET per il filtro, POST per la ricerca

Faccio una distinzione tra il filtraggio dei risultati dall'elenco di una raccolta rispetto a una ricerca complessa. La cartina di tornasole che uso è fondamentalmente se ho bisogno di qualcosa di più del filtraggio (positivo, negativo o intervallo), lo considero una ricerca più complessa che richiede POST.

Questo tende ad essere rafforzato quando si pensa a cosa verrà restituito. Di solito uso GET solo se una risorsa ha un ciclo di vita quasi completo (PUT, DELETE, GET, collection GET) . In genere in una raccolta OTTENERE un elenco di URI che sono le risorse REST che compongono quella raccolta. In una query complessa potrei estrarre da più risorse al fine di costruire la risposta (pensa a SQL join) in modo da non rispedire gli URI, ma i dati effettivi. Il problema è che i dati non saranno rappresentati in una risorsa, quindi dovrò sempre restituire i dati. Questo mi sembra un chiaro caso di richiedere un POST.

-

È passato un po 'di tempo e il mio post originale era un po' sciatto, quindi ho pensato di aggiornarlo.

GET è la scelta intuitiva per restituire la maggior parte dei tipi di dati, raccolte di risorse REST, dati strutturati di una risorsa, persino payload singolari (immagini, documenti, ecc.).

POST è il metodo catchall per tutto ciò che non sembra rientrare in GET, PUT, DELETE, ecc.

A questo punto penso che le ricerche semplici, il filtraggio abbiano un senso intuitivo tramite GET. Le ricerche complesse dipendono dalle preferenze personali, specialmente se si stanno inserendo funzioni di aggregazione, correlazioni incrociate (join), riformattazioni, ecc. Direi che i parametri GET non dovrebbero richiedere troppo tempo, ed è una query di grandi dimensioni (tuttavia è strutturata ) può spesso avere più senso come organismo di richiesta POST.

Considero anche l'aspetto dell'esperienza dell'utilizzo dell'API. In genere, voglio rendere la maggior parte dei metodi il più semplice da usare e intuitivo possibile. Inserirò chiamate più flessibili (e quindi più complesse) nei POST e su un URI di risorse diverso, soprattutto se non è coerente con il comportamento di altre risorse REST nella stessa API.

In entrambi i casi, la coerenza è probabilmente più importante del fatto che si stia effettuando una ricerca in GET o POST.

Spero che sia di aiuto.


1
Poiché REST ha lo scopo di sottrarre l'implementazione sottostante (ad es. - una risorsa non è necessariamente una riga in un database o un file su un disco rigido, ma potrebbe essere qualsiasi cosa ) non so che abbia necessariamente senso usare POST su OTTIENI quando si tratta di eseguire join SQL. Supponiamo che tu abbia un tavolo di scuole e un tavolo di bambini e desideri una classe (una scuola, più bambini). Si potrebbe facilmente definire una risorsa virtuale e GET /class?queryParams. Dal punto di vista di un utente, la "classe" è sempre stata una cosa e non è stato necessario eseguire strani join SQL.
Stevendesu,

Non c'è differenza tra "filtraggio" e "ricerca".
Nicholas Shanks,

1
Sì, esiste un filtro basato su campi esistenti. Una ricerca può contenere schemi molto più complessi, combinando campi, calcolando valori adiacenti ecc.
user13796

@stevendesu esattamente, ecco perché uso POST per entrambi (creazione di una ricerca) :-)
ymajoros

@ymajoros A meno che tu non stia salvando i termini di ricerca e i risultati della ricerca da qualche parte, non so che il POST abbia senso semanticamente. Quando esegui una ricerca, stai facendo una richiesta di informazioni, non stai fornendo nuove informazioni da conservare ovunque.
Stevendesu,

10

In REST, la definizione delle risorse è molto ampia. È in realtà comunque che vuoi raggruppare alcuni dati.

  • È utile pensare a una risorsa di ricerca come una risorsa di raccolta. I parametri della query, a volte chiamati la parte ricercabile dell'URI, restringono la risorsa agli elementi a cui il client è interessato.

Ad esempio, l'URI principale di Google punta a una risorsa di raccolta di "collegamenti a tutti i siti su Internet". I parametri di query si limitano ai siti che si desidera visualizzare.

(URI = identificatore di risorsa universale, di cui URL = localizzatore di risorse universale, in cui il familiare "http: //" è il formato predefinito per un URI. Quindi l'URL è un localizzatore, ma in REST è utile generalizzarlo a un identificatore di risorsa Le persone li usano in modo intercambiabile, però.)

  • Poiché la risorsa che stai cercando nel tuo esempio è la raccolta di lavori, ha senso cercare

OTTIENI sito / posti di lavoro? Type = blah & location = qui & etc = etc

(ritorno) {jobs: [{job: ...}]}

Quindi usa POST, che è il verbo append o process per aggiungere nuovi elementi a quella raccolta:

Sito / lavori POST

{lavoro: ...}

  • Si noti che è la stessa struttura per l' joboggetto in ogni caso. Un client può OTTENERE una raccolta di lavori, utilizzando parametri di query per restringere la ricerca e quindi utilizzare lo stesso formato per uno degli elementi per postare un nuovo lavoro. Oppure può richiedere uno di questi elementi e METTERE al suo URI per aggiornarlo.

  • Per stringhe di query veramente lunghe o complicate, la convenzione rende OK inviare quelle come richieste POST. Raggruppa i parametri della query come coppie nome / valore o oggetti nidificati in una struttura JSON o XML e invialo nel corpo della richiesta. Ad esempio, se la query contiene dati nidificati anziché un gruppo di coppie nome / valore. Le specifiche HTTP per POST lo descrivono come verbo append o process. (Se vuoi navigare su una nave da guerra attraverso una scappatoia in REST, usa POST.)

Lo userei come piano di fallback, però.

Quello che perdi quando lo fai è però a) OTTENERE è nullipotent - cioè, non cambia nulla - POST non lo è. Quindi, se la chiamata fallisce, il middleware non riproverà o memorizzerà automaticamente nella cache i risultati e 2) con i parametri di ricerca nel corpo, non è più possibile tagliare e incollare l'URI. Cioè, l'URI non è un identificatore specifico per la ricerca desiderata.

Differenziare tra "crea" da "cerca". Esistono un paio di opzioni coerenti con la pratica REST:

  • È possibile farlo nell'URI aggiungendo qualcosa al nome della raccolta, come la ricerca di lavoro anziché i lavori. Ciò significa solo che stai trattando la raccolta di ricerca come una risorsa separata.

  • Poiché la semantica di POST è sia il processo di aggiunta OR, è possibile identificare i corpi di ricerca con il payload. Come {job: ...} vs. {search: ...}. Spetta alla logica POST pubblicarla o elaborarla in modo appropriato.

È praticamente una preferenza di progettazione / implementazione. Non penso che ci sia una chiara convenzione.

Quindi, come hai già indicato, l'idea è quella di definire una risorsa di raccolta per jobs

sito / posti di lavoro

Cerca con GET + parametri query per restringere la ricerca. Le query di dati lunghe o strutturate vanno nel corpo di un POST (possibilmente in una raccolta di ricerca separata). Crea con POST da aggiungere alla raccolta. E aggiorna con PUT a un URI specifico.

(FWIW la convenzione di stile con gli URI è di usare tutte le lettere minuscole con parole separate da trattini. Ma ciò non significa che devi farlo in quel modo.)

(Inoltre, dovrei dire che dalla tua domanda, è chiaro che sei molto lontano su questa strada. Ho spiegato le cose in modo esplicito solo per allinearle, ma la tua domanda aveva già affrontato la maggior parte dei problemi semantici in questo risposta. Lo stavo solo allacciando con qualche convenzione e pratica.)


È un'idea interessante - non avrei considerato l'utilizzo del payload per differenziarlo. Sembra quasi un po 'subdolo! Ma suppongo che lo schema URI in realtà non contenga verbi: è il tipo di richiesta che definisce il verbo. Forse il payload è semanticamente più vicino al tipo di richiesta rispetto all'URI. L'unica preoccupazione è: è trasparente per un utente dell'API?
Rob Baillie,

In termini di implementazione (stiamo usando Node ed Express), potrebbe significare che routenon è possibile gestire la scelta dell'elaborazione. Dovrei dare un'occhiata a quello ...
Rob Baillie,

Ho la stessa sensazione viscerale, che separarlo dall'URI sembra più pulito. Sto andando avanti e indietro; è una chiamata di giudizio. Tuttavia, la semantica di HTTP consentirebbe di inserirlo nel corpo. Mi piace dire che REST è modellato sul World Wide Web e il WWW è stato realizzato con GET e POST.
Rob,

8

In genere utilizzo query OData, funzionano come una chiamata GET ma consentono di limitare le proprietà che vengono restituite e filtrarle.

Usi token come $select=e $filter=quindi finirai con un URI che assomiglia a questo:

/users?$select=Id,Name$filter=endswith(Name, 'Smith')

Puoi anche effettuare il paging usando $skipe $tope ordinando.

Per ulteriori informazioni, consulta OData.org . Non hai specificato quale lingua stai usando, ma se è ASP.NET, la piattaforma WebApi supporta le query OData - per altri (PHP ecc.) Ci sono probabilmente librerie che puoi usare per tradurle in query di database.


6
Un collegamento interessante e vale la pena esaminare, ma risolve il problema fondamentale descritto, che le richieste GET non supportano più di 2000 caratteri nella stringa di query ed è del tutto possibile che la query potrebbe essere molto più lunga di questa?
Rob Baillie,

@RobBaillie Non credo, in quanto è ancora una chiamata GET con una stringa di query. Suggerirei di utilizzare OData ovunque sia possibile poiché è uno standard per la query di origini dati Web e per le poche (se presenti) volte la query deve essere così complessa da non poter essere inserita in una query di 2000 caratteri, creare uno specifico endpoint a cui si effettua una chiamata GET
Trevor Pilley

Puoi spiegare il tuo approccio per un "endpoint specifico a cui fai una chiamata GET"? Come potresti immaginare che endpoint sembrerebbe?
Rob Baillie,

@RobBaillie certo - di nuovo non sono sicuro di quale tecnologia stai utilizzando, ma in ASP.NET creerei un controller specifico chiamato JobsNearMeAddedInTheLast7Dayso qualunque cosa per incapsulare la query che è troppo lunga / complessa per OData e quindi esponila solo tramite chiamate GET .
Trevor Pilley,

1
Vedo. Un altro pensiero interessante che probabilmente ha alcune gambe, anche se non sono sicuro che questo possa aiutare nel mio caso particolare: la ricerca sfaccettata con molti tipi di sfaccettatura e molti possibili valori di sfaccettatura
Rob Baillie,

5

Un approccio da considerare consiste nel considerare l'insieme di possibili query come una risorsa di raccolta, ad es /jobs/filters.

POSTrichieste a questa risorsa, con i parametri di query nel corpo, sarà o creare una nuova risorsa o identificare un filtro equivalente esistente e restituire un URL contenente il suo ID: /jobs/filters/12345.

L'ID può quindi essere utilizzato in una richiesta GET per i lavori: /jobs?filter=12345. Le GETrichieste successive sulla risorsa filtro restituiranno la definizione del filtro.

Questo approccio ha il vantaggio di liberarti dal formato dei parametri della query per la definizione del filtro, potenzialmente offrendoti più potenza per definire filtri complessi. Le condizioni OR sono un esempio a cui riesco a pensare che sono difficili da realizzare con le stringhe di query.

Uno svantaggio di questo approccio è la perdita della leggibilità dell'URL (sebbene ciò possa essere attenuante recuperando la definizione tramite una GETrichiesta per la risorsa filtro). Per questo motivo, potresti anche voler supportare lo stesso o un sottoinsieme dei parametri di query sulla /jobsrisorsa come supporteresti per una risorsa di filtro. Questo potrebbe essere usato per query più brevi. Se viene fornita questa funzione, al fine di mantenere la cache tra i due tipi di filtro, quando si utilizzano i parametri di query sulla /jobsrisorsa, l'implementazione dovrebbe creare / riutilizzare internamente una risorsa di filtro e restituire uno 302o lo 303stato che indica l'URL sotto forma di /jobs?filter=12345.


La mia prima reazione a questo è che, sebbene siano buone informazioni, in realtà è solo una variazione della risposta fornita da @burninggramma. In sostanza si tratta di "creare una nuova entità chiamata filtro / ricerca, chiamare per crearlo e quindi chiamare per recuperarlo". La variazione è che la chiamata per recuperarla è più simile a una chiamata per applicarla a una raccolta. Interessante. Tuttavia, sia la tua risposta che quella del burninggramma soffrono dello stesso problema: non desidero creare i filtri. Ce ne sarà un numero enorme, e non devono essere archiviati se non per mantenere un'implementazione RESTful.
Rob Baillie,

2
Ovviamente, i parametri di query sono la soluzione migliore, ma la tua domanda chiede in particolare come gestire le definizioni dei filtri più a lungo del limite di URL imposto da alcuni server. Per aggirare il limite di lunghezza dovrai comprimere la stringa di query in qualche modo o devi usare un metodo di richiesta che supporti la specifica di un corpo di lunghezza arbitraria. Se non si desidera trattare i filtri come una risorsa, è sufficiente supportare un'interfaccia non riposante in cui le definizioni dei filtri sono POST. Perderai la cache, ma se i tuoi dati sono abbastanza volatili non trarrebbero alcun beneficio dalla memorizzazione nella cache.
pgraham,

Puoi superare la necessità di memorizzare i filtri semplicemente ... non memorizzandoli. Nulla di REST garantisce che sia persistente. Potresti fare una richiesta GET /jobs/37e ricevere un risultato, quindi qualcuno elimina la risorsa e 2 secondi dopo la stessa richiesta restituisce un 404. Allo stesso modo se tu POST /searchese tu sei reindirizzato a un risultato di ricerca (la ricerca viene creata e ricevi 201 con Intestazione della posizione della risorsa), 2 secondi dopo tale risultato può essere cancellato dalla memoria e deve essere rigenerato. Non è necessario uno stoccaggio a lungo termine.
Stevendesu,

5

Questa è una vecchia risposta, ma posso ancora contribuire un po 'alla discussione. Ho osservato molto spesso un equivoco di REST, RESTful e Architecture. RESTful non parla mai di NON costruire la ricerca, non c'è nulla in RESTful sull'architettura, è un insieme di principi o criteri di progettazione.

Per descrivere una ricerca in modo migliore, dobbiamo parlare di un'architettura in particolare e quella che si adatta meglio è l'architettura orientata alle risorse (ROA).

In RESTful ci sono dei principi da progettare, idempotente non significa che il risultato non può cambiare come ho letto in alcune risposte, significa che il risultato di una richiesta indipendente non dipende da quante volte viene eseguito. Può cambiare, immaginiamo che aggiorni continuamente un database alimentandolo con alcuni dati forniti da un'API RESTful, l'esecuzione dello stesso GET potrebbe modificare il risultato ma non dipende da quante volte è stato eseguito. Se sono in grado di congelare il mondo, significa che non c'è stato, trasformazione, nulla all'interno del servizio quando richiedo la risorsa che porta a un risultato diverso.

Per definizione, una risorsa è tutto ciò che è importante da riferirsi come una cosa da sola.

In un'architettura orientata alle risorse (chiamiamola ROA d'ora in poi per brevità) ci concentriamo sulla risorsa che potrebbe essere un sacco di cose:

  • Una versione di un documento
  • L'ultima versione aggiornata del documento
  • Un risultato proveniente da una ricerca
  • Un elenco di oggetti
  • Il primo articolo che ho comprato da un e-commerce

Ciò che lo rende unico in termini di risorse è l' addestrabilità, il che significa che ha un solo URI

In questo modo la ricerca si adatta perfettamente a RESTful considerando il ROA . Dobbiamo usare GET perché presumo che la tua ricerca sia una ricerca normale e non cambi nulla, quindi è idempotente (anche se restituisce cose diverse a seconda dei nuovi elementi aggiunti). Qui c'è una confusione in questo modo perché potrei attenermi a RESTful e non a ROA, significa che potrei seguire uno schema che crea una ricerca e restituire cose diverse con gli stessi parametri perché non sto usando il principio di indirizzabilità di ROA. Come va? Bene, se invii i filtri di ricerca nel corpo o nell'intestazione la risorsa non è INDIRIZZABILE.

Puoi trovare i principi di cosa è esattamente e URI nel documento originale W3:

https://www.w3.org/DesignIssues/Axioms

Qualsiasi URL in questa architettura deve essere auto-descrittivo. È necessario se segui i principi per indirizzare qualsiasi cosa nell'URI, significa che puoi usare / (barra) per separare tutto ciò di cui hai bisogno o interrogare i parametri. Sappiamo che ci sono delle limitazioni ma questo è il modello di architettura.

Seguendo il modello ROA in RESTful una ricerca non è più di qualsiasi altra risorsa, l'unica differenza è che le risorse provengono da un calcolo anziché da una relazione diretta con l'oggetto stesso. Sulla base del principio ho potuto affrontare e ottenere un semplice servizio di calcolo aritmetico basato sul seguente schema:

http://myapi.com/sum/1/2

Dove somma, 1 e 2 possono essere modificati ma il risultato del calcolo è unico ed è indirizzabile, ogni volta che chiamo con gli stessi parametri ottengo lo stesso e nulla cambia nel servizio. Il resouce / sum / 1/2 e / substract / 5/4 aderiscono perfettamente ai principi.


3

OTTIENI va bene, se hai una raccolta statica che restituisce sempre gli stessi risultati (rappresentazione) per un URI. Ciò implica anche che i dati che generano queste rappresentazioni non vengono mai modificati. L'origine è un database di sola lettura.

Il fatto che GET restituisca risultati diversi per lo stesso URI viola l' idempotenza / sicurezza e il principio CoolURI e di conseguenza non è RESTful . È possibile che verbi idempotenti scrivano in un database, ma non devono mai influire sulla rappresentazione.

Una ricerca comune inizia con una richiesta POST che restituisce un riferimento al risultato. Genera il risultato (è nuovo e può essere recuperato con un GET successivo). Questo risultato può essere gerarchico (ulteriori riferimenti con URI che puoi OTTENERE), ovviamente, e potrebbe riutilizzare elementi di ricerche precedenti, se ha senso per l'applicazione.

A proposito, so che le persone lo fanno diversamente. Non devi spiegarmi quanto può essere conveniente violare REST.


Aaaaaaaah - quindi è così che dovrebbe funzionare! Grazie!
Rob Baillie,

1
L'idempotenza non significa che deve sempre restituire esattamente lo stesso, deve restituire lo stesso se NIENTE cambia. La ricerca può essere considerata il risultato di un calcolo ed è una risorsa stessa.
Maximiliano Rios

L'idempotenza in realtà significa che il risultato rimane lo stesso. È possibile ed è possibile utilizzare il controllo della cache. E ovviamente puoi usare DELETE che interferisce con i GET successivi. Se, tuttavia, un agente deve mantenere la conoscenza del funzionamento interno dell'applicazione, non è più RESTful. Sopra, stavo parlando dell'idea più estrema di REST. In pratica, le persone possono violarne molti aspetti. Stanno pagando il prezzo quando le cache non vengono più memorizzate nella cache in modo efficiente.
Martin Sugioarto

"L'idempotenza effettivamente significa che il risultato rimane lo stesso." ... dopo la richiesta. il punto, credo, è che la richiesta non modifica i dati.
AndreiMotinga,
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.