Download the PHP package codewithagents/openapi-laravel without Composer

On this page you can find all versions of the php package codewithagents/openapi-laravel. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package openapi-laravel

openapi-laravel

CI Latest Version Total Downloads PHP 8.2+

One OpenAPI spec in, a working typed Laravel slice out: laravel-data models, spec-derived validation, native enums, controllers, and routes, out of the box, drift-gated in CI. The spec is the source of truth, your code follows it.

Documentation: openapi-laravel.codewithagents.de

From OpenAPI spec to generated Data classes, validation rules and controllers; you write only business logic; openapi:check fails CI on drift and regeneration never touches your files

Hand-written DTOs, validation rules, and controllers drift from the API contract silently. Nobody notices the missing nullable, the renamed wire field, or the new enum case until production rejects a valid payload, or a consumer files the bug for you. The spec already states every one of those shapes; the drift exists only because humans re-type them.

So make the spec the source of truth and regeneration the sync mechanism. One command emits spatie/laravel-data classes with explicit, spec-derived rules() methods plus native PHP enums, an abstract controller per tag, and a routes file, so the request/response types and the routing table derive from the spec too. When the spec changes, you re-run the generator and review the diff.

Unlike annotation-driven tools that generate a spec from your code, this goes the other way: the spec drives the code. And unlike most generators, the output is not a black box. It is readable, deterministic PHP that lives in your repo and looks like code you would have written yourself.

Sibling project of openapi-zod-ts, which does the same for TypeScript. Both are tested against a shared corpus of real-world public API documents, 135 specs on this side (detailed in Why quality matters below).

The generated classes extend Spatie\LaravelData\Data, so spatie/laravel-data v4 is a runtime peer dependency of your app (a normal require, not require --dev). The generator itself is a dev dependency.


Install

The generator is a dev dependency; spatie/laravel-data is a runtime dependency of your app because the generated classes extend it:

Publish the config (optional):

Quick start

Point it at your spec and generate:

One command emits the full output: Data classes with rules(), native enums, one abstract controller per tag (app/Http/Controllers/Api by default), and a routes/api.generated.php file, all typed against each other. Then scaffold the concrete controllers the routes file references, one time, so the app boots immediately:

Each stub extends its generated abstract controller and implements every operation as an explicit throw new LogicException('Not implemented: ...') placeholder. Existing files are skipped, never overwritten: the stubs are your code from the moment they are written, and openapi:check never inspects them. Models only? Opt out per run:

The artisan command writes into the namespace from config/openapi-laravel.php (output.namespace, default App\Data), overridable per run with --namespace. Set spec and output.path in the config too and you can then just run php artisan openapi:generate. Settings resolve with strict precedence: flags beat the config, the config beats the built-in defaults (controllers.enabled and routes.enabled can disable the scaffold permanently; --controllers / --routes force it back on for one run).

Not a Laravel project? The same generator ships as a framework-free binary. It reads an optional openapi-laravel.json from the working directory (or --config=<path>) whose keys mirror the Laravel config, with the same flag-over-config precedence. Controllers and routes default to <output>/Controllers and <output>/routes.php:

Full flow: generate models, rules, controllers and routes from an OpenAPI spec, catch drift in CI, regenerate without touching hand-written code

One spec drives models, validation rules, controllers and routes; the drift gate fails CI when they disagree, and regeneration never touches your code.

The same flow powers the cross-language e2e demo: one spec, a generated Laravel backend, and a TypeScript SPA.

Keep generated code in sync (CI)

Once the generated files are committed, add openapi:check to your CI pipeline. It regenerates the full file set in memory and compares it byte-for-byte against what is on disk, without writing anything:

Exit codes: 0 the committed files match the spec, 1 drift detected (the build fails), 2 a config or spec error. Add --diff to print a bounded unified diff per changed file so you can see exactly what drifted. The check honors the same flags as openapi:generate (--spec, --output, --namespace, --no-controllers, --no-routes) and only compares generator-owned files, so hand-written concrete controllers are never flagged as drift.

