Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Api Versioning Bundle Laravel Package

bugloos/api-versioning-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require bugloos/api-versioning-bundle
    

    Add to config/bundles.php:

    return [
        // ...
        Bugloos\ApiVersioningBundle\BugloosApiVersioningBundle::class => ['all' => true],
    ];
    
  2. Basic Configuration Publish the default config:

    php artisan vendor:publish --provider="Bugloos\ApiVersioningBundle\BugloosApiVersioningBundle" --tag="config"
    

    Edit config/api_versioning.php to define your versioning strategy (e.g., header, query, or path).

  3. First Use Case Annotate a controller method with @ApiVersion("1") to enforce versioning:

    use Bugloos\ApiVersioningBundle\Annotation\ApiVersion;
    
    class UserController extends AbstractController
    {
        /**
         * @ApiVersion("1")
         */
        public function getUser(Request $request)
        {
            // Version 1 logic
        }
    }
    
  4. Testing Use the API_VERSION header or query param (?version=1) to test versioned endpoints.


Implementation Patterns

Versioning Strategies

  • Header-Based (Recommended): Set API_VERSION header (e.g., API_VERSION: 1). Configure in config/api_versioning.php:

    'strategy' => Bugloos\ApiVersioningBundle\Strategy\HeaderStrategy::class,
    
  • Query Parameter: Use ?version=1 in URLs. Configure:

    'strategy' => Bugloos\ApiVersioningBundle\Strategy\QueryStrategy::class,
    
  • Path-Based: Use /v1/users (requires route prefixing; not natively supported by this bundle—see Gotchas).

Workflows

  1. Versioned Controllers: Group versioned logic in separate controllers or methods:

    class V1UserController extends AbstractController
    {
        /**
         * @ApiVersion("1")
         */
        public function index() { /* V1 logic */ }
    }
    
    class V2UserController extends AbstractController
    {
        /**
         * @ApiVersion("2")
         */
        public function index() { /* V2 logic */ }
    }
    
  2. Middleware Integration: Use the bundle’s middleware to enforce versioning globally:

    // config/routes.php
    $kernel->addControllerMiddleware(new ApiVersioningMiddleware());
    
  3. Dynamic Version Switching: Combine with Symfony’s Request to dynamically load versioned services:

    $version = $this->get('api_versioning.version_resolver')->getVersion();
    $service = $this->get(sprintf('app.user_service.%s', $version));
    
  4. Documentation: Use @ApiVersion in PHPDoc to auto-generate API docs (e.g., Swagger/OpenAPI plugins).

Integration Tips

  • API Platform: Extend ApiResource to include versioning metadata:

    #[ApiVersion("1")]
    class User extends ApiResource { ... }
    
  • Event Listeners: Trigger version-specific events:

    $this->get('event_dispatcher')->dispatch(
        new VersionRequestedEvent($version, $request)
    );
    
  • Caching: Cache responses per version:

    $cacheKey = sprintf('api_v%s_%s', $version, $request->getPathInfo());
    

Gotchas and Tips

Pitfalls

  1. Path-Based Versioning Limitation: The bundle does not natively support /v1/endpoint routing. Workaround:

    • Use a custom router or middleware to extract version from path.
    • Example middleware:
      public function handle(Request $request, Closure $next)
      {
          $version = $request->attributes->get('version');
          if ($version) {
              $request->headers->set('API_VERSION', $version);
          }
          return $next($request);
      }
      
      Register in routes.php:
      $kernel->addControllerMiddleware(new ExtractVersionFromPathMiddleware());
      
  2. Annotation Override: @ApiVersion on a method overrides class-level annotations. Test this behavior early.

  3. Symfony 5.4+ Conflicts: If using Symfony 5.4+, ensure api_platform.core.eventlistener is not overriding versioning logic.

  4. Default Version Fallback: The bundle throws a VersionNotFoundException if no version is provided. Configure a default in config/api_versioning.php:

    'default_version' => '1',
    

Debugging

  • Check Resolved Version: Log the resolved version in middleware:

    $version = $this->get('api_versioning.version_resolver')->getVersion();
    \Log::debug('Resolved API version:', ['version' => $version]);
    
  • Validate Headers: Ensure API_VERSION header is correctly set (case-sensitive). Use Postman/cURL to test:

    curl -H "API_VERSION: 1" http://your-api/users
    
  • Clear Cache: After config changes, run:

    php artisan cache:clear
    php artisan config:clear
    

Tips

  1. Versioned Routes: Use Symfony’s requirements to enforce versioning in routing:

    # config/routes.yaml
    _api:
      path: /api
      controller: Bugloos\ApiVersioningBundle\Controller\ApiVersioningController::indexAction
      requirements:
        version: \d+
    
  2. Deprecation Warnings: Log warnings for deprecated versions:

    if ($version === '1' && $request->headers->get('X-Request-Id')) {
        \Log::warning('Version 1 is deprecated', ['request_id' => $request->headers->get('X-Request-Id')]);
    }
    
  3. Testing: Use ApiVersioningBundle\Tests\VersionResolverTest as a reference for writing tests:

    $this->client->request('GET', '/users', [], [], [
        'HTTP_API_VERSION' => '1',
    ]);
    
  4. Extension Points:

    • Custom Strategies: Extend Bugloos\ApiVersioningBundle\Strategy\AbstractStrategy for custom version sources (e.g., JWT claims).
    • Event Subscribers: Listen to api_versioning.version_resolved to modify version logic dynamically.
  5. Performance: Cache the VersionResolver service if resolving versions frequently:

    $this->container->get('api_versioning.version_resolver')->setCache($cache);
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky