what specifically resourcesupport for example entre enable does diferencia create apis api rest hateoas

api - specifically - spring hal



DiseƱo de API RESTful, HATEOAS y descubrimiento de recursos (5)

En respuesta a la pregunta 1, asumo que su único punto de entrada es http://api.addressbook.com/zip_codes , y la intención es permitir al cliente recorrer toda la colección de códigos postales y finalmente recuperar las ciudades relacionadas. a ellos

En cuyo caso haría que el recurso http://api.addressbook.com/zip_codes devuelva una redirección a la primera página de códigos postales, por ejemplo:

http://api.addressbook.com/zip_codes?start=0&end=xxxx

Esto contendría una "página" de enlaces de código postal (sea cual sea el número adecuado para que el sistema lo maneje, más un enlace a la página siguiente (y la página anterior si la hay).

Esto permitiría a un cliente rastrear la lista completa de códigos postales si así lo desea.

Las direcciones URL devueltas en cada página se verían similares a esto:

http://api.addressbook.com/zip_codes/02125

Y luego sería una cuestión de decidir si incluir la información de la ciudad en la representación devuelta por una URL de código postal, o el enlace a ella dependiendo de la necesidad.

Ahora el cliente tiene la opción de recorrer la lista completa de códigos postales y luego solicitar el código postal (y luego las ciudades) para cada uno, o solicitar una página de códigos postales, y luego solicitar información detallada a un parti

Una de las ideas centrales detrás de HATEOAS es que los clientes deben poder comenzar desde la URL de un solo punto de entrada y descubrir todos los recursos expuestos y las transiciones de estado disponibles para ellos. Aunque puedo ver perfectamente cómo funciona con HTML y un humano detrás de un navegador haciendo clic en los enlaces y en los botones "Enviar", me pregunto cómo se puede aplicar este principio a los problemas con los que no tengo suerte.

Me gusta cómo se presenta el principio de diseño RESTful en documentos y artículos educativos en los que todo tiene sentido. Cómo obtener una taza de café es un buen ejemplo de ello. Intentaré seguir la convención y daré un ejemplo simple y libre de detalles tediosos. Echemos un vistazo a los códigos postales y las ciudades.

Problema 1

Digamos que quiero diseñar una API RESTful para buscar ciudades mediante códigos postales. Encontré recursos llamados ''ciudades'' anidadas en códigos postales, de modo que GET en http://api.addressbook.com/zip_codes/02125/cities devuelve un documento que contiene, por ejemplo, dos registros que representan a Dorchester y Boston.

Mi pregunta es: ¿cómo se puede descubrir dicha url a través de HATEOAS? Probablemente no sea práctico exponer el índice de todos los códigos postales de ~ 40K en http://api.addressbook.com/zip_codes . Incluso si no es un problema tener un índice de ítems de 40K, recuerde que he creado este ejemplo y que hay colecciones de una magnitud mucho mayor.

Esencialmente, me gustaría exponer no el enlace, sino la plantilla del enlace, más bien, de esta manera: http://api.addressbook.com/zip_codes/{:zip_code}/cities , y eso va en contra de los principios y se basa en los principios de - Conocimiento de la banda que posee un cliente.

Problema 2

Digamos que quiero exponer el índice de ciudades con ciertas capacidades de filtrado:

  • GET en http://api.addressbook.com/cities?name=X devolvería solo las ciudades con nombres que coincidan con X

  • GET en http://api.addressbook.com/cities?min_population=Y solo devolverá ciudades con una población igual o mayor a Y

Por supuesto, estos dos filtros se pueden usar juntos: http://api.addressbook.com/cities?name=X&min_population=Y .

Aquí me gustaría exponer no solo la URL, sino también estas dos posibles opciones de consulta y el hecho de que se pueden combinar. Esto parece ser simplemente imposible sin el conocimiento fuera de banda del cliente de la semántica de esos filtros y principios detrás de la combinación de ellos en URL dinámicas.

Entonces, ¿cómo los principios detrás de HATEOAS pueden ayudar a hacer que una API tan trivial realmente RESTANTE?


Esta solución me viene a la mente, pero no estoy seguro de que la recomendaría : en lugar de devolver una URL de recurso, devuelva una URL WADL que describa el punto final. Ejemplo:

<application xmlns="http://wadl.dev.java.net/2009/02" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <grammars/> <resources base="http://localhost:8080/cities"> <resource path="/"> <method name="GET"> <request> <param name="name" style="query" type="xs:string"/> <param name="min-population" style="query" type="xs:int"/> </request> <response> <representation mediaType="application/octet-stream"/> </response> </method> </resource> </resources> </application>

Ese ejemplo fue autogenerado por CXF a partir de este código Java:

import javax.ws.rs.GET; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; public class Cities { @GET public Response get(@QueryParam("name") String name, @QueryParam("min-population") int min_poulation) { // TODO: build the real response return Response.ok().build(); } }


Me encontré con estas mismas preguntas, así que trabajé en un ejemplo práctico que resuelve ambos problemas (y algunos que aún no has pensado). http://thereisnorightway.blogspot.com/2012/05/api-example-using-rest.html?m=1

Básicamente, la solución al problema 1 es que cambie su representación (como dice Roy, dedique su tiempo al recurso). No tiene que devolver todas las cremalleras, solo haga que su recurso contenga paginación. Como ejemplo, cuando solicita páginas de noticias de un sitio de noticias, le ofrece noticias de hoy y enlaces a más, aunque todos los artículos pueden vivir bajo la misma estructura de URL, es decir, artículo / 123, etc.

El problema 2 es un poco incómodo - hay un comando poco usado en http llamado OPCIONES que usé en el ejemplo para reflejar básicamente la capacidad de la url - aunque también podría resolver esto en la representación, sería más complicado. Básicamente, devuelve una estructura personalizada que muestra las capacidades del recurso (incluidos los parámetros opcionales).

¡Déjame saber lo que piensas!


Siento que has saltado la URL del marcador. Esa es la primera url, no las de ciudades o códigos postales.

Entonces comienzas en ab: = http: //api.addressbook.com

Este primer enlace devuelve una lista de enlaces disponibles. Así es como funciona la web. Usted va a www.yahoo.com y luego comienza a hacer clic en los enlaces sin saber a dónde van.

Entonces, desde el enlace original ab: obtendrías los otros enlaces y podrían tener enlaces REL que explican cómo se debe acceder a esos recursos o qué parámetros se pueden enviar.

Lo primero que pensamos al diseñar nuestros sistemas es comenzar desde la página de marcadores y determinar todos los diferentes enlaces a los que se puede acceder.

Estoy de acuerdo con usted sobre el "conocimiento fuera de banda de los semánticos de esos filtros por parte del cliente", para mí es difícil comprar una máquina que pueda adaptarse a lo que está allí a menos que tenga alguna especificación preconcebida como HTML. Es más probable que el cliente sea creado por un desarrollador que conozca todas las posibilidades y luego codifique la aplicación para que "potencialmente" espere que esos enlaces estén disponibles. Si el enlace está disponible, el programa puede usar la lógica que el desarrollador implementó antes de actuar el recurso. Si no está ahí, entonces simplemente no ejecuta el enlace. Al final, los caminos posibles se trazan antes de comenzar a recorrer la aplicación.


Sugiero usar formularios XHTML:

GET / HTTP/1.1 OK <form method="get" action="/zip_code_search" rel="http://api.addressbook.com/rels/zip_code_search"> <p>Zip code search</p> <input name="zip_code"/> </form> GET /zip_code_search?zip_code=02125 HTTP/1.1 303 See Other Location: /zip_code/02125

Lo que falta en HTML es un atributo rel para la form .

Echa un vistazo a este artículo :

Para resumir, hay varias razones para considerar XHTML como la representación predeterminada para sus servicios RESTful. Primero, puede aprovechar la sintaxis y la semántica de elementos importantes como <a> , <form> y <input> lugar de inventar los suyos. En segundo lugar, terminará con servicios que se parecen mucho a los sitios porque los usuarios y las aplicaciones los podrán explorar. El XHTML todavía es interpretado por un ser humano: es solo un programador durante el desarrollo en lugar de un usuario en tiempo de ejecución. Esto simplifica las cosas a lo largo del proceso de desarrollo y facilita que los consumidores aprendan cómo funciona su servicio. Y, finalmente, puede aprovechar los marcos de desarrollo web estándar para crear sus servicios RESTful.

También echa un vistazo a OpenSearch .

Para reducir el número de solicitudes, considere esta respuesta:

HTTP/1.1 200 OK Content-Location: /zip_code/02125 <html> <head> <link href="/zip_code/02125/cities" rel="related http://api.addressbook.com/rels/zip_code/cities"/> </head> ... </html>