2011-06-22 10 views
12

Me gusta RESTful por su simplicidad y por la forma en que evita la falla de los sistemas 'empresariales' normales como SOAP, o la dureza binaria de DCOM y RPC.¿Acciones/servicios RESTful que no corresponden a una entidad?

Pero REST parece más adecuado para entidades de base de datos que para servicios más abstractos. Me preguntaba si podrías aconsejarme cómo harías estas situaciones:

Por ejemplo, supongamos que tengo un servicio web RESTful para un sistema de base de datos normal (por ejemplo, un sitio de compra de lácteos), así que tener/products/eggs/battery y/products/milk/skimmed

Hacer un INSERT se lograría haciendo un POST a/products/eggs.

Pero, ¿cómo harías con un comando "borrar todo"? El verbo DELETE solo es adecuado para entidades individuales. Y un "DELETE/productos/leche" implica la eliminación de la categoría del producto "leche" en sí, en lugar de solo todos los productos dentro de la categoría de leche. ¿Y qué pasa si quieres lograr ambas cosas?

Otra pregunta que tengo se refiere a las acciones del servicio web que no están relacionadas con una entidad. Por ejemplo, si estoy diseñando un servicio web para una base de datos de contraseñas, tendría operaciones como "GET /passwords/stackoverflow.com", lo cual está bien, pero también tendría operaciones para deshabilitar el sitio web en caso de intrusión. detección. Bajo el modelo de servicio web de "vieja escuela" tendría un método simplemente llamado "disableWebsite", sin embargo, no puedo crear un verbo HTTP llamado "DISABLE" y un recurso llamado "/ sitio web" (por lo que la solicitud sería " DESACTIVAR/sitio web "). ¿Cuál es la solución aquí?

Finalmente, ¿cómo concilia los formularios HTML con RESTful? Los formularios web solo pueden realizar solicitudes GET utilizando cadenas de consulta o POST. Si tengo un formulario de búsqueda, quiero que solicite "/ products/search/{query}", pero ahora la solicitud se verá como "/ products/search? Query = {query}".

Respuesta

5

Creo que deberías dejar de pensar en los recursos como sinónimos para las entidades de bases de datos. Sí, a menudo están relacionados, pero un recurso es realmente solo un concepto direccionable en su dominio. Creo que es mucho más útil pensar en los recursos como las cosas que ves en la web cuando usas tu navegador (listas, artículos, publicaciones, comentarios, imágenes, lo que sea).

Pero, ¿cómo harías con un comando "borrar todo"?

no estoy seguro de por qué/productos/BORRAR leche implica la supresión de la misma categoría de leche, pero si usted prefiere:

DELETE /products?category=milk 

DELETE no implica la supresión de una sola entidad de base de datos.Implica la eliminación de un único recurso. Y "/ products? Category = milk" (o "/ products/milk", para el caso) identifica un único recurso. Si puedes OBTENERLO, puedes ELIMINARLO.

¿Y si quieres lograr ambas cosas?

¿Qué le parece esto?

DELETE /product-categories/milk 

Un truco que se hizo popular con Ruby on Rails es proporcionar un (GET usando) forma para cualquier operación PUT/POST/BORRAR. Por lo tanto, para estas eliminaciones, es posible que desee proporcionar un formulario como el siguiente:.

GET /product-categories/milk/delete 

