¿Cómo encajan las búsquedas en una interfaz RESTful?


137

Al diseñar una interfaz RESTful, la semántica de los tipos de solicitud se considera vital para el diseño.

  • GET - Lista de colección o elemento de recuperación
  • PUT - Reemplazar colección o elemento
  • POST - Crear colección o elemento
  • BORRAR - Bueno, erm, eliminar colección o elemento

Sin embargo, esto no parece cubrir el concepto de "búsqueda".

Por ejemplo, al diseñar un conjunto de servicios web que admiten un sitio de búsqueda de empleo, es posible que tenga los siguientes requisitos:

  • Obtener anuncio de trabajo individual
    • Llegar adomain/Job/{id}/
  • Crear anuncio de trabajo
    • Publicar endomain/Job/
  • Actualizar anuncio de trabajo
    • PONER adomain/Job/
  • Eliminar anuncio de trabajo
    • BORRAR adomain/Job/

"Obtener todos los trabajos" también es simple:

  • Llegar adomain/Jobs/

Sin embargo, ¿cómo cae el trabajo "búsqueda" en esta estructura?

Usted podría reclamar que es una variación de "colección de listas" y poner en práctica como:

  • Llegar adomain/Jobs/

Sin embargo, las búsquedas pueden ser complejas y es completamente posible producir una búsqueda que genere una cadena GET larga. Es decir, haciendo referencia a una pregunta SO aquí , hay problemas al usar cadenas GET de más de aproximadamente 2000 caracteres.

Un ejemplo podría estar en una búsqueda facetada, continuando con el ejemplo de "trabajo".

Puedo permitir la búsqueda en facetas: "Tecnología", "Título del trabajo", "Disciplina", así como palabras clave de texto libre, edad del trabajo, ubicación y salario.

Con una interfaz de usuario fluida y una gran cantidad de tecnologías y títulos de trabajo, es factible que una búsqueda abarque una gran cantidad de opciones de facetas.

Ajusta este ejemplo a CV, en lugar de trabajos, trae aún más facetas, y puedes imaginar fácilmente una búsqueda con un centenar de facetas seleccionadas, o incluso solo 40 facetas, cada una de las cuales tiene 50 caracteres (por ejemplo, títulos de trabajo, nombres de universidades, Nombres del empleador).

En esa situación, puede ser conveniente mover un PUT o POST para garantizar que los datos de búsqueda se envíen correctamente. P.ej:

  • Publicar endomain/Jobs/

Pero semánticamente esa es una instrucción para crear una colección.

También podría decir que expresará esto como la creación de una búsqueda:

  • Publicar endomain/Jobs/Search/

o (como lo sugiere el burninggramma a continuación)

  • Publicar endomain/JobSearch/

Semánticamente parece tener sentido, pero en realidad no estás creando nada, estás haciendo una solicitud de datos.

Entonces, semánticamente es un GET , pero no se garantiza que GET respalde lo que necesita.

Entonces, la pregunta es: tratando de mantenerme tan fiel al diseño RESTful como sea posible, mientras me aseguro de mantenerme dentro de las limitaciones de HTTP, ¿cuál es el diseño más apropiado para una búsqueda?


3
A menudo intento usar GET domain/Jobs?keyword={keyword} . Esto funciona bien para mí :) Mi esperanza es que el SEARCHverbo se convierta en un estándar. programmers.stackexchange.com/questions/233158/…
Knerd

Sí, puedo ver que para un ejemplo trivial no hay problema. Pero en la herramienta que estamos construyendo, en realidad no es tan increíble que terminemos con una búsqueda compleja que da como resultado una cadena GET de más de 2000 caracteres. ¿Entonces que?
Rob Baillie

En realidad un muy buen punto. ¿Qué hay de especificar una tecnología de compresión?
Knerd

2
GET con un cuerpo está permitido por la especificación HTTP, puede o no ser compatible con middleware (a veces no);) y no es una práctica preferida. Esto aparece en Stackexchange periódicamente. stackoverflow.com/questions/978061/http-get-with-request-body
Rob

2
Terminé haciendo que POST JobSearch creara una entidad de búsqueda real y devolviera un jobSearchId. Entonces OBTENER trabajos? JobSearch = jobSearchId devuelve la colección de trabajos real.
Cerad

Respuestas:


93

No debe olvidar que las solicitudes GET tienen algunas ventajas superiores sobre otras soluciones:

