2012-07-02 16 views
16

He estado leyendo mucho sobre los beneficios potenciales si tuviera que convertir mis servicios web actuales de Restful para que sean lo más HATEOS posible. Entiendo la importancia de proporcionar enlaces en la carga útil para reducir la carga del consumidor al recordar las próximas acciones válidas disponibles. Sin embargo, no puedo entender cómo ayudará al consumidor de mis servicios web de Restful en realidad.¿Vale la pena lograr HATEOAS para servicios web tranquilos en el mundo real?

Para ilustrar, Tomo este ejemplo de Rest In Practice libro sobre cómo hacer una orden de café: -

<order xmlns="http://schemas.restbucks.com"> 
    <location>takeAway</location> 
    <item> 
    <name>latte</name> 
    <quantity>1</quantity> 
    <milk>whole</milk> 
    <size>small</size> 
    </item> 
    <cost>2.0</cost> 
    <status>payment-expected</status> 
    <link rel="payment" href="https://restbucks.com/payment/1234" /> 
</order> 

Básicamente, esto permite al consumidor realizar un pago definida por la etiqueta <link>. Sin embargo, en realidad, el consumidor aún necesita conocer toda la semántica de esa llamada al servicio web, por ejemplo, qué método (POST o PUT) usar, qué parámetros de solicitud usar en la carga útil para realizar el pago, etc. .. en otras palabras, el consumidor aún necesita confiar en la documentación WADL para saber cómo hacer que invoque este servicio web con éxito. Estas etiquetas probablemente tengan más sentido si todas usan GET en un elemento específico. De lo contrario, realmente no veo muchos beneficios en la definición de los enlaces aquí ... aparte del hecho de que el consumidor sabe qué acciones pueden invocar a continuación, y luego consultar el WADL para determinar cómo invocarlo correctamente.

Mi siguiente preocupación es la posibilidad de terminar con una carga útil muy pesada con todas las etiquetas <link>. Por ejemplo, si un GET en/proyectos/1/usuarios devuelve toda la información de los usuarios que pertenecen proyecto 1, supongo que voy a terminar con las siguientes etiquetas: -

<project> 
    <users> 
     <user id="12" name="mike" ... /> 
     <user id="23" name="kurt" ... /> 
     <user id="65" name="corey" ... /> 
    </user> 
    <links> 
     <link rel="self" href="http://server/projects/1/users"/> 
     <link rel="create_user" href="http://server/projects/1/users"/> 

     <link rel="get_user_mike" href="http://server/projects/1/users/12"/> 
     <link rel="get_user_kurt" href="http://server/projects/1/users/23"/> 
     <link rel="get_user_corey" href="http://server/projects/1/users/65"/> 
     ... 
    </links> 
</project> 

Si un proyecto contiene decir, 500 usuarios ... ¿no tendría 500 enlaces de usuario en la carga útil? De lo contrario, ¿cuál es el mejor enfoque para rediseñar mis servicios web para manejar esta situación? ¿O es esto aceptable en el mundo real?

Cualquier idea o sugerencia es muy apreciada aquí. Gracias.

Respuesta

9

Para pensar por qué es lo correcto, imagine su API sin un enfoque HATEOAS: tendrá que publicar todos los posibles esquemas de URI en su documentación (o en su WADL, si eso es lo suyo), y desde ese punto en adelante no puede cambiarlos sin romper sus clientes.

En esencia, sus clientes estarán inextricablemente unidos a su elección de diseño de URI. Ese es un nivel de acoplamiento que puede evitar fácilmente simplemente documentando donde los enlaces son en sus tipos de medios en lugar de documentar cómo se ven los enlaces también.

Dicho esto, podría estar bien que las necesidades de su aplicación adopten ese enfoque, y eso está bien. Solo ten en cuenta que estarás atascado con tu diseño de URI durante mucho, mucho tiempo. Sin embargo, estarás en good company.

+6