En esa forma (piense HTML), puede preguntar a su usuario si es realmente en Aceptar para eliminar toda la categoría (Por favor, no Preste atención a la noción de que los formularios HTML no son realmente compatibles con los servicios web RESTful. HTML es un formato bastante exitoso para interactuar con recursos en la web, y una aplicación AJAX bien diseñada probablemente primero funcione como una aplicación HTML bien diseñada. Hay algunos detalles que deben resolverse para admitir tanto a navegadores como a otros clientes, pero todos son clientes de REST legítimos.

Cómo deshabilitar un nosotros bsite?

Hay un montón de maneras de hacer esto. Solo un PUT a /sites/stackoverflow.com con un indicador para deshabilitar podría funcionar.

Finalmente, ¿cómo concilia los formularios HTML con RESTful?

Realmente no se puede hacer un HTTP PUT o DELETE desde el navegador, pero puede proporcionar un campo oculto en su forma a fingir:

<input type="hidden" name="_method" value="PUT" /> 

Siempre y cuando su motor de enrutamiento lo admite , esta es una buena forma de enrutar una publicación del navegador al controlador apropiado (también he visto a personas usar un encabezado X-HTTP-Method-Override para clientes que no son HTML sin soporte completo para verbos HTTP).

Si está interesado en profundizar, recomiendo el Web Services Cookbook como motor de arranque. Además, eche un vistazo a Richardson Maturity Model. Y recuerda que REST es como el resto de la web. No sería muy útil sin los enlaces. Proporcione a sus clientes una forma de moverse.

<a href="/products/milk/delete" rel="delete" /> 

<atom:link href="/products/milk/delete" rel="delete" /> 
+0

¡Excelente respuesta! Pero usar 'GET/product-categories/milk/delete' no es realmente una buena solución REST, porque GET es un método de guardado y" NO DEBE tener la importancia de tomar una acción que no sea la recuperación "ver [enlace] (http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html). Yo recomendaría usar un POST algo como 'POST/product-categories/milk/deletecategory'. Esta es la forma en que Twitter maneja muchas cosas con su API. – Robert

+0

El OBTENER es recuperar un formulario, no hacerlo en realidad. –

2

Pero, ¿cómo harías con un comando "borrar todo"? El verbo DELETE solo es adecuado para entidades individuales.

False.

Y un "DELETE/products/milk" implica la eliminación de la categoría del producto "leche" en sí, en lugar de solo todos los productos dentro de la categoría de leche.

Correcto.

¿Y si quieres lograr ambas cosas?

¿Qué pasa con DELETE en /cart/milk/?

Bajo el modelo de servicios web 'vieja escuela' que tendría un método llamado simplemente "disableWebsite",

¿Qué?

Sin embargo, no puedo crear un verbo HTTP llamado "DESACTIVAR" y un recurso llamado "/ sitio web" (por lo que la solicitud sería "DESACTIVAR/sitio web"). ¿Cuál es la solución aquí?

POST.POST a /passwords/stackoverflow.com/disable/ La entidad (passwords/stackoverflow.com) contiene una sub-entidad "deshabilitar" y "habilitar" dentro de ella. Puede publicar en cualquiera de los dos para cambiar el estado de la entidad principal.

Si tengo un formulario de búsqueda que quiero que solicitar "/ productos/Búsqueda/{query}"

Es por eso que los servicios web más tranquilo están escritos en Javascript o Flex o algo por el estilo.

Los servicios web RESTful y los formularios HTML "nativos" no son realmente compatibles. No están destinados a ser.

4

REST Los sistemas interactúan con "recursos" que no se correlacionan con la noción estándar de una entidad.
Un "recurso" es un concepto muy difuso, con algunas reglas estrictas. Me gusta pensar en un recurso como en cualquier concepto útil que pueda ayudar a que el cliente haga lo que debe hacer. Entonces, si necesita eliminar un grupo de entidades, cree un recurso que represente ese "conjunto de entidades" y luego use el método DELETE en él.

El verdadero truco para diseñar sistemas tranquilos es dejar de tratar de asignar significado a recursos particulares, pero asignar significancia a la relación entre dos recursos. Piensa en cómo funciona HTML. Usted descarga una página, y hay un enlace de hoja de estilo. El rel = "stylesheet" define el significado de lo que se encuentra al final de la URL href.
Si desea deshabilitar un sitio web, acceda al recurso del sitio web y use la URL que está en el enlace con rel = "disabler". El diseño REST se trata de definir recursos que están interrelacionados a través de los enlaces. Algunos enlaces se utilizan solo para recuperar información, otros se usan para realizar cambios en el estado de los recursos.

Las estrictas reglas que debe seguir un recurso son que un recurso debe tener un identificador (por ejemplo una URL) y se puede única interactuar con ese recurso a través de "representaciones" de ese recurso. Esas representaciones pueden estar en una amplia gama de formatos diferentes.

En cuanto a los formularios HTML, olvídate de cómo luce el URI, el uso de los parámetros de cadena de caracteres es RESTful como los parámetros de ruta. Los formularios HTML le permiten hacer GET y POST, es decir, operaciones seguras y operaciones inseguras. Eso es suficiente para que alguien haga REST. Sure DELETE y PUT pueden ser útiles, pero en realidad los beneficios que esos métodos extra aportan a un sistema RESTful son muy pequeños, en comparación con algo como hipermedia.

Cuestiones relacionadas