1) Las solicitudes GET pueden copiarse desde la barra de URL, son digeridas por los motores de búsqueda, son "amigables". Donde "amigable" significa que normalmente una solicitud GET no debe modificar nada dentro de su aplicación (idempotente) . Este es el caso estándar para una búsqueda.

2) Todos estos conceptos son muy importantes no solo desde el usuario y el motor de búsqueda, sino desde un punto de vista arquitectónico y de diseño de API .

3) Si crea una solución alternativa con POST / PUT , tendrá problemas en los que no está pensando en este momento. Por ejemplo, en el caso de un navegador, el botón de navegación hacia atrás / actualizar página / historial. Esto se puede resolver, por supuesto, pero será otra solución, luego otra y otra ...

Considerando todo esto, mi consejo sería:

a) Debería poder adaptarse a su GET utilizando una estructura de parámetros inteligente . En el caso extremo, incluso puede optar por tácticas como esta búsqueda de Google, donde configuré muchos parámetros, pero es una URL muy corta.

b) Cree otra entidad en su aplicación como JobSearch . Suponiendo que tenga tantas opciones, es probable que también necesite almacenar estas búsquedas y administrarlas, por lo que solo está limpiando su aplicación. Puede trabajar con los objetos JobSearch como una entidad completa, lo que significa que puede probarlo / usarlo más fácilmente .


Personalmente, trataría de luchar con todas mis garras para lograrlo con a) y cuando se pierda toda esperanza, me arrastraría de regreso con lágrimas en los ojos a la opción b) .


44
Para aclarar, esta pregunta tiene como objetivo el diseño de servicios web, no el diseño de sitios web. Entonces, si bien el comportamiento del navegador es de interés en el alcance más amplio de la interpretación de la pregunta, en el caso particular descrito no tiene ninguna consecuencia. (punto interesante sin embargo).
Rob Baillie

@RobBaillie Ye, el navegador fue solo un caso de uso. Quería expresar el hecho de que su búsqueda en su conjunto está representada por una cadena de URL. Lo que tiene mucha comodidad en la usabilidad junto con otros puntos más adelante en la respuesta.
p1100i

En el punto b, ¿es esta una variación simple de mi propia referencia a un POST para domain/Jobs/Search/, tal vez con en su domain/JobsSearch/lugar, o quiso decir algo diferente? ¿Puedes aclarar?
Rob Baillie

77
¿Por qué tengo la impresión de que REST es a menudo parte del problema, en lugar de parte de la solución?
JensG

1
"La solicitud GET no debe modificar nada dentro de su aplicación (idempotente)" mientras que GET es idempotente, la palabra relevante es " segura " aquí. Idempotente significa que hacer GET en un recurso dos veces es lo mismo que hacer GET en ese recurso una vez. PUT también es idempotente, pero no seguro, por ejemplo.
Jasmijn

12

TL; DR: OBTENER para filtrar, POST para buscar

Hago una distinción entre filtrar los resultados de enumerar una colección frente a una búsqueda compleja. La prueba de tornasol que uso es básicamente si necesito más que filtrado (positivo, negativo o rango) . Considero que es una búsqueda más compleja que requiere POST.

Esto tiende a reforzarse cuando se piensa en lo que se devolverá. Por lo general, solo uso GET si un recurso tiene un ciclo de vida mayormente completo (PUT, DELETE, GET, collection GET) . Por lo general, en una colección GET, estoy devolviendo una lista de URI que son los recursos REST que conforman esa colección. En una consulta compleja, es posible que extraiga de varios recursos para construir la respuesta (piense en la combinación SQL) para que no envíe URI de regreso, sino datos reales. El problema es que los datos no estarán representados en un recurso, por lo que siempre tendré que devolver los datos. Esto me parece un caso claro de requerir una POST.

-

Ha pasado un tiempo y mi publicación original fue un poco descuidada, así que pensé en actualizar.

GET es la opción intuitiva para devolver la mayoría de los tipos de datos, colecciones de recursos REST, datos estructurados de un recurso, incluso cargas útiles singulares (imágenes, documentos, etc.).

POST es el método general para todo lo que no parece encajar en GET, PUT, DELETE, etc.

En este punto, creo que las búsquedas simples, el filtrado tienen sentido intuitivamente a través de GET. Las búsquedas complejas dependen de la preferencia personal, especialmente si está agregando funciones de agregación, correlaciones cruzadas (uniones), reformateadores, etc. Diría que los parámetros GET no deberían ser demasiado largos, y es una consulta grande (sin embargo, se está estructurando ) a menudo puede tener más sentido como un cuerpo de solicitud POST.

