Modular API Gateway System with Laravel 11

Modular API Gateway System with Laravel 11

The Challenge

When I joined the backend project at Grupo Antyr, we faced a complex architectural challenge: we needed a system capable of orchestrating more than 10 different business domains (credits, inventory, sales, customers, payments, etc.) so that each could be deployed independently without affecting the rest of the system.

The main problem was that the legacy system had all domains intertwined, making it impossible to make changes without risking breaking functionalities in other modules. A simple deploy could take hours of testing and coordination.

The Documentation Problem

But there was another equally critical challenge: keeping documentation updated for multiple teams. The frontend team, mobile teams, and various international partners consumed these APIs, and every change generated:

  • Endless meetings to explain endpoint changes
  • Outdated documentation in wikis and Postman collections
  • Support tickets for “the API is not working” (when it was just a renamed field)
  • Development friction due to lack of clear contracts

We needed a solution that would:

  1. Generate documentation automatically from code
  2. Be always synchronized with reality
  3. Be organized by modules for easy navigation
  4. Comply with OpenAPI 3.0 standards for interoperability

The Solution: HMVC Architecture

We designed and implemented an HMVC (Hierarchical Model-View-Controller) architecture in Laravel 11 that acts as a modular API Gateway. The core idea was simple but powerful: each business domain behaves as a self-contained module with its own logic, routes, controllers, and models.

Key Components

1. Independent Modules Each domain is a complete Laravel module with its own structure:

Modules/
├── Credits/
│   ├── Routes/
│   ├── Controllers/
│   ├── Models/
│   ├── Services/
│   └── Tests/
├── Inventory/
├── Sales/
└── ...

2. Service Layer I implemented a robust service layer that handles the business logic. This keeps the controllers thin and facilitates testing:

  • Services for complex operations
  • Repositories for data access
  • DTOs (Data Transfer Objects) for transfer between layers

3. Redis for Performance I integrated Redis for:

  • Smart caching of frequent responses
  • Storage of tokens and permissions (abilities with SHA-256)
  • Drastic reduction of database queries

4. Automatic OpenAPI Documentation with Custom Scramble

We chose Laravel Scramble to generate OpenAPI documentation automatically from code. The problem: Scramble out-of-the-box does not support module organization in its visual interface.

The Challenge: We needed the documentation to show endpoints grouped by modules (Credits, Inventory, Sales, etc.) so consumers could easily navigate them.

The Solution: We extended Scramble by creating a custom InfoExtractor that:

// Custom InfoExtractor for modules
class ModuleInfoExtractor extends InfoExtractor
{
    public function extract(): OpenApi
    {
        $openApi = parent::extract();
        
        // Group endpoints by module using tags
        foreach ($openApi->paths as $path => $pathItem) {
            $module = $this->extractModuleFromPath($path);
            foreach ($pathItem->operations() as $operation) {
                $operation->tags = [$module];
            }
        }
        
        return $openApi;
    }
    
    private function extractModuleFromPath(string $path): string
    {
        // /api/v1/credits/... → Credits
        preg_match('#/api/v1/([^/]+)/#', $path, $matches);
        return ucfirst($matches[1] ?? 'General');
    }
}

We also customized the Scramble Blade view to display a sidebar with module navigation:

{{-- resources/views/vendor/scramble/index.blade.php --}}
<div class="flex h-screen">
    <div class="w-64 bg-gray-900 overflow-y-auto">
        @foreach($modules as $module)
            <div class="px-4 py-2">
                <h3 class="text-teal-300 font-bold">{{ $module }}</h3>
                <ul class="text-sm text-gray-400">
                    @foreach($endpointsByModule[$module] as $endpoint)
                        <li>{{ $endpoint->method }} {{ $endpoint->path }}</li>
                    @endforeach
                </ul>
            </div>
        @endforeach
    </div>
    <div class="flex-1">
        {{-- Original Scramble content --}}
    </div>
</div>

Result: Automatic documentation, organized by modules, always updated.

This completely eliminated the technical debt of manual documentation and improved communication with international partners. Frontend developers now simply visit /docs/api and have everything up to date.

Measurable Results

Independent Deployments: Now each module is deployed without affecting others
Latency Reduction: Redis reduced DB queries by 70%
Deploy Time: From 3+ hours to less than 30 minutes
Updated Documentation: OpenAPI always synchronized with the code
Scalability: Ability to add new modules without modifying the core

Key Learnings

1. Architecture Matters More Than the Framework

Laravel is excellent, but the right architecture is what truly scales. HMVC gave us:

  • Clear separation of concerns
  • Long-term maintainability
  • Easier onboarding of new developers

2. Automatic Documentation Is Not Optional

Scramble was a game-changer, although we had to extend it. Automatically generated documentation:

  • Is always updated
  • Reduces alignment meetings
  • Facilitates integration with partners

But the most important learning: Do not be afraid to customize your tools. Scramble didn’t support modules out-of-the-box, but with a custom InfoExtractor and a customized Blade view, we adapted it perfectly to our needs.

3. Redis is Your Best Friend

Well-implemented caching not only improves performance, it also reduces infrastructure costs and improves user experience.

4. Testing from the Start

Each module has its own test suite. This gave us the confidence to refactor and add features without fear.

Technical Stack

  • Backend: Laravel 11 (PHP 8.2+)
  • Architecture: HMVC pattern
  • Cache: Redis 7.x
  • Documentation: OpenAPI 3.0 (Scramble)
  • Database: MySQL 8.0
  • Containerization: Docker
  • Testing: PHPUnit + Pest

Conclusion

This project taught me that the right architecture can transform a monolithic system into a scalable modular platform without the need for full microservices. HMVC in Laravel gave us the perfect balance between monolith and microservices.

The key to success was:

  1. Modularity by design
  2. Strategic caching
  3. Automatic documentation
  4. Exhaustive testing

If you are facing similar scalability problems in your monolith, consider HMVC before jumping straight into microservices. Sometimes, the simplest solution is the right one.


Questions about the implementation? Do not hesitate to contact me on LinkedIn or GitHub.

Artículos relacionados