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

Open Api 3 Laravel Package

jane-php/open-api-3

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the Package:

    composer require jane-php/open-api-3
    

    Ensure your Laravel project uses PHP 8.0+ and has a PSR-7 HTTP client (e.g., guzzlehttp/psr7).

  2. Prepare Your OpenAPI Spec:

    • Store your OpenAPI 3.x spec (JSON/YAML) in a file, e.g., config/api-spec.json.
    • Example structure:
      {
        "openapi": "3.0.0",
        "info": { "title": "My API", "version": "1.0.0" },
        "paths": { ... }
      }
      
  3. Generate the Client: Add a custom Artisan command (e.g., GenerateApiClient) in app/Console/Commands:

    use Jane\OpenApi\Generator;
    use Jane\OpenApi\Reader;
    use Illuminate\Console\Command;
    
    class GenerateApiClient extends Command
    {
        protected $signature = 'api:generate {--spec= : Path to OpenAPI spec}';
        protected $description = 'Generate a PHP client from an OpenAPI spec';
    
        public function handle()
        {
            $specPath = $this->option('spec') ?? config('api.spec_path');
            $reader = new Reader();
            $spec = $reader->readFromFile($specPath);
            $generator = new Generator();
            $client = $generator->generate($spec, 'ApiClient');
    
            // Save to app/ApiClient/Client.php (or use a trait)
            file_put_contents(app_path('ApiClient/Client.php'), $client);
            $this->info('Client generated successfully!');
        }
    }
    

    Register the command in app/Console/Kernel.php:

    protected $commands = [
        \App\Console\Commands\GenerateApiClient::class,
    ];
    
  4. First Usage: Call the generated client in a service:

    use App\ApiClient\Client;
    
    class MyService
    {
        public function __construct(private Client $client) {}
    
        public function fetchUser($id)
        {
            return $this->client->get("/users/{$id}");
        }
    }
    

    Bind the client in a service provider:

    $this->app->bind(Client::class, function ($app) {
        $spec = (new Reader())->readFromFile(config('api.spec_path'));
        return (new Generator())->generate($spec, 'ApiClient');
    });
    

Implementation Patterns

Core Usage Patterns

  1. PSR-7 Compliance:

    • Generated clients return Psr\Http\Message\RequestInterface and ResponseInterface.
    • Example with Guzzle:
      $client = new \GuzzleHttp\Client(['handler' => HandlerStack::create()]);
      $response = $client->send($generatedRequest);
      
  2. Method Chaining:

    • Leverage Laravel’s service container to chain clients:
      $this->app->bind('auth.client', function ($app) {
          return $app->make(Generator::class)
                      ->generate($authSpec, 'AuthClient');
      });
      
  3. Dynamic Spec Loading:

    • Load specs from environment-specific files (e.g., .env):
      $specPath = config('services.api.spec');
      $spec = (new Reader())->readFromFile($specPath);
      
  4. Authentication:

    • Use OpenAPI’s securitySchemes to auto-generate auth headers:
      # api-spec.yaml
      components:
        securitySchemes:
          api_key:
            type: apiKey
            in: header
            name: X-API-KEY
      
      The generated client will include methods like withApiKey($token).
  5. Request/Response DTOs:

    • Generated clients include typed DTOs for requests/responses (PHP 8 attributes):
      $user = $client->users()->create([
          'name' => 'John Doe',
          'email' => 'john@example.com'
      ]);
      // $user is auto-cast to a typed object (e.g., `UserResponse`)
      

Laravel-Specific Patterns

  1. HTTP Client Integration:

    • Extend Laravel’s HTTP client with generated methods:
      Http::macro('apiGet', function ($uri, $spec) {
          $client = (new Generator())->generate($spec, 'DynamicClient');
          return $client->get($uri);
      });
      
  2. Middleware for Auth:

    • Add auth middleware to the generated client:
      $client = $generator->generate($spec, 'ApiClient');
      $client->getMiddleware()->push(
          \App\Http\Middleware\AuthenticateApi::class
      );
      
  3. Caching Generated Clients:

    • Cache clients in Laravel’s cache (e.g., Redis) if specs rarely change:
      $client = Cache::remember('api.client', now()->addHours(1), function () {
          return $generator->generate($spec, 'CachedClient');
      });
      
  4. Testing with Factories:

    • Use Laravel’s factories to mock API responses:
      $response = new \Psr\Http\Message\Response(
          200,
          [],
          json_encode(['id' => 1, 'name' => 'Test'])
      );
      $client->getMockHandler()->append(
          new \Http\Mock\Handler\MockResponse($response)
      );
      
  5. Event Dispatching:

    • Dispatch events for API calls (e.g., logging, analytics):
      $client->getEventDispatcher()->addListener(
          'api.request.sent',
          function ($request) {
              event(new ApiRequestSent($request));
          }
      );
      

Advanced Patterns

  1. Plugin System:

    • Extend the generator with custom plugins (e.g., for GraphQL or WebSockets):
      $generator->addPlugin(new class implements \Jane\OpenApi\Plugin\PluginInterface {
          public function generate(\Jane\OpenApi\Generator $generator) {
              // Custom logic
          }
      });
      
  2. Async Clients:

    • Use with ReactPHP for async requests:
      $loop = React\EventLoop\Factory::create();
      $client = new \React\Http\Client($loop);
      $promise = $client->sendRequest($generatedRequest);
      $promise->then(...);
      
  3. Spec Validation:

    • Validate specs before generation (e.g., with zircote/swagger-php):
      $validator = new \Zircote\Swagger\Validator();
      $validator->validate(file_get_contents($specPath));
      

Gotchas and Tips

Common Pitfalls

  1. Spec Parsing Errors:

    • Issue: Invalid OpenAPI specs (e.g., missing paths or servers) cause generation failures.
    • Fix: Validate specs with spectral or openapi-linter in CI:
      npx @stoplight/spectral lint api-spec.yaml
      
    • Laravel Tip: Add a spec:validate Artisan command:
      $this->call('vendor:publish', ['--provider' => 'Zircote\Swagger\SwaggerValidatorServiceProvider']);
      
  2. Circular References:

    • Issue: $ref loops in specs (e.g., self-referencing schemas) crash the generator.
    • Fix: Simplify schemas or use allOf/anyOf instead of circular $ref.
  3. PHP 8 Attributes:

    • Issue: Generated DTOs may use PHP 8 attributes (e.g., #[\ArrayShape(['id' => 'int'])]), which break on older PHP versions.
    • Fix: Downgrade PHP or use a custom template to strip attributes.
  4. PSR-7 Handler Conflicts:

    • Issue: Generated clients assume a PSR-7 handler (e.g., Guzzle) is available.
    • Fix: Mock the handler in tests:
      $handler = new \Http\Mock\Handler();
      $client = new \GuzzleHttp\Client(['handler' => $handler]);
      
  5. Namespace Collisions:

    • Issue: Generated classes may conflict with existing Laravel classes (e.g., User).
    • Fix: Use custom templates to prefix class names:
      $generator->setTemplate('class', 'app/ApiClient/Templates/class.stub');
      

Debugging Tips

  1. Verbose Generation:

    • Enable debug output to see generation steps:
      $generator->setDebug(true);
      
  2. Inspect Generated Code:

    • Temporarily save generated classes to a tmp/ directory:
      $generator->setOutputDir(__DIR__.'/tmp');
      
  3. Middleware Debugging:

    • Log middleware execution:
      $client->getMiddleware()->push(function ($request,
      
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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
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
spatie/mailcoach-vapor