También considero el aspecto de experiencia del uso de API. En general, quiero que la mayoría de los métodos sean lo más fáciles de usar e intuitivos posible. Insertaré llamadas que son más flexibles (y, por lo tanto, más complejas) en POST y en un URI de recursos diferente, especialmente si es inconsistente con el comportamiento de otros recursos REST en la misma API.

De cualquier manera, la consistencia es probablemente más importante que si está haciendo una búsqueda en GET o POST.

Espero que esto ayude.


1
Dado que REST pretende abstraer la implementación subyacente (por ejemplo, un recurso no es necesariamente una fila en una base de datos o un archivo en un disco duro, pero podría ser cualquier cosa ) No sé si necesariamente tiene sentido usar POST sobre OBTENGA cuando se trata de realizar uniones SQL. Suponga que tiene una mesa de escuelas y una mesa de niños y quiere una clase (una escuela, varios niños). Podría definir fácilmente un recurso virtual y GET /class?queryParams. Desde la perspectiva de un usuario, la "clase" siempre fue una cosa y no tenía que hacer ninguna unión SQL extraña.
stevendesu

No hay diferencia entre "filtrar" y "buscar".
Nicholas Shanks

1
Sí, hay un filtro basado en los campos existentes. Una búsqueda puede contener patrones mucho más complejos, combinando campos, calculando valores adjecentes, etc.
user13796

@stevendesu exactamente, es por eso que uso POST para ambos (creando una búsqueda) :-)
ymajoros

@ymajoros A menos que esté guardando los términos de búsqueda y los resultados de la búsqueda en alguna parte, no sé si POST tiene sentido semánticamente. Cuando realiza una búsqueda, realiza una solicitud de información, no proporciona información nueva para retener en ningún lado.
stevendesu

10

En REST, la definición de recursos es muy amplia. Realmente, sin embargo, desea agrupar algunos datos.

  • Es útil pensar en un recurso de búsqueda como un recurso de recopilación. Los parámetros de consulta, a veces llamados la porción de búsqueda del URI, reducen el recurso a los elementos que le interesan al cliente.

Por ejemplo, el URI principal de Google apunta a un recurso de recopilación de "enlaces a cada sitio en Internet". Los parámetros de consulta reducen eso a los sitios que desea ver.

(URI = identificador universal de recursos, de los cuales URL = localizador universal de recursos, donde el conocido "http: //" es el formato predeterminado para un URI. Por lo tanto, URL es un localizador, pero en REST es bueno generalizar eso a un identificador de recurso Sin embargo, las personas los usan de manera intercambiable).

  • Dado que el recurso que está buscando en su ejemplo es la colección de trabajos, tiene sentido buscar con

OBTENER sitio / trabajos? Type = blah & location = here & etc = etc

(volver) {trabajos: [{trabajo: ...}]}

Y luego use POST, que es el verbo agregar o procesar para agregar nuevos elementos a esa colección:

Sitio POST / trabajos

{trabajo: ...}

  • Tenga en cuenta que es la misma estructura para el jobobjeto en cada caso. Un cliente puede OBTENER una colección de trabajos, utilizando parámetros de consulta para limitar la búsqueda, y luego usar el mismo formato para uno de los elementos para PUBLICAR un nuevo trabajo. O puede tomar uno de esos elementos y PONERLO en su URI para actualizarlo.

  • Para cadenas de consulta realmente largas o complicadas, la convención hace que sea correcto enviarlas como solicitudes POST. Agrupe los parámetros de la consulta como pares de nombre / valor, u objetos anidados en una estructura JSON o XML y envíelos al cuerpo de la solicitud. Por ejemplo, si su consulta tiene datos anidados en lugar de un grupo de pares de nombre / valor. La especificación HTTP para POST lo describe como el verbo anexar o procesar. (Si quieres navegar en un acorazado a través de una escapatoria en REST, usa POST).

Sin embargo, usaría eso como el plan alternativo.

Sin embargo, lo que pierde cuando hace eso es a) GET es nulipotente, es decir, no cambia nada, POST no lo es. Entonces, si la llamada falla, el middleware no volverá a intentar automáticamente ni guardará en caché los resultados, y 2) con los parámetros de búsqueda en el cuerpo, ya no podrá cortar ni pegar el URI. Es decir, el URI no es un identificador específico para la búsqueda que desea.

