http - tutorial - servicios rest ejemplo
¿Cómo puedo lidiar con las limitaciones de longitud de cadena de consulta HTTP GET y aún quiero ser RESTful? (7)
Como se indica en http://www.boutell.com/newfaq/misc/urllength.html , la cadena de consulta HTTP tiene una longitud limitada. Puede ser limitado por el cliente (Firefox, IE, ...), el servidor (Apache, IIS, ...) o el equipo de red (cortafuegos aplicativo, ...).
Hoy me enfrento a este problema con un formulario de búsqueda. Desarrollamos un formulario de búsqueda con muchos campos, y este formulario se envía al servidor como una solicitud GET, por lo que puedo marcar la página resultante.
Tenemos tantos campos que nuestra cadena de consulta tiene 1100 bytes de longitud, y tenemos un servidor de seguridad que elimina las solicitudes HTTP GET con más de 1024 bytes. Nuestro administrador del sistema nos recomienda utilizar POST en su lugar, por lo que no habrá ninguna limitación.
Claro, el POST funcionará, pero realmente siento una búsqueda como un GET y no como un POST. Así que creo que revisaré nuestros nombres de campo para garantizar que la cadena de consulta no sea demasiado larga, y si no puedo, seré pragmático y usaré POST.
¿Pero hay un defecto en el diseño de los servicios RESTful? Si tenemos una longitud limitada en la solicitud GET, ¿cómo puedo hacer para enviar objetos grandes a un servicio web RESTful? Por ejemplo, si tengo un programa que hace cálculos basados en un archivo, y deseo proporcionar un servicio web RESTful como este: http://compute.com?content=<base64 file>
. Esto no funcionará porque la cadena de consulta no tiene longitud ilimitada.
Estoy un poco desconcertado ...
5 años después, parece existir otra opción viable: use el cuerpo del mensaje GET
. Incluyo esta respuesta como una alternativa a todas las sugerencias anteriores, a pesar de que tiene sus propias limitaciones (investigue un poco).
En cuanto a su ejemplo: http://compute.com?content={base64file}
, usaría POST porque está cargando "algo" para computar. Para mí, este "algo" se siente más como un recurso como un parámetro simple.
En contraste con esto en la búsqueda habitual, comenzaría a seguir con GET y parámetros. Haces que sea mucho más fácil para los APIs probar y jugar con tu API. Haga que el acceso de solo lectura (que en la mayoría de los casos es la mayoría del tráfico) sea lo más simple posible.
Pero el dilema de las cadenas de consulta grandes es una limitación válida de GET. Aquí iría pragmático, siempre y cuando no alcances este límite, ve con GET y url-params. Esto funcionará en el 98% de los casos de búsqueda. Solo actúe si alcanza este límite y luego también introduce POST con carga útil (con tipo Content-Type: application/x-www-form-urlencoded
).
¿Tienes más ejemplos del mundo real?
Esta es una fácil. Use POST. HTTP no impone un límite en la longitud de la URL para GET, pero los servidores sí lo hacen. Sea pragmático y trabaje con un POST.
También podría usar un cuerpo GET (que está permitido) pero eso es un doble golpe en cuanto a que no es el uso correcto y probablemente tenga problemas en el servidor.
La confusión en torno a GET es una limitación del navegador. Si está creando una interfaz RESTful para una aplicación A2A o P2P, entonces no hay ninguna limitación para la longitud de su GET.
Ahora, si desea utilizar un navegador para ver su interfaz RESTful (también conocido como desarrollo / depuración), entonces se encontrará con este límite, pero existen herramientas para evitarlo.
La especificación HTTP realmente aconseja utilizar POST cuando envía datos a un recurso para su cálculo.
Su búsqueda parece un cálculo, no un recurso en sí mismo. Lo que podría hacer si aún desea que sus resultados de búsqueda sean un recurso es crear un token para identificar ese resultado de búsqueda específico y redirigir el agente de usuario a ese recurso.
A continuación, puede eliminar los tokens de resultados de búsqueda después de un período de tiempo.
Ejemplo
POST /search
query=something&category=c1&category=c2&...
201 Created
Location: /search/01543164876
entonces
GET /search/01543164876
200 Ok
... your results here...
De esta forma, los navegadores y los proxies aún pueden almacenar en caché los resultados de búsqueda, pero usted está enviando los parámetros de su consulta utilizando POST.
EDITAR
Para una aclaración, 01543164876
aquí representa una identificación única para el recurso que representa su búsqueda. Esas 2 solicitudes básicamente significan: crear un nuevo objeto de búsqueda con estos criterios, luego recuperar los resultados asociados con el objeto de búsqueda creado.
Esta ID puede ser una ID única generada para cada nueva solicitud. Esto significa que su servidor perderá objetos de "búsqueda" y tendrá que limpiarlos regularmente con una estrategia de almacenamiento en caché.
O puede ser un hash de todos los criterios de búsqueda que realmente representan la búsqueda realizada por el usuario. Esto le permite reutilizar los ID ya que volver a crear una búsqueda devolverá un ID existente que puede (o no) ya estar en caché.
REST es una manera de hacer las cosas, no un protocolo. Incluso si no te gusta POST cuando realmente es un GET, funcionará.
Si debe / debe permanecer con la definición "estándar" de GET, POST, etc. que tal vez considere realizar una consulta POST, esa consulta se almacenará en el servidor con un id de consulta y solicitará la consulta más adelante con GET por id.
Según su descripción, en mi humilde opinión debe usar un POST. POST es para poner datos en el servidor y, en algunos casos, obtener una respuesta. En su caso, realiza una búsqueda (envía una consulta al servidor) y obtiene el resultado de esa búsqueda (recupera el resultado de la consulta).
La definición de GET dice que se debe usar para recuperar un recurso ya existente. Por definición, POST es crear un nuevo recurso. Esto es exactamente lo que está haciendo: crear un recurso en el servidor y recuperarlo. Incluso si no almacena el resultado de búsqueda, creó un objeto en el servidor y lo recuperó. Como dijo PeterMmm previsiblemente, puede hacer esto con un POST (crear y almacenar el resultado de la consulta) y luego usar un GET para recuperar la consulta, pero es más práctico hacer solo un POST y recuperar el resultado.
¡Espero que esto ayude! :)