Descripción general
Elimina el cuello de botella de tener que escribir el mismo contrato API y tipos dos veces mientras se desarrolla el backend y el frontend juntos, y explica el contexto y los principios que transforman el trabajo de desarrollo repetitivo, incluyendo cadenas de campo de router, handler y MongoDB, en generación basada en el source.
Historia de origen
trabajo en conjunto con el backend y el frontend. Al crear una función, escribí el endpoint y los DTO de solicitud/respuesta en Java WebFlux, y luego en el frontend tuve que escribir el mismo URL y tipo de TypeScript. Para alinear la documentación de Swagger, repetidamente trasladé información ya existente en el backend a otro formato.
el mayor cuello de botella fue reescribir el contrato API creado en el backend en un formato que el frontend pudiera usar. Si uno de los URL, método HTTP, parámetros de ruta/consulta o la estructura de solicitud/respuesta se modificaba de manera diferente en ambos lados, el problema se descubría más tarde que la compilación. Más allá de ser simplemente una molestia, la discrepancia que surge al gestionar la misma información dos veces es un problema mayor.
también quería reducir la repetición al crear nuevas RouterFunction y handlers. Si añadí una referencia como ApiAccountHandler::search al router, pensé que al menos se debería generar automáticamente una clase handler y un esqueleto de método que no existan.
así, primero se crearon la generación de Swagger/OpenAPI, la generación de esqueleto de handler y la generación de enum de campos de entidad de Mongo. Aunque parecen ideas separadas, el punto de partida es el mismo. Se trata de que la información ya escrita en el código fuente del backend no sea reescrita por humanos, y que las partes que pueden ser leídas por máquinas sean generadas por herramientas de desarrollo.
Filosofía de desarrollo
se basa en el código fuente del backend
utiliza la información ya existente en RouterFunction, handlers, DTO y entidades como la fuente original para la documentación API y el código generado. La clave es no gestionar el mismo contrato en un archivo separado.
elige la automatización en el tiempo de desarrollo sobre la magia en tiempo de ejecución
no es un framework que intercepte solicitudes de producción, sino que analiza las fuentes en un entorno de desarrollo local y genera archivos reales. Puedes verificar los resultados visualmente y gestionarlos en versiones.
sigue las convenciones del proyecto de manera predecible
no tiene como objetivo un compilador universal que entienda todo el código Java. Prefiero analizar la estructura del endpoint funcional de WebFlux que realmente uso con reglas claras.
elimina las secciones de conexión repetitivas
crea Swagger en el endpoint del backend y conecta el generador del frontend que lee ese documento para crear el servicio y el tipo en una cadena de automatización.
¿Qué se lee en el backend?
fuente de RouterFunction
Lee el método HTTP, la ruta anidada, la referencia del método del controlador y el predicado.
Fuente del controlador
Lee el cuerpo de la solicitud, los valores de consulta/ruta y el tipo de publicador de respuesta.
DTO de Solicitud / Respuesta
Conecta el tipo de Java ya escrito en el backend con el esquema OpenAPI.
Fuente de entidad Mongo
Lee el nombre bruto de almacenamiento del campo Java y @Field, y la colección de @Document.
Controlador RSocket
Lee la ruta @MessageMapping y el tipo de carga útil de solicitud/respuesta.
¿Qué se crea en lugar de escribir repetidamente?
swagger.json
Convierte el endpoint REST en un contrato API que el servicio frontal y el generador de tipos TypeScript pueden usar.
asyncapi-rsocket.json
Convierte la ruta RSocket y la carga útil en un contrato que el generador de cliente RSocket frontal puede leer.
Fuente del controlador
Genera y corrige la estructura de clase y método basada en la referencia del controlador que se escribió primero en RouterFunction.
{Entity}Fields enum
Crea un enum para el nombre bruto de almacenamiento y el campo Java de la entidad para no repetir el nombre del campo de cadena.
CollectionNames enum
Genera para poder usar el nombre de colección declarado en @Document en lugar de una cadena.
Flujo de automatización en el proyecto actual
• Escribe RouterFunction, controlador y DTO de solicitud/respuesta Java en el backend.
• El watcher del perfil local detecta cambios en la fuente y actualiza swagger.json o asyncapi-rsocket.json.
• El script de generación de @byeolnaerim/typed-rx-http lee la documentación y genera funciones de servicio y tipos TypeScript.
• En el código de la pantalla, se importan las funciones generadas sin reescribir la URL y el tipo de respuesta.
• Cuando la entidad cambia, también se actualizan el enum de campos utilizados en la consulta y el enum de colecciones.