Estou projetando uma API para passar por HTTP e estou pensando se o uso do comando HTTP POST, mas apenas com parâmetros de consulta de URL e sem corpo de solicitação, é um bom caminho.
Considerações:
- O "bom design da Web" exige que ações não idempotentes sejam enviadas via POST. Esta é uma ação não idempotente.
- É mais fácil desenvolver e depurar este aplicativo quando os parâmetros de solicitação estão presentes no URL.
- A API não se destina ao uso generalizado.
- Parece que fazer uma solicitação POST sem corpo levará um pouco mais de trabalho, por exemplo, um
Content-Length: 0
cabeçalho deve ser explicitamente adicionado. - Também me parece que um POST sem corpo é um pouco contrário às expectativas da maioria dos desenvolvedores e estruturas HTTP.
Existem mais armadilhas ou vantagens em enviar parâmetros em uma solicitação POST por meio da consulta de URL em vez do corpo da solicitação?
Editar: A razão pela qual isso está sendo considerado é que as operações não são idempotentes e têm efeitos colaterais diferentes da recuperação. Veja a especificação HTTP :
Em particular, foi estabelecida a convenção de que os métodos GET e HEAD NÃO DEVEM ter o significado de tomar uma ação diferente da recuperação. Esses métodos devem ser considerados "seguros". Isso permite que os agentes do usuário representem outros métodos, como POST, PUT e DELETE, de uma maneira especial, para que o usuário fique ciente do fato de que uma ação possivelmente insegura está sendo solicitada.
...
Os métodos também podem ter a propriedade "idempotência", pois (além de problemas de erro ou expiração) os efeitos colaterais de N> 0 solicitações idênticas são os mesmos que para uma única solicitação. Os métodos GET, HEAD, PUT e DELETE compartilham essa propriedade. Além disso, os métodos OPTIONS e TRACE NÃO DEVEM ter efeitos colaterais e, portanto, são inerentemente idempotentes.
Respostas:
Se sua ação não for idempotente, você DEVE usar
POST
. Se não, você está apenas pedindo problemas na linha.GET
,PUT
eDELETE
métodos devem ser idempotentes. Imagine o que aconteceria no seu aplicativo se o cliente estivesse buscando previamente todas asGET
solicitações possíveis para o seu serviço - se isso causasse efeitos colaterais visíveis ao cliente, algo estaria errado.Concordo que o envio de um
POST
com uma string de consulta, mas sem um corpo, parece estranho, mas acho que pode ser apropriado em algumas situações.Pense na parte da consulta de uma URL como um comando para o recurso para limitar o escopo da solicitação atual. Normalmente, as strings de consulta são usadas para classificar ou filtrar uma
GET
solicitação (como?page=1&sort=title
), mas suponho que faça sentidoPOST
também limitar o escopo (talvez como?action=delete&id=5
).fonte
/action?response_format=json
)Todo mundo está certo: fique com o POST para solicitações não idempotentes.
Que tal usar uma sequência de consulta URI e solicitar conteúdo? Bem, é HTTP válido (veja a nota 1), então por que não ?!
Também é perfeitamente lógico: os URLs, incluindo sua parte da cadeia de caracteres de consulta, destinam-se à localização de recursos. Enquanto os verbos do método HTTP (POST - e seu conteúdo opcional de solicitação) são para especificar ações ou o que fazer com os recursos. Essas devem ser preocupações ortogonais. (Mas não são preocupações ortogonais maravilhosas para o caso especial de ContentType = application / x-www-form-urlencoded, consulte a nota 2 abaixo.)
Nota 1: A especificação HTTP (1.1) não declara que os parâmetros e o conteúdo da consulta são mutuamente exclusivos para um servidor HTTP que aceita solicitações POST ou PUT. Portanto, qualquer servidor é livre para aceitar os dois. Ou seja, se você escrever o servidor, não há nada que o impeça de optar por aceitar os dois (exceto talvez uma estrutura inflexível). Geralmente, o servidor pode interpretar as cadeias de consulta de acordo com as regras que desejar. Ele pode até interpretá-los com lógica condicional que também se refere a outros cabeçalhos como o Tipo de conteúdo, o que leva à Nota 2:
Nota 2: Se um navegador web é a principal forma as pessoas estão acessando o aplicativo web, e application / x-www-form-urlencoded é o tipo de conteúdo que eles estão postando, em seguida, você deve seguir as regras para que Content-Type. E as regras para o código application / x-www-form-url são muito mais específicas (e francamente, incomuns): nesse caso, você deve interpretar o URI como um conjunto de parâmetros, e não como um local de recurso. [Este é o mesmo ponto de utilidade que Powerlord levantou; pode ser difícil usar formulários da web para postar conteúdo no seu servidor. Apenas expliquei um pouco diferente.]
Nota 3: para que servem originalmente as strings de consulta? O RFC 3986 define cadeias de consulta HTTP como uma parte do URI que funciona como uma maneira não hierárquica de localizar um recurso.
Caso os leitores que fazem essa pergunta desejem perguntar o que é uma boa arquitetura RESTful: o padrão da arquitetura RESTful não exige que os esquemas de URI funcionem de uma maneira específica. A arquitetura RESTful se preocupa com outras propriedades do sistema, como armazenamento em cache de recursos, o design dos próprios recursos (comportamento, recursos e representações) e se a idempotência é satisfeita. Ou, em outras palavras, obter um design altamente compatível com o protocolo HTTP e seu conjunto de verbos de método HTTP. :-) (Em outras palavras, a arquitetura RESTful não é muito positiva com a localização dos recursos .)
Nota final: às vezes, os parâmetros de consulta são usados para outras coisas, que não estão localizando recursos nem codificando conteúdo. Já viu um parâmetro de consulta como 'PUT = true' ou 'POST = true'? Essas são soluções alternativas para navegadores que não permitem o uso dos métodos PUT e POST. Embora esses parâmetros sejam vistos como parte da cadeia de consulta da URL (na conexão), eu argumento que eles não fazem parte da consulta da URL em espírito .
fonte
Você quer razões? Aqui está um:
Um formulário da web não pode ser usado para enviar uma solicitação para uma página que usa uma combinação de GET e POST. Se você definir o método do formulário como GET, todos os parâmetros estarão na string de consulta. Se você definir o método do formulário como POST, todos os parâmetros estarão no corpo da solicitação.
Fonte: Padrão HTML 4.01, seção 17.13 Submissão de formulários
fonte
method
POST é, não há menção de alterar o URI no formulárioaction
. E é claro que qualquer URI já pode conter uma parte da string de consulta./Books?bookCode=1234
. O servidor da Web obterá vars de formulário POST e uma string de consulta.Do ponto de vista programático, para o cliente está empacotando parâmetros e anexando-os ao URL e conduzindo um POST versus um GET. No lado do servidor, está avaliando os parâmetros de entrada da string de consulta em vez dos bytes postados. Basicamente, é uma lavagem.
Onde pode haver vantagens / desvantagens em como plataformas específicas de clientes funcionam com as rotinas POST e GET em sua pilha de rede, bem como em como o servidor da Web lida com essas solicitações. Dependendo da sua implementação, uma abordagem pode ser mais eficiente que a outra. Saber que guiaria sua decisão aqui.
No entanto, da perspectiva de um programador, prefiro permitir um POST com todos os parâmetros no corpo ou um GET com todos os parâmetros no URL e ignorar explicitamente os parâmetros de URL com qualquer solicitação POST. Evita confusão.
fonte
Eu acho que ainda pode ser bastante RESTful ter argumentos de consulta que identifiquem o recurso na URL, mantendo a carga útil do conteúdo confinada ao corpo do POST. Isso parece separar as considerações de "O que estou enviando?" versus "Para quem estou enviando?".
fonte
O campo REST possui alguns princípios orientadores que podemos usar para padronizar a maneira como usamos verbos HTTP. Isso é útil ao criar APIs RESTful como você está fazendo.
Em poucas palavras: GET deve ser somente leitura, ou seja, não afeta o estado do servidor. POST é usado para criar um recurso no servidor. PUT é usado para atualizar ou criar um recurso. DELETE é usado para excluir um recurso.
Em outras palavras, se sua ação da API alterar o estado do servidor, o REST nos aconselha a usar POST / PUT / DELETE, mas não GET.
Os agentes de usuários geralmente entendem que fazer vários POSTs é ruim e alertam contra isso, porque a intenção do POST é alterar o estado do servidor (por exemplo, pagar por mercadorias no check-out) e você provavelmente não deseja fazer isso duas vezes!
Compare com um GET que você pode fazer quantas vezes quiser (idempotente).
fonte
Concordo - provavelmente é mais seguro usar uma solicitação GET se você estiver apenas transmitindo dados no URL e não no corpo. Veja esta pergunta semelhante para algumas visualizações adicionais sobre todo o conceito POST + GET.
fonte