POST HTTP con parametri di query URL & # 8212; buona idea o no? [chiuso]

StackOverflow https://stackoverflow.com/questions/611906

  •  03-07-2019
  •  | 
  •  

Domanda

Sto progettando un'API per andare su HTTP e mi chiedo se usare il comando HTTP POST, ma con solo i parametri di query URL e nessun corpo di richiesta, sia un buon modo di procedere.

Considerazioni:

  • " Buon design web " richiede che le azioni non idempotenti vengano inviate tramite POST. Questa è un'azione non idempotente.
  • È più semplice sviluppare ed eseguire il debug di questa app quando i parametri della richiesta sono presenti nell'URL.
  • L'API non è destinata a un uso diffuso.
  • Sembra che fare una richiesta POST senza corpo richiederà un po 'più di lavoro, ad es. un'intestazione Content-Length: 0 deve essere esplicitamente aggiunta.
  • Mi sembra anche che un POST senza body sia un po 'contrario alle aspettative della maggior parte dei framework HTTP e degli sviluppatori.

Ci sono più insidie ??o vantaggi nell'invio di parametri su una richiesta POST tramite la query URL anziché il corpo della richiesta?

Modifica: il motivo per cui questo è in considerazione è che le operazioni non sono idempotenti e hanno effetti collaterali diversi dal recupero. Vedi le specifiche HTTP :

  

In particolare, la convenzione è stata   stabilito che GET e HEAD   i metodi NON DOVREBBERO avere il   significato di intraprendere un'azione diversa   di recupero. Questi metodi dovrebbero   essere considerato "sicuro". Questo consente all'utente   agenti per rappresentare altri metodi,   come POST, PUT e DELETE, in a   modo speciale, in modo che l'utente sia fatto   consapevole del fatto che un possibile   azione non sicura richiesta.

     

...

     

I metodi possono anche avere la proprietà di   & Quot; idempotence " in quello (a parte   errori o problemi di scadenza)   effetti collaterali di N > 0 identico   le richieste sono le stesse di una singola   richiesta. I metodi GET, HEAD, PUT   e DELETE condividono questa proprietà. Anche,   i metodi OPZIONI e TRACCIA DOVREBBERO   NON ha effetti collaterali, e così sono   intrinsecamente idempotente.

È stato utile?

Soluzione

Se la tua azione non è idempotente, allora DEVI utilizzare POST . In caso contrario, stai solo chiedendo problemi lungo la linea. I metodi GET , PUT e DELETE sono richiesti per essere idempotenti. Immagina cosa accadrebbe nella tua applicazione se il client stesse pre-recuperando ogni possibile GET richiesta per il tuo servizio - se ciò causasse effetti collaterali visibili al client, allora qualcosa non va.

Sono d'accordo che l'invio di un POST con una stringa di query ma senza un corpo sembri strano, ma penso che possa essere appropriato in alcune situazioni.

Pensa alla parte della query di un URL come un comando alla risorsa per limitare l'ambito della richiesta corrente. In genere, le stringhe di query vengono utilizzate per ordinare o filtrare una richiesta GET (come ? Page = 1 & amp; sort = title ) ma suppongo abbia senso su un POST per limitare anche l'ambito (forse come ? action = delete & amp; id = 5 ).

Altri suggerimenti

Tutti hanno ragione: attenersi al POST per richieste non idempotenti.

Che dire dell'utilizzo sia di una stringa di query URI sia di richiesta contenuto? Bene, è un HTTP valido (vedi nota 1), quindi perché no!

È anche perfettamente logico: gli URL, inclusa la parte della stringa di query, servono per localizzare risorse. Mentre i verbi del metodo HTTP (POST - e il suo contenuto di richiesta facoltativo) servono per specificare le azioni o cosa fare con delle risorse. Quelle dovrebbero essere preoccupazioni ortogonali. (Ma non sono meravigliosamente preoccupazioni ortogonali per il caso speciale di ContentType = application / x-www-form-urlencoded, vedere la nota 2 di seguito.)

Nota 1: la specifica HTTP (1.1) non afferma che i parametri e il contenuto della query si escludono a vicenda per un server HTTP che accetta richieste POST o PUT. Quindi qualsiasi server è libero di accettare entrambi. Cioè se scrivi il server non c'è nulla che ti impedisca di scegliere di accettare entrambi (tranne forse un framework non flessibile). In genere, il server può interpretare le stringhe di query in base alle regole che desidera. Può persino interpretarli con una logica condizionale che fa riferimento anche ad altre intestazioni come Content-Type, che porta alla Nota 2:

