Skip to content

Implementación Endpoints V3 de Ofertas en sw-api

1. Contexto

Este documento describe el plan para implementar los endpoints de la API REST V3 relacionados con la obtención de ofertas (/rest/v3/offers y /rest/v3/offer) dentro de la aplicación sw-api.

La especificación general de la API V3 (incluyendo los endpoints originales y su propósito) puede consultarse en lib-docs/switchain/files/restApiV3.js, aunque la implementación actual diferirá como se describe a continuación.

Esta implementación forma parte de una migración mayor desde un sistema legado basado en Meteor y MongoDB hacia una arquitectura moderna con TypeScript, NodeJS, base de datos relacional (gestionada con Prisma) y siguiendo principios de Domain-Driven Design (DDD) y Arquitectura Hexagonal.

Flujo de Datos Esperado (Actualizado):

  1. El paquete packages/rates (y su correspondiente worker apps/rates) es responsable de calcular periódicamente las ofertas disponibles para cada appId (API Key de partner) y almacenarlas en caché en Redis.
  2. El paquete packages/rates expone un controlador, pairOffersRetriever (accesible a través del objeto exportado RatesControllers en packages/rates/index.ts), que encapsula la lógica para leer estas ofertas cacheadas desde Redis dado un appId.
  3. La aplicación sw-api expondrá los endpoints V3 (/rest/v3/offers y /rest/v3/offer).
  4. Cuando sw-api reciba una petición a un endpoint de ofertas, deberá:
    • Autenticar la petición y extraer el appId (API Key) del contexto de la petición.
    • Importar RatesControllers desde @sws/rates.
    • Llamar directamente al método run() del controlador RatesControllers.pairOffersRetriever con el appId.
    • Para /rest/v3/offer, filtrar la lista completa de ofertas obtenida basándose en los parámetros de consulta (pair, chainPair, amountFrom) dentro del manejador de la ruta.
    • Formatear y devolver la respuesta según la especificación de la API V3.

Arquitectura Simplificada:

La implementación en sw-api seguirá una estructura simplificada para estos endpoints:

  • Domain: Mínimo, principalmente para definir la estructura de la respuesta (DTOs).
  • Application: No se crearán servicios específicos para ofertas en sw-api/application. La lógica reside en el controlador de packages/rates.
  • Infrastructure:
    • Controladores: No se crearán controladores específicos para ofertas en sw-api/infrastructure/controllers.
    • Rutas (V3Routes.ts): Se añadirán las rutas /rest/v3/offers y /rest/v3/offer. Los manejadores de estas rutas importarán RatesControllers y llamarán directamente a RatesControllers.pairOffersRetriever.run(). La lógica de filtrado para /rest/v3/offer se implementará aquí.
    • Fábricas: No se requiere una OfferFactory específica en sw-api para instanciar el controlador, ya que se importa directamente la instancia preconfigurada desde @sws/rates.

2. Endpoints a Implementar (Basado en restApiV3.js)

  • GET /rest/v3/offers: Devuelve la lista completa de ofertas disponibles para el appId asociado a la API Key de la petición.
  • GET /rest/v3/offer: Devuelve una oferta específica basada en parámetros de consulta (pair, chainPair, amountFrom).

3. Plan de Implementación Detallado (Actualizado)

Paso 1: Definir/Reutilizar Componentes del Dominio (sw-api/domain)

  1. Value Objects / DTOs:
    • ApiKey: Asegurar que el tipo ApiKey (probablemente string) esté disponible en el contexto de la ruta (inyectado por el middleware de autenticación).
    • PairOfferDto: Definir un DTO en sw-api que represente la estructura de una oferta devuelta por RatesControllers.pairOffersRetriever y que coincida con el formato esperado por la respuesta de la API V3. Es crucial conocer la estructura exacta devuelta por el controlador de rates. Esta estructura debe obtenerse del propio controlador RatesControllers.pairOffersRetriever en @sws/rates, ya que la documentación en restApiV3.js describe la implementación anterior.

Paso 2: Implementar Lógica de Aplicación (sw-api/application)

  • Omitido: No se crearán servicios de aplicación específicos para ofertas en sw-api.

Paso 3: Configurar Infraestructura (sw-api/infrastructure)

  1. Fábricas (sw-api/infrastructure/factories/):
    • Omitido: No se necesita una OfferFactory para las ofertas.
  2. Controlador (sw-api/infrastructure/controllers/):
    • Omitido: No se necesita un OffersController.
  3. Rutas (V3Routes.ts en sw-api/infrastructure/routes/):
    • Importar RatesControllers desde @sws/rates.
    • Registrar las rutas GET /rest/v3/offers y GET /rest/v3/offer usando Elysia.
    • En el manejador de GET /rest/v3/offers:
      • Extraer el ApiKey del contexto.
      • Llamar a RatesControllers.pairOffersRetriever.run(apiKey).
      • Formatear la respuesta HTTP (código 200, cuerpo { data: [...] }).
    • En el manejador de GET /rest/v3/offer:
      • Extraer el ApiKey y los parámetros de consulta (pair, chainPair, amountFrom).
      • Llamar a RatesControllers.pairOffersRetriever.run(apiKey).
      • Filtrar la lista de ofertas devuelta según los parámetros de consulta.
      • Formatear la respuesta HTTP (código 200 con { data: {...} } si se encuentra, o error 404 si no).
    • Asegurar que el middleware de autenticación que extrae/valida la API Key se aplique a estas rutas.

Paso 4: Middleware de Autenticación (Revisión/Ajuste)

  • Verificar que el middleware de autenticación existente en sw-api extrae correctamente el ApiKey (probablemente del header Authorization o similar) y lo pone a disposición del controlador o del contexto de la petición.
  • Asegurar que el ApiKey validado pueda ser fácilmente inyectado o accedido por el controlador o del contexto de la petición.

Paso 5: Pruebas

  • Unitarias: Probar directamente los manejadores de ruta en V3Routes.ts, utilizando mocks para RatesControllers.pairOffersRetriever y el middleware de autenticación. Enfocarse en la lógica de filtrado para /rest/v3/offer.
  • Integración: Probar las rutas completas desde la petición HTTP hasta la ejecución del controlador de rates (idealmente conectando con una instancia de Redis de prueba poblada con datos). Verificar la correcta autenticación, el paso de parámetros, el filtrado y el formato de respuesta.

4. Consideraciones Adicionales (Actualizado)

  • Dependencias: Gestionar correctamente la dependencia de sw-api hacia packages/rates.
  • Tipos de Datos: Es fundamental conocer la estructura exacta de los datos devueltos por RatesControllers.pairOffersRetriever.run() para poder definir el PairOfferDto en sw-api y realizar el filtrado correctamente. Será necesario inspeccionar el código de @sws/rates o añadir tipos compartidos, ya que la documentación en restApiV3.js no refleja la implementación actual.
  • Configuración del Controlador de Rates: La instancia importada RatesControllers.pairOffersRetriever ya debería estar configurada (incluyendo la conexión Redis) por la PairOfferFactory dentro del paquete rates.
  • Manejo de Errores: Definir cómo se manejarán los errores devueltos por RatesControllers.pairOffersRetriever.run() (ej., Redis no disponible, API Key no encontrada) en los manejadores de ruta de sw-api y cómo se traducirán a respuestas HTTP.
  • Filtrado para /rest/v3/offer: La lógica de filtrado residirá en el manejador de la ruta en V3Routes.ts.

5. Próximos Pasos

  1. Validar este plan actualizado.
  2. Proceder con la implementación paso a paso según lo definido.