openapi:check failing the build on contract drift

See the drift-check guide for a full CI walkthrough.


Pipeline

You write your business logic. The DTOs, their validation, the controller signatures, and the routing table stay in sync when the spec changes.

What the generator handles today:

For known limitations and graceful-degradation cases see the limitations guide.

The same spec also produces a typed abstract controller per tag and a routes file. An operation you forget to implement is a PHP fatal at class-definition time, not a gap discovered in production:

You write only the concrete PetController extends AbstractPetController, and php artisan openapi:scaffold (or vendor/bin/openapi-laravel scaffold) writes its initial, one-time stub for you. See the server scaffold guide for the full walkthrough.

A few OpenAPI features degrade gracefully rather than crash. An undiscriminated object union is typed mixed with presence-only validation (no false-rejects). Non-object request and response bodies fall back to Illuminate\Http\Request / JsonResponse with a generator warning. A non-standard per-property required: true boolean is ignored in favour of the schema-level required array, with a diagnostic on stderr. See the limitations guide for the full, honest list.


The hard case

The Customer example above is the easy 80%. The schema below is the kind that breaks generators: the Pet schema from the e2e demo spec (e2e/spec/petstore.yaml) combines a nested $ref, a typed collection, an inline enum, a nullable number, an additionalProperties map, a scalar oneOf union, a snake_case wire name, and a readOnly/writeOnly split, in one object. Trimmed to the interesting parts:

The generator turns that into two classes, because the readOnly/writeOnly flags mean the read shape and the write shape differ on the wire. The read variant (e2e/backend/app/Data/PetData.php, trimmed):

The write variant (e2e/backend/app/Data/PetWritableData.php) is the mirror image: it carries secret_note (writeOnly, accepted on create, never read back) and drops created_at (readOnly, set server-side). The abstract controller types addPet(PetWritableData $pet): PetData, so the split is enforced at the signature level, not by convention.

This exact schema is exercised by the Playwright e2e suite over real HTTP: the #[MapName] field round-trips in both directions, the writeOnly secret never appears in a response, null stays null, the map round-trips intact, and the scalar union arrives uncoerced.


Philosophy

The spec is the source of truth. Code follows the contract, never the other way around. This is the opposite of annotation-driven tools where your PHP generates the spec.

You own the output. Generated classes are readable PHP in your repo. Review them, commit them, read them in a diff. No opaque runtime, no reflection magic you can't follow.

Explicit over inferred. Validation rules are emitted verbatim from spec constraints, not guessed from property types at runtime. What the contract says is what gets validated.

Deterministic. Stable ordering everywhere. Regenerating produces a byte-identical diff or no diff at all, so the generator is safe to run in CI and commit.

Modern only. PHP 8.2+, Laravel 11/12/13, laravel-data v4. No legacy shims.


How it compares

The Laravel ecosystem is full of code-first tools that generate an OpenAPI document from your controllers and annotations: l5-swagger, dedoc/scramble, vyuldashev/laravel-openapi. Those are excellent if your code is the source of truth. This tool is for the other direction: spec-first, where the OpenAPI document is the contract and your models derive from it.