Para diferenciar entre "crear" de "buscar". Hay un par de opciones que son consistentes con la práctica REST:

  • Puede hacerlo en el URI agregando algo al nombre de la colección, como búsqueda de trabajo en lugar de trabajos. Eso solo significa que está tratando la colección de búsqueda como un recurso separado.

  • Dado que la semántica de POST es un proceso de agregar o OR, puede identificar cuerpos de búsqueda con la carga útil. Como {job: ...} vs. {search: ...}. Depende de la lógica POST publicarlo o procesarlo adecuadamente.

Eso es más o menos una preferencia de diseño / implementación. No creo que haya una convención clara.

Entonces, como ya ha establecido, la idea es definir un recurso de recopilación para jobs

sitio / trabajos

Busque con parámetros de consulta GET + para acotar la búsqueda. Las consultas de datos largas o estructuradas van al cuerpo de una POST (posiblemente a una colección de búsqueda separada). Cree con POST para agregar a la colección. Y actualice con PUT a un URI específico.

(FWIW, la convención de estilo con URI es usar todo en minúsculas con palabras separadas por guiones. Pero eso no significa que tenga que hacerlo de esa manera).

(Además, debería decir que a partir de su pregunta, está claro que está muy lejos en este camino. Expliqué las cosas de manera explícita solo para alinearlas, pero su pregunta ya había abordado la mayoría de los problemas semánticos en este respuesta. Solo estaba entrelazándola con un poco de convención y práctica.)


Es una idea interesante: no habría considerado usar la carga útil para diferenciar. ¡Casi parece un poco encubierto! Pero supongo que el esquema URI en realidad no contiene ningún verbo: es el tipo de solicitud que define el verbo. Tal vez la carga útil está semánticamente más cerca del tipo de solicitud que el URI. La única preocupación es: ¿Es transparente para un usuario de la API?
Rob Baillie

En términos de implementación (estamos usando Node y Express), puede significar que routerealmente no se puede manejar la elección del procesamiento. Tendría que echarle un vistazo a eso ...
Rob Baillie

Tengo el mismo presentimiento, que separarlo por URI parece más limpio. Estoy como yendo y viniendo; Es una decisión judicial. Sin embargo, la semántica de HTTP permitiría ponerlo en el cuerpo. Me gusta decir que REST sigue el modelo de la World Wide Web y que WWW se creó con GET y POST.
Rob

8

Generalmente uso consultas OData, funcionan como una llamada GET pero le permiten restringir las propiedades que se devuelven y filtrarlas.

Utiliza tokens como $select=y, $filter=por lo tanto, terminará con un URI que se parece a esto:

/users?$select=Id,Name$filter=endswith(Name, 'Smith')

También puede hacer paginación usando $skipy $topy ordenando.

Para obtener más información, visite OData.org . No ha especificado qué idioma está usando, pero si es ASP.NET, la plataforma WebApi admite consultas OData; para otros (PHP, etc.) probablemente haya bibliotecas que puede usar para traducirlas en consultas de bases de datos.


66
Un enlace interesante y vale la pena mirar, pero ¿Resuelve el problema fundamental descrito, que reciben las solicitudes no son compatibles con más de 2000 caracteres en la cadena de consulta, y es muy posible que la consulta podría ser mucho más largo que esto?
Rob Baillie

@RobBaillie No lo creo, ya que todavía es una llamada GET con una cadena de consulta. Sugeriría usar OData siempre que sea posible, ya que es un estándar para consultar fuentes de datos web y por las pocas (si es que las hay) que la consulta debe ser tan compleja que no pueda encajar en una consulta de 2000 caracteres, cree un punto final al que realiza una llamada GET
Trevor Pilley

¿Puede explicar su enfoque para un "punto final específico al que hace una llamada GET"? ¿Cómo te imaginas que se vería ese punto final?
Rob Baillie

@RobBaillie seguro, una vez más, no estoy seguro de qué tecnología está utilizando, pero en ASP.NET crearía un controlador específico llamado JobsNearMeAddedInTheLast7Dayso lo que sea para encapsular la consulta que es demasiado larga / compleja para OData y luego exponerla solo a través de llamadas GET .
Trevor Pilley

1
Veo. Otro pensamiento interesante que probablemente tiene algunas piernas, aunque no estoy seguro de que esto ayude en mi caso particular: búsqueda facetada con muchos tipos de facetas y muchos valores de facetas posibles
Rob Baillie

5

Un enfoque a considerar es tratar el conjunto de consultas posibles como un recurso de recopilación, por ejemplo /jobs/filters.

POSTpeticiones a este recurso, con los parámetros de consulta en el cuerpo, o bien se cree un nuevo recurso o identificar un filtro equivalente existente y devolver una dirección URL que contiene su ID: /jobs/filters/12345.

El ID puede ser utilizado en una petición GET de puestos de trabajo: /jobs?filter=12345. Las GETsolicitudes posteriores en el recurso de filtro devolverán la definición del filtro.

Este enfoque tiene la ventaja de que lo libera del formato de parámetro de consulta para la definición del filtro, lo que le brinda más poder para definir filtros complejos. O las condiciones son un ejemplo que puedo pensar que son difíciles de lograr con las cadenas de consulta.

Un inconveniente de este enfoque es que pierde la legibilidad de la URL (aunque esto puede mitigarse al recuperar la definición a través de una GETsolicitud del recurso de filtro). Por esta razón, es posible que también desee admitir el mismo o un subconjunto de los parámetros de consulta en el /jobsrecurso como lo haría con un recurso de filtro. Esto podría usarse para consultas más cortas. Si se proporciona esta característica, para mantener la capacidad de almacenamiento en caché entre los dos tipos de filtrado, cuando se utilizan parámetros de consulta en el /jobsrecurso, la implementación debe crear / reutilizar internamente un recurso de filtro y devolver un estado 302o 303indicando la URL en forma de /jobs?filter=12345.


Mi primera reacción a esto es que, si bien es una buena información, en realidad es solo una variación de la respuesta proporcionada por @burninggramma. Esencialmente es "crear una nueva entidad llamada filtro / búsqueda, llamar para crearla y luego llamar para recuperarla". La variación es que la llamada para recuperarlo es más como una llamada para aplicarlo a una colección. Interesante. Sin embargo, tanto su respuesta como la de Burninggramma tienen el mismo problema: no deseo crear los filtros. Habrá una gran cantidad de ellos, y no es necesario almacenarlos, excepto para mantener una implementación RESTful.
Rob Baillie

2
Obviamente, los parámetros de consulta son la mejor solución, pero su pregunta se refiere específicamente a cómo manejar las definiciones de filtro por más tiempo que el límite de URL impuesto por algunos servidores. Para evitar el límite de longitud, deberá comprimir la cadena de consulta de alguna manera o deberá utilizar un método de solicitud que admita la especificación de un cuerpo de longitud arbitraria. Si no desea tratar los filtros como un recurso, simplemente admita una interfaz que no sea tranquila donde las definiciones de filtro se PUBLICAN. Perderá la capacidad de almacenamiento en caché, pero si sus datos son lo suficientemente volátiles, de todos modos no se beneficiaría del almacenamiento en caché.
pgraham

Puede superar la necesidad de almacenar filtros simplemente ... no almacenándolos. Nada sobre REST garantiza que sea persistente. Puede solicitar GET /jobs/37y recibir un resultado, luego alguien elimina el recurso y 2 segundos después la misma solicitud devuelve un 404. De manera similar, si usted POST /searchesy usted son redirigidos a un resultado de búsqueda (la búsqueda se crea y recibe un 201 con Ubicación del encabezado del recurso), 2 segundos después, ese resultado puede borrarse de la memoria y debe regenerarse. No hay necesidad de almacenamiento a largo plazo.
stevendesu

5

Esta es una vieja respuesta, pero aún puedo contribuir un poco a la discusión. He observado muy a menudo un malentendido de REST, RESTful y Arquitectura. RESTful nunca menciona nada sobre NO construir búsqueda, no hay nada en RESTful sobre arquitectura, es un conjunto de principios o criterios de diseño.

Para describir una Búsqueda de una mejor manera, tenemos que hablar sobre una arquitectura en particular y la que mejor se adapta es la Arquitectura Orientada a Recursos (ROA).

En RESTful hay principios para diseñar, idempotente no significa que el resultado no pueda cambiar, ya que leí en algunas respuestas, significa que el resultado de una solicitud independiente no depende de cuántas veces se ejecute. Puede cambiar, imaginemos que estoy actualizando continuamente una base de datos alimentándola con algunos datos que son servidos por una API RESTful, ejecutar el mismo GET podría cambiar el resultado pero no depende de cuántas veces se haya ejecutado. Si puedo congelar el mundo, significa que no hay estado, transformación, nada dentro del servicio cuando solicito el recurso que conduce a un resultado diferente.

