Symfony Bundle · PHP 8.2+ · Packagist

Deja de escribir el mismo cliente HTTP una y otra vez

Un motor de integración para Symfony que centraliza tus APIs externas bajo contratos claros.

undefined composer require carlosgude/integration-engine
Ver en GitHub →

HttpClient envía peticiones. IntegrationEngine estructura integraciones.

Usa HttpClient cuando necesitas una o dos llamadas simples. Usa IntegrationEngine cuando la API forma parte de tu arquitectura y quieres contratos claros, respuestas tipadas y una Anti-Corruption Layer entre el proveedor y tu dominio.

Cada integración acaba siendo un caso aislado

Diferentes formatos, autenticaciones inconsistentes, lógica de cache duplicada. El código se fragmenta y cada nueva API es empezar de cero.

Auth duplicada

Tokens y cache reimplementados en cada integración.

Sin contrato común

Cada cliente HTTP tiene su propia estructura.

Difícil de testear

HTTP acoplado al dominio. Imposible aislar.

Sin consistencia

Cada desarrollador resuelve el problema a su manera.

Cero visibilidad

Sin trazabilidad, sin logs unificados, sin contexto compartido.

Un flujo único para todas tus integraciones

Un único punto de entrada. Cada paso tiene una responsabilidad clara.

Registry
IntegrationEngine
Action
Auth
HTTP
Mapper
Response DTO

Auth dinámica con cache

OAuth, sesiones, API keys. El engine los resuelve y cachea automáticamente.

Context de path

/orders/{id} se resuelve en tiempo de llamada. Fallo explícito si falta parámetro.

Headers en tres capas

YAML → auth → capa de llamada. Cada capa sobreescribe a la anterior. Sin magia.

Respuestas tipadas

Cada acción define su propio Response DTO con contrato garantizado.

Totalmente extensible

Client, cache y config source sustituibles con una línea en YAML.

Scaffolding incluido

make:integration genera Mapper, Response DTO y YAML en segundos.

De cero a integración tipada en segundos.

El comando hace las preguntas. Tú solo escribes la lógica.

$ php bin/console make:integration Github GetUser
config/packages/integration_engine.yaml
src/Infrastructure/Integrations/Github/GithubIntegration.php
src/Infrastructure/Integrations/Github/Github.yaml
src/Infrastructure/Integrations/Github/GetUser/Request/GetUserAction.php
src/Infrastructure/Integrations/Github/GetUser/Response/GetUserMapper.php
src/Infrastructure/Integrations/Github/GetUser/Response/GetUserResponse.php

Una línea. Siempre la misma.

Sin strings mágicos — todo a través de contratos.

// Action path: GET /orders
$this->engine->send(
    GetOrdersAction::getName()
);
// → GET /orders
// Action path: GET /orders/{id}
$response = $this->engine->send(
    actionName: GetOrderAction::getName(),
    context: DefaultActionContext::create(['id' => $id]),
);
// → GET /orders/42

\assert($response instanceof GetOrderResponse);
// GetOrderResponse { id: 42, reference: 'ORD-001', items: [...] }
// Action path: POST /orders
$response = $this->engine->send(
    actionName: CreateOrderAction::getName(),
    body: CreateOrderBody::create(['reference' => 'ORD-001']),
    headers: new CorrelationHeaders($correlationId),
);
// → POST /orders { "reference": "ORD-001" }

\assert($response instanceof CreateOrderResponse);
// CreateOrderResponse { id: 99, reference: 'ORD-001', status: 'pending' }
// Action endpoint: POST /graphql
$response = $this->engine->send(
    actionName: GetOrderAction::getName(),
    body: GetOrderBody::create(['id' => $id]),
);
// → POST /graphql { "query": "...", "variables": { "id": 42 } }

\assert($response instanceof GetOrderResponse);
// GetOrderResponse { id: 42, reference: 'ORD-001', items: [...] }

Para el flujo completo (facade → service → domain) → README →

El bundle propone. No impone.

Tres niveles que emergen solos. Usa los que necesites.

ClaseResponsabilidadAlcance
CreateChargeAction Solo declara el método, el path y el DTO de respuesta. Sin lógica HTTP. Acción concreta
GithubAction Auth, path base y headers comunes de GitHub. Reutilizado por todas sus acciones. Integración
AbstractAction Contrato base que provee el engine. Extensible sin tocar el core. Bundle

El comando make:integration crea el config, las clases y el YAML en un solo paso.

Empieza en un comando

Sin boilerplate. Sin decisiones arbitrarias. Solo tu lógica de negocio.