openapi-laravel l5-swagger / scramble ensi-platform/* hand-writing
Direction Spec → code Code → spec Spec → code n/a
Generates laravel-data DTOs Yes No No (custom DTOs) You do
Spec-derived validation rules() Yes, differentially tested against the spec No Partial You do
Native PHP enums Yes No No You do
Server scaffold (abstract controllers + routes) Yes (default) No Yes You do
allOf / additionalProperties Yes n/a Partial You do
oneOf / anyOf Scalar union type hints; discriminated object unions validated and hydrated; undiscriminated ones presence-only, no false-reject n/a Partial You do
Minimum Laravel version 11 9+ 10+ n/a
Runtime peer dependency spatie/laravel-data v4 none own DTO layer none
Standard OpenAPI (no custom extensions) Yes Yes No (custom OAS) n/a
Owned, readable, committed output Yes n/a Generated Yes
Runs without Laravel (CI) Yes (bin) No No n/a
Drift detection in CI Yes (openapi:check, byte-level, exit 1 on drift in generator-owned files) n/a (spec is generated from code) No Manual review

The spatie/laravel-data v4 runtime peer is a real adoption cost: the generated DTOs are laravel-data classes, so your app takes on that dependency and its conventions.

Pick something else if:


Why not just ask an AI agent?

An agent can write a Data class from your spec, and the first one will probably be fine. But the output is non-deterministic (the same prompt produces a different class tomorrow), nobody reviews the hundredth one, and the moment the spec changes you are back to hand-maintained code that drifts. This generator is deterministic: same spec in, byte-identical files out. That makes the output diffable, reviewable once instead of every time, and re-runnable in CI on every spec change.

The honest kicker: agents built this generator. The generator is what makes their output trustworthy on the hundredth run, not just the first.


Proof: a full contract-first round trip

The strongest claim a generator can make is that its output actually interoperates over the wire. The e2e/ directory proves exactly that from a single spec, and the full cross-language loop is green: one spec drives a generated Laravel backend and a generated TypeScript client and SPA, and a Playwright headless-Chrome suite drives the browser through the whole stack over real HTTP.

One spec, two languages, no hand-written types on either side of the wire. Run the whole thing yourself (you need Docker Desktop and Node.js 18+); the runner brings the stack up, runs the headless-Chrome suite, and tears it down:

The suite proves the cross-language serialization seams round-trip over real HTTP: a snake_case wire field forcing #[MapName] (mapped both directions), a writeOnly field accepted on write and never read back, a readOnly date-time set server-side and ignored on input, a nullable number where null stays null, an additionalProperties map that round-trips intact, and a oneOf: [string, integer] scalar union with no coercion. A valid create returns 201, an invalid one returns 422 from the spec-derived rules() surfaced in the browser, and a delete returns 204.

Running two independent generators against one contract surfaced two honest findings, both since addressed: an empty additionalProperties map serialized as [] rather than {} (the classic PHP empty-array ambiguity), now fixed in 0.5.0 so empty maps serialize as {}; and the generated openapi-zod-ts client omits the Accept: application/json header, which broke browser content-negotiation against Laravel until a small middleware was added in the demo backend (filed upstream as openapi-zod-ts #289).

Use it two ways: as proof that both generated sides agree on the wire, and as a template a team can copy to bootstrap a spec-first project. See e2e/ for the full reference.


Security: the spec is untrusted input

The generator reads an OpenAPI document and writes PHP that your application then loads and executes, so it treats the spec as untrusted input. Docblock injection is neutralized, namespace and class-name options are validated before any file is written, validation patterns are never silently dropped, non-OpenAPI documents are rejected with a clear error, and a pre-parse input-size guard caps the YAML alias-bomb blast radius. A hostile-input regression suite guards all of these. Output paths are written exactly where you point them by design, so point them at fixed, operator-controlled locations and never derive them from untrusted input. See the limitations guide for the full threat model and operator boundaries.


Why quality matters

A code generator has a wide blast radius: a subtle regression touches every project that runs it.

See the docs for the full quality story.


Roadmap

Current release is on Packagist (see the badge above); 0.13.0 is queued. The full feature set described in this README ships today.

Open before 1.0:

The version stays 0.x until the output format settles, then tags 1.0.0 per the versioning policy. See ROADMAP.md for the release history and locked-in decisions.


License

MIT © codewithagents


All versions of openapi-laravel with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
illuminate/support Version ^11.0|^12.0|^13.0
spatie/laravel-data Version ^4.23
symfony/yaml Version ^7.0|^8.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package codewithagents/openapi-laravel contains the following files

Loading the files please wait ...