Por definición, un recurso es cualquier cosa importante para ser referenciada como una cosa por sí misma.

En una arquitectura orientada a recursos (llamémosle ROA de ahora en adelante por brevedad) nos enfocamos en el recurso que podría ser muchas cosas:

  • Una versión de un documento.
  • La última versión actualizada del documento.
  • Un resultado proveniente de una búsqueda
  • Una lista de objetos
  • El primer artículo que compré en un comercio electrónico.

Lo que lo hace único en términos de recursos es la capacidad de dirección, lo que significa que solo tiene un URI

De esa manera, la búsqueda encaja perfectamente en RESTful teniendo en cuenta el ROA . Tenemos que usar GET porque supongo que su búsqueda es una búsqueda normal y no cambia nada, por lo que es idempotente (incluso si devuelve cosas diferentes dependiendo de los nuevos elementos agregados). Hay una confusión aquí de esa manera porque podría apegarme a RESTful y no a ROA, significa que podría seguir un patrón que crea una búsqueda y devolver diferentes cosas con los mismos parámetros porque no estoy usando el principio de direccionamiento de ROA. ¿Como es eso? Bueno, si envía los filtros de búsqueda en el cuerpo o encabezado, el recurso no es DIRECCIONABLE.

Puede encontrar los principios de lo que es exactamente y URI en el documento original W3:

https://www.w3.org/DesignIssues/Axioms

Cualquier URL en esta arquitectura tiene que ser autodescriptiva. Es necesario si sigue los principios para abordar todo en el URI, significa que puede usar / (barra oblicua) para separar lo que necesite o consultar parámetros. Sabemos que hay limitaciones en eso, pero este es el patrón de arquitectura.

Siguiendo el patrón de ROA en RESTful, una búsqueda no es más que cualquier otro recurso, la única diferencia es que los recursos provienen de un cálculo en lugar de una relación directa con el objeto en sí. Según el principio, podría abordar y obtener un servicio de cálculo aritmético simple basado en el siguiente patrón:

http://myapi.com/sum/1/2

Donde sum, 1 y 2 pueden modificarse, pero el resultado del cálculo es único y es accesible, cada vez que llamo con los mismos parámetros obtengo lo mismo y nada cambia en el servicio. El recurso / sum / 1/2 y / substract / 5/4 se adhieren perfectamente a los principios.


3

GET está bien, si tiene una colección estática que siempre devuelve los mismos resultados (representación) para un URI. Eso también implica que los datos que generan estas representaciones nunca se alteran. La fuente es una base de datos de solo lectura.

El hecho de que GET devuelva resultados diferentes para un mismo URI viola la idempotencia / seguridad y el principio CoolURI y, en consecuencia, no es RESTful . Es posible que los verbos idempotentes escriban en una base de datos, pero nunca deben afectar la representación.

Una búsqueda común comienza con una solicitud POST que devuelve una referencia al resultado. Genera el resultado (es nuevo y se puede obtener con un GET posterior). Este resultado puede ser jerárquico (más referencias con URI que puede OBTENER), por supuesto, y podría reutilizar elementos de búsquedas anteriores, si tiene sentido para la aplicación.

Por cierto, sé que las personas lo hacen de manera diferente. No necesita explicarme lo conveniente que puede ser violar REST.


Aaaaaaaah, ¡así es como se supone que debe funcionar! ¡Gracias!
Rob Baillie

1
La idempotencia no significa que siempre debe devolver exactamente lo mismo, sino que debe devolver lo mismo si NADA cambia. La búsqueda puede considerarse el resultado de un cálculo y es un recurso en sí mismo.
Maximiliano Rios

La idempotencia realmente SIGNIFICA que el resultado sigue siendo el mismo. Puede, y es practicable, usar el control de caché. Y, por supuesto, puede usar DELETE que interfiere con GET posteriores. Sin embargo, si un agente necesita mantener conocimiento sobre el funcionamiento interno de la aplicación, ya no es RESTful. Arriba, estaba hablando de la idea más extrema de REST. En la práctica, las personas pueden violar muchos aspectos de la misma. Están pagando el precio cuando los cachés ya no se almacenan en caché de manera eficiente.
Martin Sugioarto

"La idempotencia realmente SIGNIFICA que el resultado sigue siendo el mismo" ... después de la solicitud. El punto, creo, es que la solicitud no cambia los datos.
AndreiMotinga
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.