Estoy diseñando una API para ir sobre HTTP y me pregunto si usar el comando HTTP POST, pero solo con parámetros de consulta de URL y sin cuerpo de solicitud, es una buena manera de hacerlo.
Consideraciones:
- El "buen diseño web" requiere que se envíen acciones no idempotentes a través de POST. Esta es una acción no idempotente.
- Es más fácil desarrollar y depurar esta aplicación cuando los parámetros de solicitud están presentes en la URL.
- La API no está destinada a un uso generalizado.
- Parece que realizar una solicitud POST sin cuerpo requerirá un poco más de trabajo, por ejemplo, se
Content-Length: 0
debe agregar explícitamente un encabezado. - También me parece que un POST sin cuerpo es un poco contrario a las expectativas de la mayoría de los desarrolladores y los marcos HTTP.
¿Hay más dificultades o ventajas para enviar parámetros en una solicitud POST a través de la consulta URL en lugar del cuerpo de la solicitud?
Editar: La razón por la que esto se está considerando es que las operaciones no son idempotentes y tienen otros efectos secundarios además de la recuperación. Ver la especificación HTTP :
En particular, la convención ha establecido que los métodos GET y HEAD NO DEBEN tener la importancia de tomar una acción que no sea la recuperación. Estos métodos deben considerarse "seguros". Esto permite a los agentes de usuario representar otros métodos, como POST, PUT y DELETE, de una manera especial, para que el usuario sea consciente del hecho de que se está solicitando una acción posiblemente insegura.
...
Los métodos también pueden tener la propiedad de "idempotencia" en que (aparte de los problemas de error o caducidad) los efectos secundarios de N> 0 solicitudes idénticas son las mismas que para una solicitud única. Los métodos GET, HEAD, PUT y DELETE comparten esta propiedad. Además, los métodos OPTIONS y TRACE NO DEBEN tener efectos secundarios, por lo que son inherentemente idempotentes.
Respuestas:
Si su acción no es idempotente, DEBE usarla
POST
. Si no lo hace, solo está pidiendo problemas en el futuro.GET
,PUT
yDELETE
se requieren métodos para ser idempotentes. Imagine lo que sucedería en su aplicación si el cliente buscara previamente todas lasGET
solicitudes posibles de su servicio; si esto causara efectos secundarios visibles para el cliente, entonces algo está mal.Estoy de acuerdo en que enviar un
POST
con una cadena de consulta pero sin un cuerpo parece extraño, pero creo que puede ser apropiado en algunas situaciones.Piense en la parte de consulta de una URL como un comando del recurso para limitar el alcance de la solicitud actual. Por lo general, las cadenas de consulta se usan para ordenar o filtrar una
GET
solicitud (me gusta?page=1&sort=title
), pero supongo que tiene sentidoPOST
limitar también el alcance (tal vez me gusta?action=delete&id=5
).fuente
/action?response_format=json
)Todos tienen razón: quédese con POST para solicitudes no idempotentes.
¿Qué pasa con el uso de una cadena de consulta URI y contenido de solicitud? Bueno, es HTTP válido (ver nota 1), ¿por qué no?
También es perfectamente lógico: las URL, incluida su parte de cadena de consulta, son para localizar recursos. Mientras que los verbos del método HTTP (POST - y su contenido de solicitud opcional) son para especificar acciones o qué hacer con los recursos. Esas deberían ser preocupaciones ortogonales. (Pero, no son preocupaciones maravillosamente ortogonales para el caso especial de ContentType = application / x-www-form-urlencoded, vea la nota 2 a continuación).
Nota 1: la especificación HTTP (1.1) no establece que los parámetros de consulta y el contenido sean mutuamente exclusivos para un servidor HTTP que acepte solicitudes POST o PUT. Por lo tanto, cualquier servidor es libre de aceptar ambos. Es decir, si escribe el servidor, no hay nada que le impida elegir aceptar ambos (excepto tal vez un marco inflexible). Generalmente, el servidor puede interpretar cadenas de consulta de acuerdo con las reglas que desee. Incluso puede interpretarlos con lógica condicional que se refiere a otros encabezados como Content-Type también, lo que lleva a la Nota 2:
Nota 2: si un navegador web es la forma principal en que las personas acceden a su aplicación web, y application / x-www-form-urlencoded es el Tipo de contenido que publican, entonces debe seguir las reglas para ese Tipo de contenido. Y las reglas para application / x-www-form-urlencoded son mucho más específicas (y, francamente, inusuales): en este caso, debe interpretar el URI como un conjunto de parámetros, y no como una ubicación de recursos. [Este es el mismo punto de utilidad que Powerlord planteó; que puede ser difícil usar formularios web para PUBLICAR contenido en su servidor. Acabo de explicar un poco diferente.]
Nota 3: ¿para qué sirven originalmente las cadenas de consulta? RFC 3986 define cadenas de consulta HTTP como una parte de URI que funciona como una forma no jerárquica de localizar un recurso.
En caso de que los lectores que hagan esta pregunta deseen preguntar qué es una buena arquitectura RESTful: el patrón de arquitectura RESTful no requiere esquemas URI para funcionar de manera específica. La arquitectura RESTful se ocupa de otras propiedades del sistema, como la capacidad de almacenamiento en caché de los recursos, el diseño de los propios recursos (su comportamiento, capacidades y representaciones) y si se satisface la idempotencia. O, en otras palabras, lograr un diseño que sea altamente compatible con el protocolo HTTP y su conjunto de verbos de métodos HTTP. :-) (En otras palabras, la arquitectura RESTful no es muy preceptiva con la forma en que se encuentran los recursos) .
Nota final: a veces los parámetros de consulta se utilizan para otras cosas, que no son ni localizar recursos ni codificar contenido. ¿Alguna vez has visto un parámetro de consulta como 'PUT = true' o 'POST = true'? Estas son soluciones para navegadores que no le permiten usar los métodos PUT y POST. Si bien dichos parámetros se ven como parte de la cadena de consulta de URL (en el cable), sostengo que no son parte de la consulta de la URL en espíritu .
fuente
Quieres razones? Aquí hay uno:
No se puede usar un formulario web para enviar una solicitud a una página que usa una combinación de GET y POST. Si establece el método del formulario en GET, todos los parámetros están en la cadena de consulta. Si establece el método del formulario en POST, todos los parámetros están en el cuerpo de la solicitud.
Fuente: estándar HTML 4.01, sección 17.13 Envío de formularios
fuente
method
es POST, no se menciona el cambio del URI en el formularioaction
. Y, por supuesto, cualquier URI ya puede contener una parte de cadena de consulta./Books?bookCode=1234
. El servidor web obtendrá vars de formulario POST y una cadena de consulta.Desde un punto de vista programático, para el cliente está empacando parámetros y agregándolos a la url y realizando un POST frente a un GET. En el lado del servidor, está evaluando los parámetros entrantes de la cadena de consulta en lugar de los bytes publicados. Básicamente, es un lavado.
Donde podría haber ventajas / desventajas podría estar en cómo funcionan las plataformas de cliente específicas con las rutinas POST y GET en su pila de redes, así como también cómo el servidor web maneja esas solicitudes. Dependiendo de su implementación, un enfoque puede ser más eficiente que el otro. Saber eso guiaría su decisión aquí.
Sin embargo, desde la perspectiva de un programador, prefiero permitir una POST con todos los parámetros en el cuerpo o una GET con todos los parámetros en la url, e ignorar explícitamente los parámetros de la url con cualquier solicitud POST. Evita la confusión.
fuente
Creo que aún podría ser bastante RESTful tener argumentos de consulta que identifiquen el recurso en la URL mientras se mantiene la carga útil de contenido confinada al cuerpo POST. Esto parecería separar las consideraciones de "¿Qué estoy enviando?" versus "¿A quién se lo envío?".
fuente
El campamento REST tiene algunos principios rectores que podemos usar para estandarizar la forma en que usamos los verbos HTTP. Esto es útil al construir API RESTful como lo está haciendo.
En pocas palabras: GET debe ser de solo lectura, es decir, no tener ningún efecto en el estado del servidor. POST se utiliza para crear un recurso en el servidor. PUT se usa para actualizar o crear un recurso. DELETE se usa para eliminar un recurso.
En otras palabras, si su acción de API cambia el estado del servidor, REST nos aconseja usar POST / PUT / DELETE, pero no GET.
Los agentes de usuario generalmente entienden que hacer múltiples POST es malo y lo advertirán, porque la intención de POST es alterar el estado del servidor (por ejemplo, pagar los productos al momento del pago), ¡y probablemente no quieras hacerlo dos veces!
Compare con un GET que puede hacer a menudo como quiera (idempotente).
fuente
Estoy de acuerdo: probablemente sea más seguro usar una solicitud GET si solo está pasando datos en la URL y no en el cuerpo. Vea esta pregunta similar para obtener algunas vistas adicionales sobre todo el concepto POST + GET.
fuente