Me cuesta determinar cómo diseñar URL relajantes. Estoy totalmente de acuerdo con el enfoque tranquilo de usar URL con sustantivos y no verbos, no entiendo cómo hacer esto.
Estamos creando un servicio para implementar una calculadora financiera. La calculadora toma varios parámetros que cargaremos a través de un archivo CSV. Los casos de uso implicarían:
- Subir nuevos parámetros
- Obtenga los últimos parámetros
- Obtener parámetros para una fecha comercial determinada
- Hacer un conjunto de parámetros activo
- Validar un conjunto de parámetros
Entiendo que el enfoque tranquilo sería tener las siguientes URL de tipo:
/parameters
/parameters/12-23-2009
Puede lograr los primeros tres casos de uso con:
- POST donde incluye el archivo de parámetros en la solicitud de publicación
- OBTENER la primera URL
- OBTENER la segunda URL
Pero, ¿cómo haces el caso de uso cuarto y quinto sin un verbo? ¿No necesitarías URL como:
/parameters/ID/activate
/parameters/ID/validate
??
rest
restful-url
Marcus Leon
fuente
fuente
Respuestas:
Quizás algo como:
fuente
POST
está bien si necesita realizar un "procedimiento" como verificar los parámetros cada vez que envía una solicitud. Pero cuando modifica el estado (aplicación) del recurso, en realidad actualiza el recurso existente, no crea algún recurso nuevo ni publica una solicitud de procesamiento.POST
vsPUT
no es exactamente igualinsert
vsupdate
.PUT
actualiza el recurso correspondiente a la ruta dada, o crea un nuevo recurso correspondiente a la ruta dada.POST
crea un nuevo recurso en alguna parte. Por ejemplo,PUT /blog/posts/3/comments/5
actualizará el comentario apropiado, mientrasPOST /blog/posts/3/comments
que creará un nuevocomment
recurso (y debería devolver la ruta al nuevo recurso en la respuesta).PUT
es idempotente mientrasPOST
que no lo es. Por lo general, debe poner tantas restricciones sobre lo que proporciona como resultado como sea posible. Seguir conPUT
da más información al cliente del servicio.Principios generales para un buen diseño de URI:
/resource
o/resource/
; crea 301 redirecciones desde la que no usas(Nota: no dije "diseño de URI RESTful"; los URI son esencialmente opacos en REST).
Principios generales para la elección del método HTTP:
Principios generales del diseño de servicios web con HTTP:
201 Created
después de crear un recurso; el recurso debe existir en el momento en que se envía la respuesta202 Accepted
después de realizar una operación con éxito o crear un recurso de forma asincrónica400 Bad Request
cuando alguien realiza una operación sobre datos que son claramente falsos; para su aplicación esto podría ser un error de validación; generalmente reserva 500 para excepciones no capturadas401 Unauthorized
cuando alguien accede a su API sin proporcionar unAuthorization
encabezado necesario o cuando las credenciales dentro de la mismaAuthorization
no son válidas; no use este código de respuesta si no espera credenciales a través de unAuthorization
encabezado.403 Forbidden
cuando alguien accede a su API de una manera que podría ser maliciosa o si no está autorizado405 Method Not Allowed
cuando alguien usa POST cuando debería haber usado PUT, etc.413 Request Entity Too Large
cuando alguien intenta enviarte un archivo inaceptablemente grande418 I'm a teapot
cuando intentas preparar café con una teteraETag
los encabezados son buenos cuando puede reducir fácilmente un recurso a un valor hashLast-Modified
debería indicarle que mantener una marca de tiempo de cuándo se actualizan los recursos es una buena ideaCache-Control
yExpires
deben recibir valores razonablesIf-None-Modified
,If-Modified-Since
)Con respecto a su pregunta específica, POST debe usarse para los números 4 y 5. Estas operaciones caen bajo la directriz "similar a RPC" anterior. Para el n. ° 5, recuerde que POST no necesariamente tiene que usarse
Content-Type: application/x-www-form-urlencoded
. Esto podría ser fácilmente una carga útil JSON o CSV.fuente
Siempre que parezca que necesitas un nuevo verbo, piensa en convertir ese verbo en un sustantivo. Por ejemplo, convierta 'activar' en 'activación' y 'validar' en 'validación'.
Pero solo por lo que ha escrito, diría que su aplicación tiene problemas mucho mayores.
Cada vez que se propone un recurso llamado 'parámetro', debe enviar señales de alerta en la mente de cada miembro del equipo del proyecto. 'parámetro' puede aplicarse literalmente a cualquier recurso; No es lo suficientemente específico.
¿Qué representa exactamente un 'parámetro'? Probablemente una serie de cosas diferentes, cada una de las cuales debería tener un recurso separado dedicado a ella.
Otra forma de llegar a esto: cuando discute su aplicación con los usuarios finales (aquellos que presumiblemente saben poco sobre programación), ¿cuáles son las palabras que ellos mismos usan repetidamente?
Esas son las palabras con las que debería diseñar su aplicación.
Si aún no ha tenido esta conversión con posibles usuarios, ¡pare todo ahora y no escriba otra línea de código hasta que lo haga! Solo entonces su equipo tendrá una idea de lo que debe construirse.
No sé nada sobre el software financiero, pero si tuviera que adivinar, diría que algunos de los recursos pueden tener nombres como "Informe", "Pago", "Transferencia" y "Moneda".
Hay varios libros buenos sobre esta parte del proceso de diseño de software. Dos que puedo recomendar son los patrones de diseño y análisis basados en dominio .
fuente
El diseño de sus URL no tiene nada que ver con si su aplicación es RESTful o no. La frase "URL RESTful" no tiene sentido.
Creo que deberías leer un poco más sobre lo que REST es en realidad. REST trata las URLS como opacas, y como tal no sabe qué hay en ellas, si hay verbos o sustantivos o lo que sea. Es posible que aún desee diseñar sus URL, pero eso se trata de la interfaz de usuario, no de REST.
Dicho esto, pasemos a su pregunta: los dos últimos casos no son RESTful y no encajan en ningún tipo de esquema de descanso. Esos son lo que podrías llamar RPC. Si te tomas en serio REST, tendrás que repensar cómo funciona tu aplicación desde cero. O eso, o abandone REST y simplemente haga su aplicación como una aplicación RPC.
Hrmmm tal vez no.
La idea aquí es que debe tratar todo como un recurso, por lo que una vez que un conjunto de parámetros tiene una URL a la que puede referirse, simplemente agrega:
Pero, de nuevo, esa cosa de activación es RPC, no REST.
fuente
Los requisitos de activación y validación son situaciones en las que está intentando cambiar el estado de un recurso. No es diferente que hacer un pedido "completado", o alguna otra solicitud "enviada". Existen numerosas formas de modelar este tipo de cambio de estado, pero creo que a menudo funciona: crear recursos de recolección para recursos del mismo estado y luego mover el recurso entre las colecciones para afectar el estado.
Por ejemplo, crear algunos recursos como,
Si desea activar un conjunto de parámetros, agréguelo a la colección ActiveParameters. Puede pasar el conjunto de parámetros como un cuerpo de entidad, o puede pasar una url como parámetro de consulta, de la siguiente manera:
Lo mismo se puede hacer con los / ValidatedParameters. Si los parámetros no son válidos, el servidor puede devolver "Solicitud incorrecta" a la solicitud para agregar los parámetros a la colección de parámetros validados.
fuente
Sugeriría los siguientes recursos y métodos Meta.
Active los parámetros y / o valídelos:
Compruebe si los parámetros son activos y válidos:
fuente
Me siento un poco triste al ver que después de más de 10 años no hay una respuesta que indique realmente cómo podría diseñarse algo como lo solicitado en el OP en una arquitectura REST, por lo tanto, siento la necesidad de hacerlo ahora.
Primero lo primero, ¿qué es REST? El acrónimo REST o ReST significa "Transferencia de estado de representación" y define el intercambio del estado de un recurso en un determinado formato de representación. El formato de representación es la marea del tipo de medio negociado. En el caso del
application/html
formato de representación, puede ser una secuencia de contenido de texto con formato HTML que se procesa en el navegador, probablemente después de aplicar un formato de hoja de estilo para colocar ciertos elementos en ciertas ubicaciones.REST es, en principio, una generalización de la Web navegable que todos conocemos, aunque se dirige a todo tipo de aplicaciones y no solo a los navegadores. Por lo tanto, por diseño, los mismos conceptos que se aplican a la Web también se aplican a una arquitectura REST. Una pregunta como cómo lograr algo de una manera "RESTful" se resuelve al responder la pregunta de cómo lograr algo en una página web y luego aplicar los mismos conceptos en la capa de aplicación.
Una calculadora basada en la web generalmente puede comenzar con alguna "página" que le permite ingresar algunos valores para calcular antes de enviar los datos ingresados al servidor. En HTML, esto generalmente se logra a través de
<form>
elementos HTML que le enseñan al cliente sobre los parámetros disponibles para establecer, la ubicación de destino para enviar la solicitud, así como el formato de representación para aplicar al enviar los datos de entrada. Esto puede ser así:El ejemplo anterior indica que hay dos campos de entrada que puede completar el usuario o algún otro autómata, y que al invocar el elemento de entrada de envío, el navegador se encarga de formatear los datos de entrada en un
application/x-www-form-urlencoded
formato de representación que se envía a la ubicación de destino mencionada a través del método de solicitud HTTP especificado,POST
en este caso. Si ingresamos1
en elfirstNumber
campo de entrada y2
en elsecondNumber
campo de entrada, el navegador generará una representaciónfirstNumber=1&secondNumber=2
y la enviará como la carga útil del cuerpo de la solicitud real al recurso de destino.La solicitud HTTP sin procesar emitida al servidor puede verse así:
El servidor puede realizar el cálculo y responder con una página HTML adicional que contiene el resultado del cálculo, ya que la solicitud indica que el cliente entiende este formato.
Como Breton ya señaló, no existe una URL o URI "RESTful". Un URI / URL es su propio tipo de cosas y no debe transmitir ningún significado a un cliente / usuario. En la muestra de la calculadora anterior, un usuario simplemente no está interesado a dónde enviarle los datos, solo le interesa que al activar el campo de entrada de envío se envíe la solicitud. El servidor ya debe proporcionar toda la información necesaria para realizar la tarea.
Es posible que un navegador tampoco se dé cuenta de que la solicitud realmente está alimentando una calculadora con algunos parámetros de entrada, también podría ser algún tipo de formulario de pedido que devuelve solo la siguiente representación de formulario para continuar el proceso de pedido o algún tipo totalmente diferente de recurso. Simplemente realiza lo que exige la especificación HTML en tal caso y no podría importarle menos lo que el servidor está haciendo realmente. Este concepto permite que un navegador utilice el mismo formato de representación para hacer todo tipo de cosas, como ordenar algunas cosas de su tienda en línea preferida, chatear con sus mejores amigos, iniciar sesión en una cuenta en línea, etc.
La potencialidad de ciertos elementos, como en el presente caso del campo de entrada que por lo general se representa como botón, define lo que debe para con ella. En el caso de un botón o un enlace, básicamente le dice que haga clic en él. Otros elementos pueden transmitir diferentes posibilidades. Dicha prestación también se puede expresar a través de relaciones de enlace, es decir, con
preload
enlaces anotados que básicamente le dicen a un cliente que ya puede cargar el contenido del recurso vinculado en segundo plano, ya que el usuario probablemente tomará este contenido a continuación. Dichas relaciones de enlace deberían, por supuesto, estandarizarse o seguir el mecanismo de extensión para los tipos de relación definidos por el enlace web .Estos son los conceptos fundamentales que se usan en la Web y que también deberían usarse en una arquitectura REST. Según el "Tío Bob" Robert C. Martin, una arquitectura trata sobre la intención y la intención detrás de la arquitectura REST es el desacoplamiento de los clientes de los servidores para permitir que los servidores evolucionen libremente en el futuro sin tener que temer que rompan clientes. Desafortunadamente, esto requiere mucha disciplina, ya que es muy fácil introducir el acoplamiento o agregar soluciones de solución rápida para hacer el trabajo y seguir adelante. Como Jim Webber señaló en una arquitectura REST, usted, como proveedor de servicios, debe intentar diseñar un protocolo de aplicación de dominio similar a un juego de computadora basado en texto de los años 70 que los clientes seguirán hasta que lleguen al final de un proceso.
Desafortunadamente, lo que muchas de las llamadas API "REST" hacen en realidad es todo menos eso. Verá el intercambio de datos basados principalmente en JSON que se especifican en una documentación externa específica de API que generalmente es difícil de integrar dinámicamente sobre la marcha. El formato de cómo debe verse una solicitud también está codificado en la documentación externa, lo que lleva a una gran cantidad de URI de interpretación de implementación para devolver tipos predefinidosen lugar de usar algún formato de representación común que se negocie por adelantado. Esto evita que los servidores cambien, ya que los clientes ahora esperan recibir un cierto formato de datos (¡no un formato de representación!) Para URI predefinidos. Este intercambio de formato de datos personalizado además evita que los clientes interactúen con otras API, ya que el "formato de datos" suele ser una marea específica. Conocemos este concepto del pasado por las tecnologías RPC como Corba, RMI o SOAP, que condenamos como algo malvado, a pesar de que Peppol se mudó nuevamente al reemplazar AS2 con AS4 como protocolo de transferencia predeterminado recientemente.
En lo que respecta a la pregunta real formulada, el envío de datos como archivo csv no es diferente al uso de
application/x-www-form-urlencoded
representación o cosas similares. Jim Webber dejó en claro que, después de todo, HTTP es solo un protocolo de transporte cuyo dominio de aplicación es la transferencia de documentos a través de la Web . El cliente y el servidor deben ser compatibles,text/csv
como mínimo, según se define en RFC 7111 . Este archivo CSV podría generarse como consecuencia del procesamiento de un tipo de medio que define elementos de formulario, un elemento o atributo de destino para enviar la solicitud, así como el método HTTP para realizar la carga de la configuración.Hay un par de tipos de medios que admiten formularios como HTML , HAL Forms , halform , ion o Hydra . Sin embargo, actualmente no conozco un tipo de medio que pueda codificar automáticamente los datos de entrada
text/csv
directamente, por lo tanto, es posible que sea necesario definirlo y registrarlo en el registro de tipos de medios de la IANA .Supongo que la carga y descarga del conjunto completo de parámetros no debería ser un problema. Como se mencionó anteriormente, el URI de destino no es relevante ya que un cliente solo usará el URI para recuperar nuevo contenido para procesar. Filtrar por fecha comercial tampoco debería ser difícil. Aquí, sin embargo, el servidor debe ser el cliente con todas las posibilidades que el cliente simplemente puede elegir. En los últimos años, GraphQL y RestQL evolucionaron, lo que introduce un lenguaje similar a SQL que puede orientarse a un determinado punto final para obtener una respuesta filtrada. Sin embargo, en un verdadero sentido REST, esto viola la idea detrás de REST como a) GraphQL, es decir, solo usa un único punto final que de alguna manera evita el uso óptimo del almacenamiento en caché yb) requiere el conocimiento de los campos disponibles en sentido inverso, lo que puede conducir a la introducción de un acoplamiento de clientes al modelo de datos base del recurso.
La activación o desactivación de ciertos parámetros de configuración es simplemente una cuestión de activar los controles hipermedia que proporcionan esta capacidad. En los formularios HTML, esto podría ser una simple casilla de verificación o una selección de varias líneas en una lista o de ese tipo. Dependiendo de la forma y del método que defina, podría enviar toda la configuración
PUT
o ser inteligente sobre los cambios realizados y solo realizar una actualización parcial a través dePATCH
. El último requiere básicamente un cálculo de la representación de cambio al actualizado y alimentar al servidor con los pasos necesarios para transformar la representación actual en la deseada. De acuerdo con la especificación PATH, esto debe hacerse dentro de una transacción para que se apliquen todos o ninguno de los pasos.HTTP permite y alienta a un servidor a validar una solicitud recibida por adelantado antes de aplicar los cambios. Para PUT los estados de especificación:
Para resumir esta publicación, debe usar un tipo de medio existente que le permita enseñarle a un cliente sobre los parámetros de entrada requeridos o admitidos, la ubicación de destino para enviar la solicitud, la operación a usar y el tipo de medio la solicitud debe estar formateada o definir la suya propia que registre con IANA. Esto último puede ser necesario si desea convertir la entrada a
text/csv
y luego cargue la representación CSV en el servidor. La validación debe ocurrir antes de que los cambios se apliquen al recurso. El URI real no debe ser relevante para los clientes más que para determinar a dónde enviar la solicitud y, como tal, usted puede elegir libremente, el implementador del servicio. Si sigue estos pasos, tendrá la libertad de cambiar el lado del servidor en cualquier momento y, como consecuencia, los clientes no se romperán si admiten los tipos de medios utilizados.fuente
Editar: De hecho, el URI habría evitado que las
GET
solicitudes se mantuvieran idempotentes.Sin embargo, para la validación, el uso de códigos de estado HTTP para notificar la validez de una solicitud (para crear un nuevo o modificar un "parámetro" existente) se ajustaría a un modelo Restful.
Informe con un
400 Bad Request
código de estado si los datos enviados no son válidos y la solicitud debe modificarse antes de volver a enviarla ( códigos de estado HTTP / 1.1 ).Sin embargo, esto se basa en la validación en el momento del envío, en lugar de diferirlo como en su caso de uso. Las otras respuestas tienen soluciones adecuadas para ese escenario.
fuente
En un entorno REST, cada URL es un recurso único. ¿Cuales son tus recursos? Una calculadora financiera realmente no tiene recursos obvios. Necesita profundizar en lo que está llamando parámetros y extraer los recursos. Por ejemplo, un calendario de amortización para un préstamo podría ser un recurso. La URL del calendario puede incluir la fecha de inicio, el plazo (en meses o años), el período (cuando el interés se capitaliza), la tasa de interés y el principio inicial. Con todos esos valores, tiene un calendario de pagos específico:
Ahora, no sé lo que está calculando, pero su concepto de una lista de parámetros no parece RESTful. Como alguien más dijo, sus requisitos anteriores suenan más XMLRPC. Si está intentando REST, necesita sustantivos. Los cálculos no son sustantivos, son verbos que actúan sobre sustantivos. Necesitas darle la vuelta para sacar los sustantivos de tus calcs.
fuente