+1 ... Gracias por su respuesta. En mi opinión, realmente no hay escapatoria de WADL ya sea que adopte el enfoque HATEOAS o no, porque al final, todavía necesitaré documentar el uso del método y todos los parámetros requeridos (solicitud, encabezados, etc.) que mi API pueda requerir . Hiciste un buen punto acerca de no romper el código del cliente cuando cambio el patrón URI un día, PERO si no resuelve el hecho de que el código del cliente TODAVÍA está estrechamente vinculado con mi API en realidad ... (continúa) – limc

+1

Imagine , si tengo un POST/login que acepta 2 parámetros de solicitud ("usuario" y "contraseña") y un día decidí cambiar los parámetros (digamos, cambiando el nombre o agregando nuevos), aún así se romperá el código del cliente incluso si el URI es estable. La forma en que lo veo es HATEOAS definitivamente ayuda en algunas situaciones, pero es completamente inútil en otras situaciones, lo que me hace preguntarme si vale la pena adoptar HATEOAS o no. – limc

+1

Sin embargo, su ejemplo de cambios de parámetros POST no tiene nada que ver con HATEOAS. HATEOAS se refiere al uso correcto de hipervínculos dentro del contenido de la carga útil devuelto por el servidor, no por el formato de los parámetros de URI (que obviamente tienen que documentarse en algún lugar y mantenerse por razones de compatibilidad). –

5

Para su ejemplo particular, creo que tiene sentido volver a HTML. Si muestra una lista de 500 recursos en HTML, ¿incluiría un enlace a cada recurso para que los usuarios puedan obtener más información? Probablemente lo harías Una API REST no es muy diferente: si devuelve una lista de 500 recursos, debe incluir 500 enlaces, para que los usuarios puedan obtener más información sobre cada recurso.

Esperar que los clientes creen URL basadas en algunos ID o nombres sería como pedirles a los usuarios que escriban URL manualmente en la barra de direcciones del navegador.

Aquí es un very good article sobre esto, en particular:

Al igual que los archivos HTML enlazan entre sí con las etiquetas, o simplemente como archivos XML enlazan entre sí con XLink, toda la transferencia de estado tiene que ser hecho únicamente como una reacción a un enlace que se encuentra en el interior de una representación

+2

+1 ... Gracias por su comentario. Déjame preguntarte esto y ver si estás de acuerdo con mis pensamientos aquí ... el atributo 'rel' en la etiqueta' link' es bastante permanente. El consumidor siempre hará una búsqueda basada en el atributo 'rel' para obtener el URI dinámico. Sin embargo, el consumidor TODAVÍA necesita saber cómo invocar el URI dinámico consultando la WADL o una serie de documentos. ¿Suena esto bien? ¿Es común incluir un enlace a WADL desde los servicios web de Restful? – limc

+0

@limc No, eso no está bien. El formato del documento describe el método http para usar. Ver mi respuesta para más detalles. –

0

Sólo un lado del punto en el que 500 de usuario: no soy un experto pero mi entendimiento es que tranquilamente puede proporcionar la paginación:

/project/1/users/pages/1

<links> 
    ... 
    <link rel="get_user_mike" href="http://server/projects/1/users/12"/> 
    <link rel="get_user_kurt" href="http://server/projects/1/users/23"/> 
    <link rel="get_user_corey" href="http://server/projects/1/users/65"/> 
    <link rel="get_page_2" href="http://server/projects/1/users/pages/2"/> 
</links> 
0

Esto no es realmente una respuesta, solo algunos consejos para adoptar HATEOAS. No es necesario que incluya cientos de enlaces, puede incluir 1 enlace a la lista completa de 500, 1 enlace a un subconjunto paginado de los enlaces, o incluir un subconjunto paginado en la respuesta y agregar un enlace a la página siguiente.

En respuesta a lo de WADL, debe usar las funciones integradas de cualquier formato de contenido, p. Ej. En HTML, serían LINK y A elementos para indicar que el cliente debe realizar solicitudes GET y FORM elementos para solicitudes POST. Obviamente, otros formatos y API XLink y XMLHTTPRequest admiten HTTP mejor que HTML. Es posible que desee mirar http://tools.ietf.org/html/draft-nottingham-link-hint