POST HTTP con parámetros de consulta de URL: ¿buena idea o no? [cerrado]

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

  •  03-07-2019
  •  | 
  •  

Pregunta

Estoy diseñando una API para revisar HTTP y me pregunto si usar el comando POST de HTTP, pero solo con parámetros de consulta de URL y sin cuerpo de solicitud, es una buena manera de hacerlo.

Consideraciones:

  • " Buen diseño web " requiere que las acciones no identificadas se envíen 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á diseñada para un uso generalizado.
  • Parece que realizar una solicitud POST sin cuerpo requerirá un poco más de trabajo, por ejemplo. debe agregarse explícitamente un encabezado de Content-Length: 0 .
  • También me parece que un POST sin cuerpo es un poco contrario a las expectativas de la mayoría de desarrolladores y HTTP frameworks.

¿Hay más inconvenientes o ventajas al enviar parámetros en una solicitud POST a través de la consulta de URL en lugar del cuerpo de la solicitud?

Editar: la razón por la que esto se considera es que las operaciones no son idempotentes y tienen efectos secundarios distintos de la recuperación. Consulte la especificación de HTTP :

  

En particular, la convención ha sido   establecido que el GET y la CABEZA   los métodos NO DEBEN tener el   significado de tomar una acción de otro   que la recuperación. Estos métodos deben   ser considerado " seguro " ;. Esto permite al usuario   Agentes para representar otros métodos,   como POST, PUT y DELETE, en un   Manera especial, para que el usuario se haga.   consciente del hecho de que una posible   Se está solicitando una acción insegura.

     

...

     

Los métodos también pueden tener la propiedad de   " idempotencia " en eso (aparte de   problemas de error o vencimiento) el   efectos secundarios de N > 0 idéntico   las solicitudes son las mismas que para una sola   solicitud. Los métodos GET, HEAD, PUT   y BORRAR comparte esta propiedad. También,   Los métodos OPCIONES y TRAZADO DEBEN   NO tiene efectos secundarios, y también lo son   inherentemente idempotente.

¿Fue útil?

Solución

Si su acción no es idempotente, entonces DEBE usar POST . Si no lo haces, solo estás pidiendo problemas en la línea. Los métodos GET , PUT y DELETE son obligatorios para ser idempotentes. Imagine lo que sucedería en su aplicación si el cliente estuviera solicitando previamente cualquier solicitud de GET posible para su servicio; si esto causara efectos secundarios visibles para el cliente, entonces algo está mal.

Estoy de acuerdo en que el envío de un POST con una cadena de consulta pero sin 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 al recurso para limitar el alcance de la solicitud actual. Normalmente, las cadenas de consulta se usan para ordenar o filtrar una solicitud de GET (como ? Page = 1 & amp; sort = title ) pero supongo que tiene sentido en un POST para limitar también el alcance (tal vez como ? action = delete & amp; id = 5 ).

Otros consejos

Todo el mundo tiene razón: apégate a POST para solicitudes no idempotentes.

¿Qué pasa con el uso de una cadena de consulta URI y el contenido de la 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 ubicar 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 deben ser las preocupaciones ortogonales. (Pero, no son preocupaciones bellamente 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 y el contenido de la consulta se excluyan mutuamente para un servidor HTTP que acepte solicitudes POST o PUT. Así que 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 según las reglas que desee. Incluso puede interpretarlos con una lógica condicional que también hace referencia a otros encabezados como Content-Type, 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 Content-Type están publicando, entonces usted debería 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 enviar contenido a su servidor. Explicado un poco diferente.]

Nota 3: ¿para qué son originalmente las cadenas de consulta? RFC 3986 define las cadenas de consulta HTTP como una parte de URI que funciona como una forma no jerárquica de ubicar un recurso.

En caso de que los lectores que hacen esta pregunta quieran preguntar qué es una buena arquitectura REST: el patrón de arquitectura RESTful no requiere que los esquemas URI funcionen de una manera específica. La arquitectura REST se ocupa de otras propiedades del sistema, como el almacenamiento en caché de los recursos, el diseño de los recursos en sí (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étodo HTTP. :-) (En otras palabras, la arquitectura RESTful no es muy prescriptiva en cuanto a cómo se encuentran los recursos .)

Nota final: a veces los parámetros de consulta se usan para otras cosas, que no son la localización de recursos ni la codificación de contenido. ¿Alguna vez has visto un parámetro de consulta como 'PUT = true' o 'POST = true'? Estas son soluciones alternativas para los navegadores que no le permiten utilizar los métodos PUT y POST. Si bien estos parámetros se ven como parte de la cadena de consulta de la URL (en el cable), sostengo que no son parte de la consulta de la URL en espíritu .

¿Quieres razones? Aquí hay uno:

No se puede usar un formulario web para enviar una solicitud a una página que utiliza 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 configura el método del formulario en POST, todos los parámetros están en el cuerpo de la solicitud.

Fuente: HTML 4.01 estándar, sección 17.13 Envío de formularios

Desde un punto de vista programático, para el cliente está empaquetando los parámetros y agregándolos a la URL y realizando una POST frente a un GET. En el lado del servidor, está evaluando los parámetros de entrada 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 clientes específicas con las rutinas POST y GET en su pila de redes, así como en cómo el servidor web se ocupa de esas solicitudes. Dependiendo de su implementación, un enfoque puede ser más eficiente que el otro. Saber eso guiaría tu decisión aquí.

No obstante, desde la perspectiva de un programador, prefiero permitir una POST con todos los parámetros en el cuerpo, o un 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.

Creo que aún podría ser bastante REST. tener argumentos de consulta que identifiquen el recurso en la URL mientras se mantiene la carga útil del contenido limitada al cuerpo de la POST. Esto parece separar las consideraciones de " ¿Qué estoy enviando? & Quot; versus " ¿A quién lo envío? " ;.

El campamento REST tiene algunos principios rectores que podemos usar para estandarizar la forma en que usamos Verbos HTTP Esto es útil cuando crea API RESTful como lo está haciendo.

En pocas palabras: GET debe ser de solo lectura, es decir, no tiene efecto en el estado del servidor. POST se utiliza para crear un recurso en el servidor. PUT se utiliza para actualizar o crear un recurso. DELETE se utiliza para eliminar un recurso.

En otras palabras, si la acción de su API cambia el estado del servidor, REST nos recomienda utilizar POST / PUT / DELETE, pero no GET.

Los agentes de usuario generalmente entienden que hacer varias POST son incorrectas y advierten contra ellas, porque la intención de POST es alterar el estado del servidor (por ejemplo, pagar por los bienes en el momento del pago), y probablemente no quiera hacerlo dos veces !

Compare con un GET que puede hacer con la frecuencia que desee (idempotente).

Estoy de acuerdo: es probable que sea más seguro usar una solicitud GET si solo estás pasando datos en la URL y no en el cuerpo. Consulte esta pregunta similar para obtener algunas opiniones adicionales sobre el Todo el concepto POST + GET.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top