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í:
<html>
<head>
...
</head>
<body>
<form action="/../someResource" method="post" enctype="application/x-www-form-urlencoded">
<label for="firstNumber">First number:</label>
<input type="number" id="firstNumber" name="firstNumber"/>
<label for="secondNumber">Second number:</label>
<input type="number" id="secondNumber" name="secondNumber"/>
<input type="submit" value="Add numbers"/>
</form>
</body>
</html>
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 ingresamos 1
en el firstNumber
campo de entrada y 2
en el secondNumber
campo de entrada, el navegador generará una representación firstNumber=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í:
POST /../someResource
Host: www.acme.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 28
Accept: application/html
firstNumber=1&secondNumber=2
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 de PATCH
. 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:
Un servidor de origen DEBE verificar que la representación de PUT sea consistente con cualquier restricción que el servidor tenga para el recurso de destino que el PUT no pueda o no cambie. Esto es particularmente importante cuando el servidor de origen usa información de configuración interna relacionada con el URI para establecer los valores para los metadatos de representación en las respuestas GET. Cuando una representación PUT es inconsistente con el recurso de destino, el servidor de origen DEBE hacerlos consistentes, transformando la representación o cambiando la configuración del recurso, o responder con un mensaje de error apropiado que contenga información suficiente para explicar por qué la representación no es adecuada. Se sugieren los códigos de estado 409 (Conflicto) o 415 (Tipo de medio no admitido),
Por ejemplo, si el recurso de destino está configurado para tener siempre un Tipo de contenido de "texto / html" y la representación PUT tiene un Tipo de contenido de "imagen / jpeg", el servidor de origen debe hacer uno de:
a. reconfigurar el recurso objetivo para reflejar el nuevo tipo de medio;
si. transformar la representación PUT a un formato coherente con el del recurso antes de guardarlo como el nuevo estado del recurso; o,
C. rechazar la solicitud con una respuesta 415 (tipo de medio no admitido) que indica que el recurso de destino está limitado a "texto / html", tal vez incluyendo un enlace a un recurso diferente que sería un destino adecuado para la nueva representación.
HTTP no define exactamente cómo un método PUT afecta el estado de un servidor de origen más allá de lo que puede expresarse por la intención de la solicitud del agente de usuario y la semántica de la respuesta del servidor de origen. ...
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 atext/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.