rest - sesion - terminos de busqueda google analytics
POST HTTP con parĂ¡metros de consulta de URL: ¿buena idea o no? (7)
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:
- El "buen diseño web" requiere que las acciones no idempotentes 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á destinada a un uso generalizado.
- Parece que hacer una solicitud POST sin cuerpo requerirá un poco más de trabajo, por ejemplo, un
Content-Length: 0
debe agregarse explícitamente. - 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?
Edición: 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. Ver la especificación de HTTP :
En particular, se ha establecido la convención de que los métodos GET y HEAD NO DEBEN tener el significado 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 tenga conocimiento 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 vencimiento) los efectos secundarios de N> 0 solicitudes idénticas son los mismos que para una sola solicitud. Los métodos GET, HEAD, PUT y DELETE comparten esta propiedad. Además, los métodos OPCIONES y TRAZO NO DEBEN tener efectos secundarios, por lo que son inherentemente idempotentes.
Creo que todavía 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?" versus "¿A quién se lo envío?".
Desde un punto de vista programático, para el cliente es empaquetar los parámetros y agregarlos a la url y realizar 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 las plataformas cliente específicas trabajan 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. Sabiendo que eso guiaría tu decisión aquí.
No obstante, desde la perspectiva de un programador, prefiero permitir un 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.
El campamento REST tiene algunos principios rectores que podemos usar para estandarizar la forma en que usamos los 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 la API cambia el estado del servidor, REST nos recomienda usar POST / PUT / DELETE, pero no GET.
Los agentes de usuario generalmente entienden que hacer múltiples POSTs es malo y advertirán contra ello, porque la intención de POST es alterar el estado del servidor (por ejemplo, pagar por los productos al momento del pago), ¡y probablemente no quiera hacerlo dos veces!
Compare con un GET que puede hacer a menudo como quiera (idempotente).
Estoy de acuerdo: es probable que sea más seguro utilizar una solicitud GET si solo está pasando datos en la URL y no en el cuerpo. Vea esta pregunta similar para algunas vistas adicionales sobre todo el concepto POST + GET.
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
Si su acción no es idempotente, DEBE usar POST
. Si no lo haces, solo estás buscando problemas en la línea. GET
métodos GET
, PUT
y DELETE
deben ser idempotentes. Imagine lo que sucedería en su aplicación si el cliente estuviera obteniendo todas las solicitudes GET
posibles para 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 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 utilizan para ordenar o filtrar una solicitud GET
(como ?page=1&sort=title
), pero supongo que en una POST
también tiene sentido limitar el alcance (tal vez como ?action=delete&id=5
).
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 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 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 de consulta y el contenido sean mutuamente excluyentes 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 quizás 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 están publicando, 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 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 URI que funciona como una forma no jerárquica de ubicar un recurso.
En caso de que los lectores que hacen esta pregunta deseen preguntar qué es una buena arquitectura REST: el patrón de arquitectura REST 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 con la forma en que se ubican los recursos).
Nota final: a veces los parámetros de consulta se utilizan 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 su espíritu .