resources/views/pages/frontend/docs/api-poliglota-soap-rest.md
Última modificación: 27 Oct, 2026

Arquitectura Dual: RESTful JSON & SOAP/WSDL

Para integrarse tanto con ecosistemas modernos (Apps Móviles, SPAs) como con infraestructuras corporativas tradicionales (Bancos, ERPs, SAP), Mañuti implementa una API Políglota. Una única capa de servicio de negocio atiende simultáneamente a clientes REST (JSON) y SOAP (XML/WSDL) sin duplicar lógica.


1. El Patrón Service Layer como Núcleo Agnóstico

La lógica de negocio reside en App\Services\External\CatalogoService. Esta clase desconoce el protocolo de transporte; únicamente retorna estructuras de datos puras:

flowchart LR
    SERVICE["[CatalogoService]"]
    
    REST_CTRL["[CatalogoRestController]"]
    REST_OUT["Formatea JSON (REST)"]
    
    SOAP_CTRL["[CatalogoSoapController]"]
    SOAP_OUT["Genera WSDL / Procesa XML (SOAP)"]

    SERVICE --> REST_CTRL
    REST_CTRL --> REST_OUT
    
    SERVICE --> SOAP_CTRL
    SOAP_CTRL --> SOAP_OUT
// app/Services/External/CatalogoService.php
namespace App\Services\External;

use App\Models\Catalogo;

class CatalogoService
{
    /**
     * Obtiene opciones activas de un catálogo por su slug.
     * @param string $slug
     * @return array
     */
    public function getOptions(string $slug): array
    {
        $padre = Catalogo::where('catalogo', $slug)->first();
        if (!$padre) return [];

        return $padre->hijos()
            ->where('activo', 'true')
            ->orderBy('orden', 'asc')
            ->get(['id', 'etiqueta', 'valor'])
            ->toArray();
    }

    public function ping(): string
    {
        return "Pong! Servicio operativo: " . now()->toDateTimeString();
    }
}

2. API RESTful (JSON)

Diseñada bajo los estándares HTTP modernos, protegida por tokens de Laravel Sanctum:

  • Endpoint: GET /api/v1/catalogos/{slug}
  • Encabezados Requeridos:
    • Accept: application/json
    • Authorization: Bearer 1|AbCdEf123...
// app/Http/Controllers/Api/Rest/CatalogoRestController.php
public function index(string $slug): JsonResponse
{
    $data = $this->catalogoService->getOptions($slug);

    return response()->json([
        'success' => true,
        'data'    => $data
    ]);
}

3. API SOAP Empresarial (XML / WSDL Dinámico)

Implementada mediante la biblioteca laminas/laminas-soap, expone un WSDL autogenerado mediante inspección de tipos PHP (Reflection) y atiende llamadas remotas RPC:

Endpoints

  • WSDL Contract (GET): http://dominio/api/soap/catalogos
  • Operaciones RPC (POST): http://dominio/api/soap/catalogos
// app/Http/Controllers/Api/Soap/CatalogoSoapController.php
namespace App\Http\Controllers\Api\Soap;

use App\Http\Controllers\Controller;
use App\Services\External\CatalogoService;
use Laminas\Soap\AutoDiscover;
use Laminas\Soap\Server;

class CatalogoSoapController extends Controller
{
    public function wsdl(): void
    {
        $autodiscover = new AutoDiscover();
        $autodiscover->setClass(CatalogoService::class);
        $autodiscover->setUri(route('api.soap.endpoint'));

        header('Content-Type: application/xml');
        echo $autodiscover->generate()->toXml();
        exit;
    }

    public function handle(): void
    {
        $server = new Server(route('api.soap.wsdl'), [
            'cache_wsdl' => WSDL_CACHE_NONE,
        ]);
        $server->setClass(CatalogoService::class);
        $server->handle();
        exit;
    }
}

Configuración Crítica de Nginx para PHP-FPM

Para evitar el error de constantes indefinidas SOAP_1_1, el socket de Nginx debe enlazar exactamente a la versión de PHP con la extensión compilada:

location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php8.5-fpm.sock; # Garantizar versión que posee php8.5-soap
    fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    include fastcgi_params;
}

Enlaces Relacionados

Edita este documento en >> api-poliglota-soap-rest.md
← Volver a la Landing Page