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

Swagger Laravel Package

exsyst/swagger

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to Begin

  1. Installation

    composer require exsyst/swagger
    

    Add to composer.json if using a monorepo or custom package structure.

  2. Load an Existing Swagger/OpenAPI Spec

    use EXSyst\Swagger\Swagger;
    
    $swagger = Swagger::fromFile(base_path('api.json')); // Load from file
    // OR
    $swagger = new Swagger($specArray); // Load from array
    
  3. First Use Case: Inspect Paths

    $paths = $swagger->getPaths();
    foreach ($paths as $path) {
        echo $path->getPath(); // Output: /users, /products, etc.
    }
    

Where to Look First

  • Swagger class: Entry point for all operations.
  • Paths and Definitions collections: Core for managing API endpoints and models.
  • Model classes (e.g., Path, Operation, Schema): Represent OpenAPI spec components.

Implementation Patterns

Common Workflows

1. Dynamic API Documentation Generation

  • Pattern: Use the package to programmatically build a Swagger spec from Laravel routes or database-driven API definitions.
  • Example:
    $swagger = new Swagger();
    $paths = $swagger->getPaths();
    $paths->add(new Path('/api/users', [
        'get' => new Operation(['summary' => 'List users']),
    ]));
    $swagger->toFile(base_path('generated-api.json'));
    

2. Validation and Transformation

  • Pattern: Validate incoming Swagger specs or transform them for consistency.
  • Example:
    $swagger = Swagger::fromFile('external-api.json');
    if ($swagger->isValid()) {
        $swagger->normalize(); // Standardize naming/conventions
        $swagger->toFile('normalized-api.json');
    }
    

3. Integration with Laravel Routes

  • Pattern: Sync Laravel route definitions to Swagger specs during deployment.
  • Example:
    Route::get('/users', function () {
        return User::all();
    })->middleware('api');
    
    // In a service provider or command:
    $swagger = new Swagger();
    $paths = $swagger->getPaths();
    $paths->add(new Path('/users', [
        'get' => new Operation([
            'tags' => ['Users'],
            'responses' => ['200' => new Response(['description' => 'List of users'])],
        ]),
    ]));
    

4. Schema Management

  • Pattern: Manage OpenAPI definitions (or components/schemas) dynamically.
  • Example:
    $definitions = $swagger->getDefinitions();
    $definitions->add('User', new Schema([
        'type' => 'object',
        'properties' => [
            'id' => ['type' => 'integer'],
            'name' => ['type' => 'string'],
        ],
    ]));
    

Integration Tips

  • Use with darkaonline/l5-swagger: Combine this package with Laravel-specific Swagger generators (e.g., darkaonline/l5-swagger) for route-to-spec conversion, then use exsyst/swagger for post-processing.

    // Example: Extend a generated spec
    $spec = (new L5Swagger\Generator)->openapi();
    $swagger = new Swagger($spec);
    $swagger->getInfo()->setTitle('Enhanced API');
    
  • Leverage Collections: Use Paths and Definitions collections to iterate, filter, or modify specs programmatically. Example:

    $swagger->getPaths()->filter(function ($path) {
        return str_starts_with($path->getPath(), '/admin');
    });
    
  • Event-Driven Workflows: Trigger spec updates on model/route changes (e.g., using Laravel events or queue jobs).


Gotchas and Tips

Pitfalls

  1. Deprecated OpenAPI 2.0 Support:

    • The package primarily targets OpenAPI 3.x, but some methods may behave unexpectedly with Swagger 2.0 (swagger:) specs. Validate specs explicitly:
      if (!$swagger->isValid()) {
          throw new \RuntimeException('Invalid OpenAPI spec');
      }
      
  2. Immutable Models:

    • Some models (e.g., Path, Operation) are immutable after creation. Use setters or constructors to modify properties:
      // Wrong (throws error):
      $path->setPath('/new-path');
      
      // Correct:
      $path = new Path('/new-path', $path->getOperations());
      
  3. File Handling:

    • Swagger::fromFile() and toFile() assume UTF-8 encoding. For non-UTF-8 files, decode manually:
      $content = file_get_contents('api.json');
      $swagger = new Swagger(json_decode($content, true));
      
  4. Circular References:

    • Deeply nested specs (e.g., recursive schemas) may cause memory issues. Use json_encode() with JSON_UNESCAPED_SLASHES for debugging:
      $json = json_encode($swagger->toArray(), JSON_UNESCAPED_SLASHES);
      

Debugging Tips

  • Validate Specs Early: Use isValid() to catch malformed specs before processing:

    if (!$swagger->isValid()) {
        echo $swagger->getErrors(); // Dump validation errors
    }
    
  • IDE Autocompletion: The package’s models mirror OpenAPI spec structure. Use your IDE’s PHPStan or Psalm integration to resolve types:

    /** @var \EXSyst\Swagger\Path $path */
    $path = $swagger->getPaths()->get('/users');
    
  • Diffing Specs: Compare specs before/after changes using json_diff or spatie/array-to-xml:

    $before = json_encode($swagger1->toArray());
    $after = json_encode($swagger2->toArray());
    echo json_diff($before, $after);
    

Extension Points

  1. Custom Validators: Extend EXSyst\Swagger\Validator to add domain-specific rules:

    class CustomValidator extends \EXSyst\Swagger\Validator {
        public function validate($spec) {
            parent::validate($spec);
            if (!isset($spec['servers'])) {
                $this->errors[] = 'Missing servers definition';
            }
        }
    }
    
  2. Plugin System: Use anonymous functions or closures to modify specs during initialization:

    $swagger = new Swagger($specArray);
    $swagger->getInfo()->setVersion('1.0.0');
    $swagger->getPaths()->each(function ($path) {
        $path->getOperations()->each(function ($op) {
            $op->setDeprecated(false);
        });
    });
    
  3. Event Listeners: Attach listeners to Paths/Definitions collections for reactive updates:

    $paths = $swagger->getPaths();
    $paths->on('add', function ($path) {
        Log::info("Added path: {$path->getPath()}");
    });
    
  4. Hybrid Specs: Merge multiple specs (e.g., core API + modular extensions):

    $base = Swagger::fromFile('base.json');
    $extension = Swagger::fromFile('extension.json');
    $merged = $base->merge($extension);
    
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.
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle
dmstr/api-platform-utils-bundle
dmstr/api-configuration-bundle
chrisdev/ux-components
baks-dev/finances
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle