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

Laravel Openapi Cli Laravel Package

spatie/laravel-openapi-cli

Generate Laravel Artisan commands from an OpenAPI spec. Each API endpoint becomes its own command with typed options for params and request bodies, plus auth, base URL, caching, redirects, and output formatting—ideal for building API CLIs with Laravel Zero.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package:

    composer require spatie/laravel-openapi-cli
    

    Publish the config (if needed):

    php artisan vendor:publish --provider="Spatie\OpenApiCli\OpenApiCliServiceProvider"
    
  2. Register an API in a Service Provider:

    use Spatie\OpenApiCli\Facades\OpenApiCli;
    
    OpenApiCli::register('https://api.example.com/openapi.yaml', 'example-api')
        ->baseUrl('https://api.example.com');
    
  3. Run Commands: The package auto-generates commands from the OpenAPI spec. For example, a GET /users endpoint becomes:

    php artisan example-api:get-users
    
  4. First Use Case:

    • List Available Commands:
      php artisan example-api:list
      
    • Call an Endpoint with Parameters:
      php artisan example-api:get-users --limit=10 --offset=20
      

Where to Look First

  • Documentation: Spatie’s OpenAPI CLI Docs for configuration and advanced usage.
  • Generated Commands: Run php artisan to see auto-generated commands (e.g., example-api:get-users).
  • Config File: config/openapi-cli.php for global defaults (e.g., caching, auth).

Implementation Patterns

Core Workflows

1. Registering APIs

  • Basic Registration:
    OpenApiCli::register('path/to/spec.yaml', 'api-prefix');
    
  • Dynamic Registration (e.g., per environment):
    if (app()->environment('staging')) {
        OpenApiCli::register('staging-spec.yaml', 'staging-api');
    }
    

2. Configuring API Clients

  • Authentication:
    ->auth(fn () => 'Bearer ' . $this->getAuthToken())
    
  • Headers:
    ->header('X-Custom-Header', 'value')
    
  • Caching:
    ->cache(ttl: 3600) // Cache responses for 1 hour
    

3. Handling Responses

  • Custom Error Handling:
    ->onError(function ($response, $command) {
        if ($response->status() === 404) {
            $command->error('Resource not found.');
        }
    })
    
  • Retry Logic:
    ->retryOn(function ($response) {
        return $response->status() === 429; // Retry on rate limits
    }, maxRetries: 3)
    

4. Output Formatting

  • JSON/YAML Output:
    ->jsonOutput() // or ->yamlOutput()
    
  • HTML Bodies:
    ->showHtmlBody()
    

5. Laravel Zero Integration

  • Register APIs in a Laravel Zero app’s handle() method:
    OpenApiCli::register('spec.yaml', 'myapp')
        ->banner('My CLI Tool v1.0');
    
  • Expose commands directly to users:
    php myapp get-users --limit=5
    

Integration Tips

With Laravel’s HTTP Client

Use Laravel’s Http facade for custom logic:

->client(fn () => Http::withOptions(['timeout' => 30]))

With Testing

Mock the OpenAPI CLI in tests:

$this->partialMock(Spatie\OpenApiCli\Facades\OpenApiCli::class, ['register']);

With Environment-Specific Configs

Load specs dynamically:

$specPath = config("openapi.specs.{$this->app->environment()}");
OpenApiCli::register($specPath, 'env-api');

With Custom Command Logic

Extend generated commands by binding them to classes:

OpenApiCli::register('spec.yaml', 'api')
    ->bindCommand('get-users', UserCommand::class);

Then implement UserCommand to override behavior.


Gotchas and Tips

Pitfalls

  1. Spec Parsing Errors:

    • Issue: Invalid OpenAPI specs (e.g., missing paths or servers) cause silent failures.
    • Fix: Validate specs using tools like Swagger Editor before registration.
    • Debug: Enable verbose output:
      ->debug()
      
  2. Parameter Name Conflicts:

    • Issue: Path/query parameters with special characters (e.g., -, .) may break CLI parsing.
    • Fix: Use --option syntax explicitly:
      php artisan api:get-user --user-id=123
      
    • Workaround: Rename parameters in the spec or use aliases:
      ->parameterAliases(['user-id' => 'userId'])
      
  3. Caching Quirks:

    • Issue: Cached responses may stale if the spec or API changes.
    • Fix: Invalidate cache manually or use short TTLs:
      ->cache(ttl: 60) // 1-minute cache
      
  4. Authentication Failures:

    • Issue: Dynamic auth closures (e.g., OAuth token refresh) may fail silently.
    • Fix: Add logging or retry logic:
      ->retryOn(function ($response) {
          return $response->status() === 401;
      }, maxRetries: 1)
      ->onError(function ($response) {
          Log::error("Auth failed: {$response->status()}");
      })
      
  5. Command Naming Collisions:

    • Issue: Overlapping command names (e.g., api:list vs. app:list).
    • Fix: Use unique prefixes or namespaces:
      OpenApiCli::register('spec.yaml', 'api_v2')
      

Debugging Tips

  1. Enable Debug Mode:

    OpenApiCli::register('spec.yaml', 'api')->debug();
    
    • Outputs raw HTTP requests/responses to storage/logs/laravel-openapi-cli.log.
  2. Inspect Generated Commands:

    • Run php artisan to list all commands.
    • Check the app/Console/Kernel.php for registered commands.
  3. Validate Specs:

  4. Test Locally:

    • Mock the HTTP client in tests:
      $this->app->instance(\Illuminate\Http\Client\PendingRequest::class, $mockClient);
      

Extension Points

  1. Custom Command Classes:

    • Bind generated commands to custom classes for pre/post-processing:
      OpenApiCli::register('spec.yaml', 'api')
          ->bindCommand('get-users', CustomUserCommand::class);
      
    • Implement handle() in your class to override logic.
  2. Dynamic Spec Loading:

    • Load specs from a database or S3:
      $spec = Storage::disk('s3')->get('specs/api.yaml');
      OpenApiCli::register($spec, 'dynamic-api');
      
  3. Custom Output Formatters:

    • Extend the Spatie\OpenApiCli\Output\OutputFormatter trait to add new formats (e.g., CSV).
  4. Pre/Post-Request Hooks:

    • Use the beforeRequest and afterResponse callbacks:
      ->beforeRequest(function ($request) {
          $request->header('X-Request-ID', Str::uuid());
      })
      
  5. Multi-API Workflows:

    • Chain multiple APIs in a single command:
      OpenApiCli::register('api1.yaml', 'api1')
          ->register('api2.yaml', 'api2');
      
    • Combine results in a custom command.

Performance Tips

  1. Cache Aggressively:

    • Use long TTLs for read-heavy APIs:
      ->cache(ttl: 86400) // 24-hour cache
      
  2. Disable Caching for Dev:

    • Override caching in .env:
      OPEN_API_CLI_CACHE_ENABLED=false
      
  3. Parallel Requests:

    • For batch operations, use Laravel’s Http::parallel() in a custom command.
  4. Spec Minification:

    • Strip unused paths from specs to reduce parsing overhead:
      npx @openapitools/openapi-generator-cli generate -i spec.yaml -g php -o ./ --skip-validate-spec
      

Config Quirks

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.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata