API Gateway para servicios Swift: cómo unir microservicios en un solo sistema

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

API Gateway para servicios Swift: construyendo un puente entre microservicios

\n\n

Imagine que su backend es un enorme centro comercial. En su interior hay decenas de tiendas (microservicios): autenticación, catálogo de productos, carrito de compras, pagos, notificaciones. El cliente (aplicación iOS) necesita entrar a cada tienda por separado: esto es caos, lento e inseguro. API Gateway es la entrada principal, la seguridad y el navegador en uno solo. Recibe solicitudes, verifica los pases, redirige al departamento correcto y devuelve el resultado.

\n\n

En el mundo de Swift, donde Vapor y Hummingbird están ganando terreno, crear su propio API Gateway no es un lujo, sino una necesidad para proyectos escalables. Hoy analizaremos cómo escribir un gateway ligero en Swift que unifique sus servicios en un solo ecosistema.

\n\n

¿Por qué se necesita un API Gateway en la arquitectura Swift?

\n\n

Cuando tiene 2-3 microservicios, el cliente puede comunicarse directamente con cada uno. Pero cuando tiene 10+ (un escenario típico para fintech, e-commerce o SaaS), surgen problemas:

\n\n
    \n
  • Código cliente inflado — cada servicio tiene su propio endpoint, formato de errores y protocolo de autenticación
  • \n
  • Vulnerabilidades — cada servicio debe encargarse por sí mismo de CORS, rate limiting y verificación de JWT
  • \n
  • Complejidad en la refactorización — ¿Renombró un servicio? Cambie el código en todos los clientes
  • \n
  • Tráfico innecesario — el cliente hace 5 solicitudes en lugar de una para cargar una página
  • \n
\n\n

API Gateway resuelve estos problemas al convertirse en un punto de entrada único. Puede agregar datos de múltiples microservicios en una sola respuesta, aplicar políticas de seguridad y registrar todas las solicitudes. Para los desarrolladores Swift, también es una oportunidad de usar el tipado estricto del lenguaje a nivel del gateway.

\n\n

Elección de la herramienta: Vapor + Hummingbird

\n\n

Para crear un API Gateway en Swift, Vapor es ideal: el framework web más maduro del ecosistema. Proporciona middleware, enrutamiento, solicitudes de cliente (a través de Client) y soporte para async/await. Una alternativa es Hummingbird (ligero, rápido, de Apple), pero para el ejemplo usaremos Vapor por estar mejor documentado.

\n\n

Nuestro gateway realizará tres funciones:

\n
    \n
  • Proxy de solicitudes al microservicio correspondiente
  • \n
  • Autenticación mediante JWT
  • \n
  • Agregación de datos de dos servicios en una sola respuesta
  • \n
\n\n

Paso 1. Estructura básica del proyecto

\n\n

Creamos un nuevo proyecto Vapor:

\n
vapor new APIGateway --template=api\ncd APIGateway
\n\n

Añadimos la dependencia para JWT en Package.swift:

\n
.package(url: "https://github.com/vapor/jwt.git", from: "4.0.0")
\n\n

Y la vinculamos en el target:

\n
.target(name: "App", dependencies: [\n    .product(name: "Vapor", package: "vapor"),\n    .product(name: "JWT", package: "jwt")\n])
\n\n

Paso 2. Middleware para autenticación

\n\n

Creamos un middleware que verifique el token JWT y pase la información del usuario. Este es un patrón clásico para API Gateway en Swift:

\n\n
import Vapor\nimport JWT\n\nstruct JWTAuthenticator: AsyncMiddleware {\n    func respond(to request: Request, chainingTo next: AsyncResponder) async throws -> Response {\n        guard let token = request.headers.bearerAuthorization?.token else {\n            throw Abort(.unauthorized, reason: "Missing Bearer token")\n        }\n        \n        // Verificamos la firma y la fecha de expiración\n        let payload = try await request.jwt.verify(token, as: UserPayload.self)\n        \n        // Guardamos el usuario en el almacenamiento de la solicitud\n        request.storage.set(UserPayloadKey.self, to: payload)\n        \n        return try await next.respond(to: request)\n    }\n}\n\nstruct UserPayload: JWTPayload {\n    var userID: UUID\n    var role: String\n    var exp: ExpirationClaim\n    \n    func verify(using signer: JWTSigner) throws {\n                

Blogs

Book Recommendations