Es comprensible estar un poco confundido acerca de cómo usar REST correctamente en función de todas las formas en que he visto a grandes empresas diseñar sus API REST.
Tiene razón en que REST es un sistema de recopilación de recursos. Es sinónimo de Transferencia de Estado de representación. No es una gran definición si me preguntas. Pero los conceptos principales son los 4 VERB HTTP y no tener estado.
La pieza importante a tener en cuenta es que solo tiene 4 VERBOS con REST. Estos son GET, POST, PUT y DELETE. Su resendejemplo sería agregar un nuevo verbo a REST. Esto debería ser una bandera roja.
Pregunta 1
Es importante darse cuenta de que la persona que llama desde su API REST no debería saber que realizar una búsqueda PUTen su colección podría generar un correo electrónico. Eso huele a una fuga para mí. Lo que podrían saber es que realizar un PUTresultado podría generar tareas adicionales que podrían consultar más tarde. Lo sabrían realizando un GETrecurso en el recurso creado recientemente. Eso GETdevolvería el recurso y todos los TaskID de recursos asociados con él. Luego puede consultar esas tareas para determinar su estado e incluso enviar una nueva Task.
Tienes pocas opciones.
REST: enfoque basado en recursos de tareas
Cree un tasksrecurso en el que pueda enviar tareas específicas a su sistema para realizar acciones. A continuación, puede realizar GETla tarea en función de la IDdevolución para determinar su estado.
O puede mezclar un SOAP over HTTPservicio web para agregar algo de RPC a su arquitectura.
consultar todas las tareas para un recurso específico
GET http://server/api/myCollection/123/tasks
{ "tasks" :
[ { "22333" : "http://server/api/tasks/223333" } ]
}
ejemplo de recurso de tarea
PUT http://server/api/tasks
{
"type" : "send-email" ,
"parameters" :
{
"collection-type" : "foo" ,
"collection-id" : "123"
}
}
==> devuelve el id de la tarea
223334
GET http://server/api/tasks/223334
{
"status" : "complete" ,
"date" : "whenever"
}
REST- Uso de POST para desencadenar acciones
Siempre puede POSTdatos adicionales a un recurso. En mi opinión, esto violaría el espíritu de REST, pero seguiría cumpliendo.
Puedes hacer una POST similar a esta:
POST http://server/api/collection/123
{ "action" : "send-email" }
Actualizará el recurso 123 de la colección con datos adicionales. Esos datos adicionales son esencialmente una acción que le dice al servidor que envíe un correo electrónico para ese recurso.
El problema que tengo con esto es que un GETen el recurso devolverá estos datos actualizados. Sin embargo, esto resolvería sus requisitos y aún sería RESTful.
SOAP: servicio web que acepta recursos obtenidos de REST
Cree un nuevo servicio web en el que pueda enviar correos electrónicos basados en el ID de recurso anterior de la API REST. No entraré en detalles sobre SOAP aquí, ya que la pregunta original es sobre REST y estos dos conceptos / tecnologías no deben compararse, ya que se trata de manzanas y naranjas .
Pregunta 2
También tiene algunas opciones aquí:
Parece que muchas compañías más grandes que publican API de REST exponen una searchcolección que realmente es solo una forma de pasar parámetros de consulta para devolver recursos.
GET http://server/api/search?q="type = myCollection & someField >= someval"
Lo que devolvería una colección de recursos REST completamente calificados como:
{
"results" :
{ [
"location" : "http://server/api/myCollection/1",
"location" : "http://server/api/myCollection/9",
"location" : "http://server/api/myCollection/56"
]
}
}
O puede permitir algo como MVEL como parámetro de consulta.
Pregunta 3
Prefiero los subniveles que tener que volver a subir y consultar el otro recurso con un parámetro de consulta. No creo que haya ninguna regla de una forma u otra. Puede implementar ambas formas y permitir que la persona que llama decida cuál es más apropiado en función de cómo ingresó por primera vez al sistema.
Notas
No estoy de acuerdo con los comentarios de legibilidad de otros. A pesar de lo que algunos podrían pensar, REST todavía no es para consumo humano. Es para el consumo de la máquina. Si quiero ver mis Tweets, uso el sitio web normal de Twitters. No realizo un REST GET con su API. Si quiero hacer algo programáticamente con mis tweets, entonces uso su API REST. Sí, las API deben ser comprensibles, pero tu gteno es tan malo, simplemente no es intuitivo.
La otra cosa principal con REST es que debería poder comenzar en cualquier punto dado en su API y navegar a todos los demás recursos asociados SIN conocer la URL exacta de los otros recursos con anticipación. Los resultados del GETVERBO en REST deberían devolver la URL REST completa de los recursos a los que hace referencia. Entonces, en lugar de una consulta que devuelve la ID de un Personobjeto, devolvería la URL totalmente calificada como http://server/api/people/13. Entonces siempre puede navegar programáticamente los resultados incluso si la URL ha cambiado.
Respuesta al comentario
En el mundo real, de hecho, hay cosas que deben suceder que no crean, leen, actualizan o eliminan (CRUD) un recurso.
Se pueden tomar acciones adicionales sobre los recursos. Las bases de datos relacionales típicas admiten el concepto de procedimientos almacenados. Estos son comandos adicionales que se pueden ejecutar en un conjunto de datos. REST no tiene ese concepto inherentemente. Y no hay razón para que así sea. Este tipo de acciones son perfectas para los servicios web RPC o SOAP.
Este es el problema general que veo con las API REST. A los desarrolladores no les gustan las limitaciones conceptuales que rodean REST, por lo que lo adaptan para hacer lo que quieran. Sin embargo, eso deja de ser un servicio RESTful. Esencialmente, esas URL se convierten en GETllamadas en servlets de tipo pseudo-REST.
Tienes pocas opciones:
- Crear un recurso de tarea
- Soporte
POSTde datos adicionales al recurso para realizar una acción.
- Agregue los comandos adicionales a través de un servicio web SOAP.
Si usara un parámetro de consulta, ¿qué VERBO HTTP usaría para reenviar el correo electrónico?
GET- ¿Esto reenvía el correo electrónico Y devuelve los datos del recurso? ¿Qué pasaría si un sistema almacenara en caché esa URL y la tratara como la URL única para ese recurso? Cada vez que llegan a la URL, reenvían un correo electrónico.
POST - En realidad no envió ningún dato nuevo al recurso, solo un parámetro de consulta adicional.
De acuerdo con todos los requisitos dados, resolver un problema POSTen el recurso con action fielddatos POST como.