Search by

poagen / client-generator

mlavrinenko

OpenAPI-driven PHP client generator producing typed, extensible clients.

Package info

github.com/mlavrinenko/poagen

pkg:composer/poagen/client-generator

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

0.1.0 2026-11-02 22:45 UTC

This package is auto-updated.

Last update: 2026-11-03 06:47:42 UTC


README

poagen

OpenAPI-driven PHP client generator producing typed, extensible clients.

Documentation · Quickstart

poagen reads an OpenAPI 3.0 or 3.1 document and emits a PHP 8.4 HTTP client. The generated tree is disposable: every run rewrites it whole, and your own code lives beside it. The output is deterministic, so a diff after regeneration shows only real changes.

Why poagen

  • Typed. Exhaustive PHPStan annotations, backed enums, readonly models, and one method per operation.
  • Extensible. Guidance lives in a typed Profile and in attributes on your own value objects, never in an edit to generated code.
  • PSR-aligned. The emitted client depends on PSR-18, PSR-17 and PSR-7, so Guzzle, Symfony HTTP Client, or anything else that implements them plugs in.
  • Fail loud. An unsupported construct stops the run by name. poagen never drops an operation and calls the result a success.
  • Proven on real documents. Petstore, DigitalOcean, GitHub, and kilbil’s loyalty API all generate and pass their own gates.

Install

The runtime goes in require, because generated code runs in production. The generator goes in require-dev, because it only runs while you generate:

composer require poagen/client-runtime
composer require --dev poagen/client-generator

Quickstart

Write a profile:

<?php

declare(strict_types=1);

use Poagen\Generator\Generator\Profile;

return new Profile(
    schema: __DIR__ . '/schemas/petstore-3.0.yaml',
    output: __DIR__ . '/generated',
    namespace: 'App\\Petstore',
);

Generate:

vendor/bin/poagen generate poagen.php

Use the client:

use App\Petstore\Generated\ApiClient;
use App\Petstore\Generated\ApiException;
use Poagen\Runtime\Http\HttpTransport;

$client = new ApiClient(
    new HttpTransport(ApiClient::SERVER_1, ApiException::class),
    apiKey: $apiKey,
    petstoreAuth: $token,
);

$response = $client->pet()->getPetById(1);

echo $response->body?->name;

Every operation returns an Envelope carrying ->status, ->body and the PSR-7 ->response. A declared non-2xx status is a value to inspect, not an exception.

Documentation

  • Quickstart takes you from an empty project to a first response.
  • Installation covers requirements and versions.
  • Profile is the configuration reference.
  • Generated code explains models, enums, clients and envelopes.
  • Formats covers value objects, codecs and date-time zones.
  • CLI covers generate, validate, dry runs and diffs.
  • Examples shows the four real documents.
  • Status lists what poagen refuses by name.

Contributing

See CONTRIBUTING.md. The project’s decisions and specs live under truth/, next to the code they describe.

License

MIT.