Nota 2: se un browser web è il modo principale in cui le persone accedono alla tua applicazione web e application / x-www-form-urlencoded è il Content-Type stanno pubblicando, quindi dovresti seguire le regole per quel tipo di contenuto. E le regole per application / x-www-form-urlencoded sono molto più specifiche (e francamente, inusuali): in questo caso è necessario interpretare l'URI come un insieme di parametri e non come una posizione delle risorse. [Questo è lo stesso punto di utilità sollevato da Powerlord; che potrebbe essere difficile utilizzare i moduli Web per pubblicare il contenuto sul server. Ho solo spiegato un po 'diversamente.]

Nota 3: a cosa servono originariamente le stringhe di query? RFC 3986 definisce le stringhe di query HTTP come una parte URI che funziona come un modo non gerarchico di localizzare una risorsa.

Nel caso in cui i lettori che fanno questa domanda desiderano porre ciò che è buona architettura RESTful: il modello di architettura RESTful non richiede schemi URI per funzionare in un modo specifico. L'architettura RESTful si occupa di altre proprietà del sistema, come la memorizzazione nella cache delle risorse, la progettazione delle risorse stesse (comportamento, capacità e rappresentazioni) e se l'idempotenza è soddisfatta. O in altre parole, ottenere un design altamente compatibile con il protocollo HTTP e il suo set di verbi del metodo HTTP. :-) (In altre parole, l'architettura RESTful non è molto prescrittiva rispetto al modo in cui le risorse sono localizzate .)

Nota finale: a volte i parametri della query vengono utilizzati per altre cose, che non localizzano risorse né codificano il contenuto. Hai mai visto un parametro di query come 'PUT = true' o 'POST = true'? Queste sono soluzioni alternative per i browser che non ti consentono di utilizzare i metodi PUT e POST. Mentre tali parametri sono visti come parte della stringa di query dell'URL (sul filo), sostengo che non fanno parte della query dell'URL nello spirito .

Vuoi delle ragioni? Eccone uno:

Non è possibile utilizzare un modulo Web per inviare una richiesta a una pagina che utilizza un mix di GET e POST. Se si imposta il metodo del modulo su GET, tutti i parametri si trovano nella stringa della query. Se imposti il ??metodo del modulo su POST, tutti i parametri si trovano nel corpo della richiesta.

Fonte: HTML 4.01 standard, sezione 17.13 Invio modulo

Da un punto di vista programmatico, per il cliente è impacchettare i parametri e aggiungerli all'URL e condurre un POST contro un GET. Sul lato server, sta valutando i parametri in entrata dalla stringa di query anziché dai byte postati. Fondamentalmente, è un lavaggio.

Dove potrebbero esserci vantaggi / svantaggi nel modo in cui piattaforme client specifiche funzionano con le routine POST e GET nel loro stack di rete, nonché in che modo il server Web gestisce tali richieste. A seconda dell'implementazione, un approccio può essere più efficiente dell'altro. Sapere che guiderebbe la tua decisione qui.

Tuttavia, dal punto di vista di un programmatore, preferisco consentire un POST con tutti i parametri nel corpo o un GET con tutti i parametri sull'URL e ignorare esplicitamente i parametri dell'URL con qualsiasi richiesta POST. Evita la confusione.

Penso che potrebbe essere ancora abbastanza RESTful avere argomenti di query che identificano la risorsa sull'URL mantenendo il payload del contenuto confinato al corpo POST. Ciò sembrerebbe separare le considerazioni di "Cosa sto inviando?" contro " A chi lo sto inviando? " ;.

Il REST hanno alcuni principi guida che possiamo usare per standardizzare il nostro modo di usare Verbi HTTP. Ciò è utile quando si creano API RESTful mentre si sta eseguendo.

In breve: GET deve essere di sola lettura, ovvero non ha alcun effetto sullo stato del server. POST viene utilizzato per creare una risorsa sul server. PUT viene utilizzato per aggiornare o creare una risorsa. DELETE viene utilizzato per eliminare una risorsa.

In altre parole, se l'azione dell'API modifica lo stato del server, REST ci consiglia di utilizzare POST / PUT / DELETE, ma non GET.

Gli interpreti di solito capiscono che fare più POST è un male e lo mettono in guardia, perché lo scopo di POST è quello di alterare lo stato del server (es. pagare la merce alla cassa), e probabilmente non vorrai farlo due volte !

Confronta con un GET che puoi fare spesso come preferisci (idempotente).

Sono d'accordo - probabilmente è più sicuro utilizzare una richiesta GET se stai solo passando i dati nell'URL e non nel corpo. Vedi questa domanda simile per alcune visualizzazioni aggiuntive sul intero concetto POST + GET.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top