--- url: /laravel-api-generator/guide/docs-and-postman.md --- # API Docs & Postman Your API is documented the moment it exists, with Scramble for interactive OpenAPI docs and Postman collections for your team. ## Scramble: instant OpenAPI docs The generated controllers, requests and resources are written so [Scramble](https://scramble.dedoc.co) can analyze them with **no annotations and no manual setup**: ```bash composer require dedoc/scramble --dev php artisan serve ``` Open `http://localhost:8000/docs/api`: From VS Code, the **Open the API documentation** step of the [extension](/guide/extension/quick-actions) covers the whole trip in one click, including starting the server if none is running and offering to install Scramble if it is missing. ![Scramble API Docs](../scramble-docs.png) What you get automatically: * **Interactive Swagger UI**: test endpoints from the browser with *Send API Request* * **Auto-detected schemas**: `StorePostRequest`, `UpdatePostRequest`, `PostResource`… inferred from FormRequest rules and Resource structure * **Validation rules as constraints**: `required|string|max:255` becomes a required string with `<= 255 characters` in the docs * **Request/response examples**: sample JSON bodies generated for you * **Grouped endpoints**: each entity gets its own section with all CRUD operations ![Scramble Schemas](../scramble-schemas.png) | URL | Description | |-----|-------------| | `/docs/api` | Interactive Swagger UI | | `/docs/api.json` | Raw OpenAPI 3.x JSON specification | ::: tip Scramble is a dev dependency, like the generator itself. None of it ships to production. ::: ## Postman collection ```bash php artisan make:fullapi Post --fields="title:string" --postman ``` Exports `postman_collection.json` at the project root, following the Postman v2.1 schema: * A folder per entity * Pre-configured List, Create, Show, Update and Delete requests * Sample request bodies with appropriate field values * A `base_url` variable (defaults to `http://localhost:8000/api`) Import it into Postman and hand it to your frontend team the same morning. --- --- url: /laravel-api-generator/guide/extension/quick-actions.md --- # API Ready & Project Actions ## The API ready screen Once the files are written, the panel says what happened: the files written, the routes registered with the policy that protects them, and the time it took. The manifest keeps track of every file. A button opens the new controller, and **New entity** brings the builder back. ![The API ready screen, after the migrations and the tests](/ext-ready.png) The next steps run in place, each with its progress and its result. | Step | What it does | |------|--------------| | **Run the migrations** | `php artisan migrate`. If `.env` is missing, the extension first offers to create it from `.env.example` | | **Run the tests** | `php artisan test`, with **Stop** while it runs, then the number of tests passed or failed | | **Fill the database** | `php artisan migrate:fresh --seed`, after a second click that confirms the tables are dropped. The generated seeders are already registered, so the database comes back filled, 10 records per entity | | **Open the API documentation** | Finds a Laravel server on ports 8000 to 8003 or 8080, or starts `php artisan serve`, then opens the [Scramble](/guide/docs-and-postman) documentation at `/docs/api`. When Scramble is missing, the step offers the `composer require` | | **Customize the generated code** | Publishes the package's stubs to `stubs/vendor/laravel-api-generator/`, then opens their folder | A step that fails shows an excerpt of the command output, with the full log one click away, and **Run again** starts it over. The server the extension started itself stops when the panel closes. ## Project actions **Migrations, tests, seeders** in the sidebar home, or the **Project Actions** command, opens the same steps at any time, with the API routes of the whole project. ## Guardrails ### Stub validation ::: v-pre If you [customized stubs](/guide/customizing-stubs), the extension runs `api-generator:validate-stubs` before every generation. A missing required `{{placeholder}}`, or a stub written for 3.x, triggers a modal listing the offending files and the reason, with **Open Stubs Folder** to fix them or **Generate Anyway** to proceed knowingly. A stub the package no longer reads, such as `request.stub`, only gets a warning. ::: ### Dependency detection Every dependency is checked at the moment it matters. Without the `nameless/laravel-api-generator` package, the extension offers to install it via Composer; when the installed version is too old for the feature you clicked, it offers `composer update`. The optional integrations follow the same rule, whether it is `dedoc/scramble` for the docs, `laravel/sanctum` for the Auth option or `spatie/laravel-query-builder` for filtering. Whatever is missing installs in one click. ### Orphan route repair When the route list fails because `routes/api.php` references a deleted controller (the `ReflectionException` that also breaks other Laravel tooling), the extension explains what happened and offers to run `api-generator:clean-routes`. Details in [Evolving Entities](/guide/evolving). ### Files you edited Regenerating an entity keeps the files you edited by hand, and names them before anything is written. See [Safety while generating](/guide/extension/builder#safety-while-generating) and [the review screen](/guide/extension/imports#the-review-screen). --- --- url: /laravel-api-generator/changelog.md --- # Changelog Recent releases of the package and the VS Code extension. Full histories live on GitHub: [package CHANGELOG](https://github.com/Nameless0l/laravel-api-generator/blob/main/CHANGELOG.md) · [extension CHANGELOG](https://github.com/Nameless0l/laravel-api-generator-vscode/blob/master/CHANGELOG.md). ## Package - `nameless/laravel-api-generator` ### 4.0.0 - September 27, 2026 * Laravel 12 or 13 is required. Laravel 10 and 11 projects keep 3.15, and [Upgrading to 4.0](/guide/upgrading) lists every change. * Controllers receive the model through route model binding and ask the entity's policy before every action. The generated policies let everyone through, guests included, until you restrict them. * `StorePostRequest` and `UpdatePostRequest` replace `PostRequest`, and a PATCH changes only the fields it sends. * The generated tests cover partial updates, and restore and force delete on entities with soft deletes. * Every index is paginated, filterable and sortable (`filter[status]=draft&sort=-created_at&per_page=20`), with or without Spatie QueryBuilder. See [Pagination, filters and sorting](/guide/generating#pagination-filters-and-sorting). * On Laravel 13, generated models declare their key and fillable columns with `#[Table]` and `#[Fillable]`. Casts live in a `casts()` method, and enums are named after the entity and the field (`PostStatus`). * The generated code passes `pint --test`, and JSON fields accept an object or a list. * Fixed: a migration from `--add-fields` no longer runs before the table it changes when both were generated in the same second. * Removed: the config file that was never loaded, and the two service methods deprecated in 3.8. ### 3.15.1 - September 27, 2026 * Fixed: a `belongsTo` toward a model with a custom string primary key, such as `country_code`, no longer turns the key into `0` in the DTO, which made creating and updating fail. ### 3.15.0 - September 27, 2026 * Fixed: a custom primary key is validated as unique, so posting a key that already exists returns a 422 instead of a 500. * Fixed: a `hasOne` puts its foreign key on the related table, where Eloquent looks for it. A `has_one_foreign_key` warning names the column to add when the related model is generated separately. * Fixed: `date`, `time` and `datetime` fields get `DATE`, `TIME` and `DATETIME` columns instead of `TIMESTAMP`, and `time` fields are validated as a time of day. See [Field Types](/guide/field-types). * Fixed: `--query-builder` sorts on the real primary key, so entities with a custom key no longer fail on their index. * `class_data.json` gets the missing side of its relations, like schema files and Mermaid diagrams. ### 3.14.0 - September 27, 2026 * The MCP server offers a `design-api` prompt: describe the API in plain words, and the agent drafts the schema, shows you the plan, then generates it once you agree. See [MCP Server](/guide/mcp#ask-for-an-api). ### 3.13.0 - September 27, 2026 * Generate from an OpenAPI 3.0, 3.1 or Swagger 2.0 spec with `--openapi`, from the command line or through the MCP server. See [OpenAPI Specs](/guide/openapi). * Fixed: a `hasMany` follows the `belongsTo` of the other side when it is named after its role, such as `author_id` for `author: belongsTo User`. ### 3.12.0 - September 27, 2026 * An MCP server lets Claude Code, Copilot, Cursor and other agents list, preview and generate APIs, and add fields, without ever overwriting your edits. See [MCP Server](/guide/mcp). * A schema field with an unknown type now comes with an `unknown_field_type` warning. * `--add-fields` refuses an entity name that points outside `app/Models`. ### 3.11.0 - September 27, 2026 * Regenerating keeps the files you edited by hand, and names them. `--force` overwrites them anyway. See [Evolving Entities](/guide/evolving#your-edits-survive-regeneration). * The generator records what it writes in `.api-generator/manifest.json`: commit it. * `delete:fullapi` also removes the migrations added with `--add-fields`, names the files you edited, and gains `--dry-run`. ### 3.10.0 - September 27, 2026 * Laravel Boost support: guidelines and a `laravel-api-generator` skill teach your coding agent to generate APIs instead of writing the files by hand. See [Tools & Agents](/guide/integrations#ai-coding-agents). * A JSON Schema for schema files brings autocompletion and typo checks to your editor. See [Editor autocompletion](/guide/schema-files#editor-autocompletion). * `php artisan about` shows the installed version, the protocol and the detected schema file. * The documentation publishes `llms.txt` and `llms-full.txt` for AI agents. ### 3.9.0 - September 27, 2026 * `--dry-run` shows every file a command would create or update, with nothing written, for every source including `--add-fields`. * `--json` prints one machine-readable document for scripts, editors and AI agents. See [Tools & Agents](/guide/integrations). * `--schema=-` reads a schema from stdin. * `api-generator:serve --stdio` keeps a preview process running. The VS Code extension uses it, so its live preview shows the exact code the package writes. * A failed generation no longer leaves half the files behind. * Regenerating the Postman collection keeps its id. * Fixed: running `--auth` again no longer removes the resource routes from `routes/api.php`. ### 3.8.0 - September 27, 2026 * Fixed: a PUT that keeps a unique value no longer returns 422 on multi-word entities (`BlogPost`) or with a custom primary key. * Fixed: the seeder is registered in `DatabaseSeeder.php` even when the file uses Windows (CRLF) line endings. * `--auth` limits register and login to 6 requests per minute. * `json_api: true` is now honored in schema files. * `api-generator:install` offers `install:api` and Scramble, and no longer overwrites your configuration. * `delete:fullapi` asks for confirmation before deleting (`--force` skips it). * Removed the undocumented `make:loic` command. Composer downloads drop from about 7 MB to under 0.5 MB. ### 3.7.1 - July 17, 2026 * Corrected the maintainer contact email (`composer.json` + README security section). ### 3.7.0 - July 17, 2026 * **`--json-api`**: generates [JSON:API](https://jsonapi.org/)-compliant resources (`JsonApiResource`, Laravel 12.45+): an `$attributes` list plus a `$relationships` list from the entity's relations, the `id` becoming the JSON:API identifier. Controllers are unchanged; the generated feature test asserts `data.id`. Falls back to a standard resource on Laravel < 12.45. ### 3.6.1 - July 17, 2026 * **Laravel 13 support**: the constraint stopped at `^12`, so `composer require` was rejected on any application running Laravel 13 (released March 17, 2026). Now allows `^13.0`. * Fixed: 55 of the 68 package tests were silently not collected under PHPUnit 12, which no longer reads `/** @test */` doc-comments. Tests now use the `#[Test]` attribute. **Generated stubs were never affected.** * CI now covers PHP 8.3/8.4 × Laravel 13. ### 3.6.0 - July 16, 2026 * **Model PHPDoc**: every generated model carries a full `@property` docblock (real PHP types, nullability, relations, timestamps). IDE autocompletion out of the box, no ide-helper needed. * **Native enum fields**: `status:enum(draft,published)` generates a backed `App\Enums\Status` enum, the model cast, `Rule::enum()` validation, a faked factory value and a real `$table->enum()` column. * **`--pest`**: generates Pest tests (`it(…)`, `expect(…)`) instead of PHPUnit classes. * **Automatic inverse relations** on schema/Mermaid sources: declaring one side is enough; the inverse (and its FK column) is synthesized. * **Polymorphic relations**: `morphTo`, `morphOne`, `morphMany` in schema files; `--from-database` detects `*_type`/`*_id` pairs. * **Entity evolution (`--add-fields`)**: add fields to a generated entity without touching manual changes: incremental migration + in-place patches. * **Custom primary keys**: `code:string:primary` replaces `id` everywhere: model, migration, incoming relations, validation, factories. * **`api-generator:clean-routes`**: removes route lines referencing deleted controllers (the `route:list` ReflectionException fix). Supports `--dry-run`. * Fixed: self-referential relation imports; missing `Collection` import in model PHPDoc. ### 3.5.1 - July 16, 2026 * Fixed: unique columns generated a broken bare `unique` rule (500 on every store/update); now `Rule::unique(…)->ignore(…)`. * Fixed: factories for unique columns collided on seeding; now `fake()->unique()`. * Fixed: `--only` was ignored on `--from-database` / `--schema` / `--mermaid`. * Fixed: duplicate model import in tests for self-referential relations. ### 3.5.0 - July 15, 2026 * **`--from-database`**: introspects the project database and generates a complete API for every table: FKs become relations, pivot tables become `belongsToMany`, `deleted_at` enables soft deletes. * **Declarative schema file (`--schema=api-schema.yaml`)**: the whole API in one versionable YAML/JSON file, auto-detected at the project root. * **Mermaid import (`--mermaid=diagram.mmd`)**: `erDiagram` and `classDiagram` become entities and relations. * **Spatie QueryBuilder integration (`--query-builder`)**: `?filter[field]=value&sort=-created_at` on every index endpoint. * **Pivot table migrations** for `belongsToMany`, and **FK-safe migration ordering** (parents first). ### Older releases 3.3.1 (strict-types fixes), 3.3.0 (auto-registered routes and seeders, required-by-default validation), 3.2.0 (interactive wizard, Sanctum auth, generated tests, Postman export, soft deletes), 3.0.0 (clean-architecture rewrite): details in the [full changelog](https://github.com/Nameless0l/laravel-api-generator/blob/main/CHANGELOG.md). ## VS Code extension ### 1.1.0 - September 28, 2026 * A redesigned interface. The sidebar home shows the project, its Laravel and PHP versions and the package state, with **New API**, the sources and the project tools. See [Diagram & Sidebar](/guide/extension/diagram-and-sidebar#the-sidebar-home). * **One review screen for every source**: a description, the database, a schema file, a Mermaid diagram and an OpenAPI spec open the package's dry run, entity by entity, before **Generate**. See [Sources & Review](/guide/extension/imports#the-review-screen). * **Describe with Copilot in a panel**: pick the model, relate the API to the existing entities or not, adjust the proposed entities, then review the plan. * **An API ready screen** runs the migrations, the tests, the seeding, the docs and the stubs in place, and **Project Actions** opens it at any time. See [API Ready & Project Actions](/guide/extension/quick-actions). * The builder previews the real files next to the form, with **nullable**, **unique** and **default** on each field. The entity diagram gains a search, a minimap, an export to SVG or Mermaid and an inspector. Files edited by hand are flagged in the entity tree. ### 1.0.0 - September 27, 2026 * Pairs with the package 4.0: the entity tree, **Go to Related File** and **Regenerate File(s)** read the generation manifest, so the Store and Update requests, the enums and the `--add-fields` migrations show up. * On Laravel 10 and 11, the extension installs the package's 3.x line, since 4.x needs Laravel 12. * Generation errors are read from the package's error codes, and the stub check explains why a 3.x stub no longer fits. ### 0.17.0 - September 27, 2026 * **Describe an API with Copilot**: write the API in plain words, review the `api-schema.yaml` Copilot drafts, then preview and generate it. See [Sources & Review](/guide/extension/imports#describe-an-api-with-copilot). ### 0.16.0 - September 27, 2026 * Generate from an OpenAPI 3.0, 3.1 or Swagger 2.0 spec, JSON or YAML, from the command palette, the sidebar or the builder's **Import OpenAPI** button. A dry run shows the entities, the files and the schemas left aside before anything is written. Pairs with package 3.13. ### 0.15.0 - September 27, 2026 * With `laravel/mcp` in the project, Copilot's agent mode lists the package's MCP server, started with your PHP command, Sail and Docker included. See [Copilot and schema files](/guide/extension/reference#copilot-and-schema-files). Pairs with package 3.12. ### 0.14.0 - September 27, 2026 * Regenerating from the builder keeps the files you edited by hand. A modal names them: overwrite them, or keep your changes and generate the rest. The live preview marks them **kept**. Pairs with package 3.11. ### 0.13.0 - September 27, 2026 * In Laravel projects, GitHub Copilot gets the package's `laravel-api-generator` skill and generates APIs with `make:fullapi`. * `api-schema.yaml`, `.yml` and `.json` files get completion and typo checks from the package's JSON Schema. ### 0.12.0 - September 27, 2026 * The live preview is rendered by the installed package (3.9 or later): every file the generator writes, your published stubs, badges for new, modified and unchanged files, and a diff for modified ones. * Generation sends the form to `make:fullapi --schema=-`. No `class_data.json` at the project root anymore, and Soft Deletes, Auth and Postman are no longer ignored when the form has relationships. * `laravelApiGenerator.phpCommand` runs PHP through Sail or Docker. ### 0.11.1 - September 27, 2026 * The builder form now offers the one-click package update when the installed `nameless/laravel-api-generator` is too old for an option, as the import commands already did. ### 0.11.0 - July 21, 2026 * **Sidebar home**: the activity bar view opens on a panel with a New API button, the three import sources and shortcuts to the diagram, the snippets and the documentation. * **Infinite canvas**: the entity diagram pans in every direction over a dotted grid, and Ctrl+wheel zooms toward the cursor. ### 0.10.1 - July 17, 2026 * Sponsor button on the Marketplace listing; corrected the maintainer contact email. ### 0.10.0 - July 17, 2026 * **JSON:API resources**: a "JSON:API resources" option in the builder form and the source generators passes `--json-api` to the package; the live preview renders the JSON:API shape. Pairs with package >= 3.7. ### 0.9.0 - July 16, 2026 * **Model autocomplete on relationships**: target model inputs suggest the models in `app/Models`. * **Primary key designation**: a `PK` checkbox per field row, reflected in the live preview. * **Orphan route cleanup**: offers `api-generator:clean-routes` when List Routes hits a deleted controller. * **Diagram zoom & pan**: Ctrl+wheel zoom toward cursor, background pan, −/+/100%/Fit toolbar. * **Cancellable operations**: clicking a spinning button kills the running artisan process. ### 0.8.0 - July 16, 2026 * **Add Fields to Entity** command (pairs with package ≥ 3.6), with a one-click migration run after. * **Pest tests toggle** in the form and the three source commands. * **Enum field type** with values input, rendered in the live preview. ### 0.7.x - July 15 and 16, 2026 * **Generate APIs from Database / Schema File / Mermaid Diagram** commands (pair with package ≥ 3.5). * **Spatie QueryBuilder toggle** + dependency check with one-click `composer require`. * **Entity diagram overhaul**: Bezier links, cardinality pills, hover highlighting, merged inverse links. * Welcome view, auto-refresh file watcher, monorepo support, getting-started walkthrough, old-package detection. * VSIX size cut from 24.5 MB to under 1 MB. ### Older releases 0.2.0 (loading spinners, smart server management, JSON bulk import, real-time preview), 0.1.0 (initial release): details in the [full changelog](https://github.com/Nameless0l/laravel-api-generator-vscode/blob/master/CHANGELOG.md). --- --- url: /laravel-api-generator/reference/cli.md --- # CLI Reference ## Commands ```bash php artisan make:fullapi {name?} {--fields=} {--soft-deletes} {--postman} {--auth} {--interactive} {--only=} {--schema=} {--mermaid=} {--openapi=} {--from-database} {--tables=} {--with-migrations} {--query-builder} {--pest} {--json-api} {--add-fields=} {--dry-run} {--json} {--force} php artisan delete:fullapi {name?} {--force} {--dry-run} php artisan api-generator:clean-routes {--dry-run} php artisan api-generator:introspect {--table=} php artisan api-generator:validate-stubs {--json} php artisan api-generator:install php artisan api-generator:serve {--stdio} php artisan api-generator:mcp ``` ## `make:fullapi` | Argument / Option | Description | |-------------------|-------------| | `name` | Entity name (PascalCase). Omit to use the schema file / JSON mode. | | `--fields` | Field definitions in `name:type` format, comma-separated. `enum(a,b)` and `:primary` supported. | | `--soft-deletes` | Add SoftDeletes trait, migration column, restore/forceDelete endpoints. | | `--postman` | Export a Postman v2.1 collection after generation. | | `--auth` | Scaffold Sanctum authentication (AuthController, requests, routes, middleware). | | `--interactive` | Launch the step-by-step wizard for guided entity creation. | | `--only=Type,Type` | Regenerate only the listed artifacts; skip route + seeder registration. | | `--schema=file` | Generate every entity from a declarative YAML/JSON schema file. `--schema=-` reads the schema from stdin. | | `--mermaid=file` | Generate every entity from a Mermaid `erDiagram` / `classDiagram`. | | `--openapi=file` | Generate an entity from each object schema of an OpenAPI 3 or Swagger 2 document, JSON or YAML. `--openapi=-` reads it from stdin. See [OpenAPI Specs](/guide/openapi). | | `--from-database` | Introspect the existing database and generate APIs for its tables. | | `--tables=a,b` | Restrict `--from-database` to specific tables. | | `--with-migrations` | With `--from-database`: also generate the migration files. | | `--query-builder` | Use spatie/laravel-query-builder for index filtering and sorting. | | `--pest` | Generate Pest tests instead of PHPUnit. | | `--json-api` | Generate JSON:API-compliant resources (`JsonApiResource`, Laravel 12.45+). Falls back to a standard resource on older versions. | | `--add-fields=a:type,b:type` | Add fields to an existing entity: incremental migration + in-place patches. | | `--dry-run` | Run the whole generation and list the files it would create or update, without writing anything. | | `--json` | Print one JSON document instead of the text report, for scripts, editors and agents. Not available with `--interactive`. See [Tools & Agents](/guide/integrations). | | `--force` | Overwrite the files you edited by hand since they were generated. Without it they are kept and reported. | `--only` types: `Model`, `Controller`, `Service`, `DTO`, `Request`, `Resource`, `Migration`, `Factory`, `Seeder`, `Policy`, `FeatureTest`, `UnitTest`. ## `delete:fullapi` | Argument / Option | Description | |-------------------|-------------| | `name` | Entity to delete. Omit to delete every entity defined in `class_data.json`. | | `--force` | Skip the confirmation prompt. | | `--dry-run` | List the files and entries that would be removed, without deleting anything. | Removes all generated files, including the migrations added with `--add-fields`, unregisters the seeder, and strips the entity's routes from `routes/api.php` and `routes/web.php`. The confirmation names the files you edited by hand. ## `api-generator:clean-routes` Removes routes pointing to controllers that no longer exist (fixes the `route:list` ReflectionException after manual deletions). | Option | Description | |--------|-------------| | `--dry-run` | List the orphan lines without touching the files. | ## `api-generator:introspect` Emits the project's database schema as JSON for tooling. | Option | Description | |--------|-------------| | *(none)* | List all user tables (system tables filtered out). | | `--table=name` | Describe one table: column names, normalized types, soft-deletes flag. | ## `api-generator:validate-stubs` ::: v-pre Verifies that published stubs still contain every required `{{placeholder}}`, and flags the ones written for 3.x. ::: | Option | Description | |--------|-------------| | `--json` | Machine-readable output; exit code 1 on error (CI-friendly). | ## `api-generator:install` Prepares the application for generated APIs. When `routes/api.php` does not exist yet, it offers to run `php artisan install:api`, which creates the file and installs Sanctum. When Scramble is missing, it offers to install it as a dev dependency so the interactive docs are served at `/docs/api`. Both steps are optional, and the command ends by printing the one that generates your first API. ## `api-generator:serve` Keeps one process running and answers generation previews over JSON-RPC 2.0, one message per line on stdin and stdout. It never writes files. The VS Code extension relies on it for its live preview, and the methods are described in [Tools & Agents](/guide/integrations). | Option | Description | |--------|-------------| | `--stdio` | Required. Read requests on stdin and write responses on stdout. | ## `api-generator:mcp` Starts the [MCP server](/guide/mcp) on stdin and stdout, so coding agents can list, preview and generate APIs. Your agent runs it for you once registered. It needs `laravel/mcp` (Laravel 12.41 or later), and without it the command exits with an error that says how to install it. --- --- url: /laravel-api-generator/guide/extension/reference.md --- # Commands & Settings Reference ## Commands All commands live under the **Laravel API Generator** category in the command palette (`Ctrl+Shift+P`). Most are also reachable from the sidebar toolbar and `…` menu. | Command | Description | |---------|-------------| | Generate Full API | Open the [Entity Builder](/guide/extension/builder) panel | | Generate APIs from Database | Every table at once, picked in a multi-select, then the [review screen](/guide/extension/imports#the-review-screen) | | Generate APIs from Schema File | Generate from `api-schema.yaml` / `.yml` / `.json`, after the review screen | | Generate APIs from Mermaid Diagram | Generate from a `.mmd` file, after the review screen | | Generate APIs from OpenAPI Spec | Generate from an OpenAPI or Swagger file, JSON or YAML, after the review screen | | Describe an API with Copilot | Open the Copilot panel: describe the API, adjust the proposed entities, then review the plan | | Add Fields to Entity… | Evolve an entity via `--add-fields` | | Regenerate File(s)… | Rebuild selected artifacts via `--only=` | | Delete Full API | Remove an entity's files, routes and seeder registration | | Show Entity Diagram | Open the [interactive canvas](/guide/extension/diagram-and-sidebar) | | Show Snippets | List the bundled PHP snippets | | Go to Related File | Jump between an entity's generated files | | Refresh Entities | Re-scan the project for generated entities | | Project Actions | Migrations, tests, seeding, API docs and stubs, run in a panel with their result | ## Keybindings | Keys | Command | |------|---------| | `Ctrl+Alt+R` (`Cmd+Alt+R` on macOS) | Go to Related File | ## Settings | Setting | Default | Description | |---------|---------|-------------| | `laravelApiGenerator.phpPath` | `php` | Path to the PHP executable | | `laravelApiGenerator.phpCommand` | `[]` | Full command that runs PHP, one argument per item (Sail, Docker). Wins over `phpPath` when set. | | `laravelApiGenerator.mcp.enabled` | `true` | Offer the package's MCP server to Copilot's agent mode when the project has `laravel/mcp` | | `laravelApiGenerator.locale` | `auto` | UI language: `auto` (follow VS Code), `en` or `fr` | ## PHP snippets Type a `lag:` prefix in any PHP file: | Prefix | Expands to | |--------|------------| | `lag:service` | A full service class (getAll with filtering, create, find, update, delete) | | `lag:controller` | A CRUD controller with service injection | | `lag:dto` | A readonly DTO class with `fromRequest()` | | `lag:request` | A FormRequest with `authorize()` and `rules()` | | `lag:resource` | An API resource `toArray()` method | | `lag:factory` | A factory `definition()` method | | `lag:test-feature` | A feature test method skeleton | | `lag:test-unit` | A service unit test method skeleton | | `lag:route` | `Route::apiResource(…)` | | `lag:filter` | A `scopeFilter()` query scope | ## Copilot and schema files In a Laravel project, the extension gives GitHub Copilot (VS Code 1.109 and later) the package's `laravel-api-generator` agent skill. Copilot loads it when a task calls for new API resources or CRUD endpoints, and generates them with `make:fullapi` instead of writing the files by hand. When the project also has `laravel/mcp`, the extension registers the package's [MCP server](/guide/mcp) (VS Code 1.101 and later). Copilot's agent mode then lists a Laravel API Generator server whose tools list your entities, preview a generation, generate APIs and add fields, and never overwrite a file you edited. The server starts with the PHP command of the settings above, so Sail and Docker work too, and it appears or disappears on its own when you install or remove `laravel/mcp`. It also shows up in the Extensions view, under **MCP Servers - Installed**. ![The package's MCP server in VS Code, started with php artisan api-generator:mcp](/ext-mcp-server.png) `api-schema.yaml`, `api-schema.yml` and `api-schema.json` are checked against the package's [JSON Schema](/guide/schema-files#editor-autocompletion): keys and types complete as you type, and typos show up as problems. YAML files need the Red Hat YAML extension; JSON works out of the box. ## Activation The extension activates when the workspace contains an `artisan` file: including monorepos where the Laravel app lives up to two levels deep (`backend/`, `apps/api/`…). ## Changelog Extension releases are listed on the [Changelog](/changelog) page. --- --- url: /laravel-api-generator/guide/customizing-stubs.md --- # Customizing Stubs Every generated file comes from an editable template. If the default code style isn't yours, change the templates rather than the generated files. ## Publish the stubs ```bash php artisan vendor:publish --tag=api-generator-stubs ``` This copies every `.stub` into `stubs/vendor/laravel-api-generator/`. The `StubLoader` always checks this folder first and falls back to the package defaults, so you can override **only the stubs you need**. ## Validate your customizations ::: v-pre `api-generator:validate-stubs` checks that every required `{{placeholder}}` is still present in your modified templates, and flags the ones written for 3.x (see [Upgrading to 4.0](/guide/upgrading#published-stubs)): ::: ```bash php artisan api-generator:validate-stubs ``` The `--json` form fits into a CI pipeline, with machine-readable output and exit code 1 on error, enough to catch a broken stub before it reaches a teammate's machine. The [VS Code extension](/guide/extension/quick-actions) runs this validation automatically before each generation. ## Extending the generator Need a whole new artifact type? Create a custom generator by extending `AbstractGenerator`: ```php use nameless\CodeGenerator\EntitiesGenerator\AbstractGenerator; use nameless\CodeGenerator\ValueObjects\EntityDefinition; class CustomGenerator extends AbstractGenerator { public function getType(): string { return 'Custom'; } public function getOutputPath(EntityDefinition $definition): string { return app_path("Custom/{$definition->name}Custom.php"); } protected function getStubName(): string { return 'custom'; // loads stubs/custom.stub } protected function getReplacements(EntityDefinition $definition): array { return ['modelName' => $definition->name]; } protected function generateContent(EntityDefinition $definition): string { return $this->processStub($definition); } } ``` Register it in your service provider and it is called automatically during generation. --- --- url: /laravel-api-generator/guide/extension/builder.md --- # Entity Builder **New API** opens a form on the left and, on the right, the files the package is about to write. ![The builder: the form on the left, the live preview of the files on the right](/ext-builder.png) ## The form Name the entity first. The input validates PascalCase as you type, rejects the names Laravel reserves, and shows the table and the route the entity will get. A name that already exists is allowed, and the preview then compares the existing files with what the generator would write. The **Examples** menu fills the form with a blog post, a product, a task, a comment, a profile or an article. The **Import** menu brings an entity from a database table, a `class_data.json` file or an OpenAPI spec, as described in [Sources & Review](/guide/extension/imports#builder-imports). Fields are rows you add, remove and drag to reorder, each with a name and a type (`string`, `integer`, `text`, `float`, `boolean`, `json`, `date`, `datetime`, `uuid`…). Under each row, **nullable**, **unique** and **default** set the column modifiers. Two settings go further than a column: * The `enum` type asks for its values (`draft`, `published`), and the generated API gets a backed PHP enum class, the model cast, `Rule::enum()` validation and a faked factory value. * The key icon makes the field the primary key instead of the default `id`. The model (`$primaryKey`, `$incrementing`, `$keyType`), the migration and every incoming relation follow. See [Field Types & Primary Keys](/guide/field-types). Relations get their own rows (`belongsTo`, `hasMany`, `hasOne`, `belongsToMany`). The target model autocompletes from `app/Models`, the relation name defaults to the model, and the row shows the foreign key or the pivot table it implies. Generation hands the entity to the package in the schema file format, so relations arrive with real foreign key columns, foreign-keyed factories and passing tests. The options are Soft deletes, Pest tests, Sanctum auth, Spatie QueryBuilder, JSON:API resources (Laravel 12.45+) and Postman collection. **Only some files** restricts the generation to the kinds you tick, in which case routes and the seeder are left alone. The `...` menu resets the form and opens the project actions, the stubs and the snippets. ![Pick an example, add a relation, and the preview follows](/ext-builder.gif) ## Live preview The preview comes from the package installed in your project. When the form opens, the extension starts `php artisan api-generator:serve --stdio` and keeps it running, so every change is rendered in a few milliseconds by the same code that will write the files. Your published stubs, enum casts, custom primary keys and relations show up exactly as they will be generated. Every file the generation touches is listed with its folder: model, controller, service, DTO, both requests, resource, policy, migration, factory, seeder, tests and enums, plus `routes/api.php` and `DatabaseSeeder.php`. Click one to read it. A badge says whether the file is new, modified, unchanged or kept, and **View the diffs** opens each modified file side by side with what the generator would write. When the preview cannot run, it says why and offers the fix: `composer install` when the package is not installed yet, `composer update nameless/laravel-api-generator -W` when it is too old, or the setting to change when PHP is missing. The PHP process restarts by itself after a `composer update`, a change to `.env` or to `config/`. ## Safety while generating A file you edited by hand since the last generation is marked **kept**, and the package leaves it as it is. Before generating, a modal names these files: **Overwrite** replaces them anyway, **Keep my changes** generates everything else. With a package older than 3.11, the modal lists every existing file that would be overwritten, so you can back out before anything is written. A running generation can be stopped. Click the button again and the artisan process is killed, with the form as you left it. Once the files are written, the panel shows the [API ready screen](/guide/extension/quick-actions) and its next steps. ## The same command as the terminal The form builds a `make:fullapi` call, the command documented in the [CLI Reference](/reference/cli). An entity generated from the extension, from the terminal or in a CI script produces exactly the same files. --- --- url: /laravel-api-generator/guide/extension/diagram-and-sidebar.md --- # Entity Diagram & Sidebar ## The entity diagram **Entity diagram** draws every generated entity on an infinite canvas, with its columns and their types read from the migrations, foreign keys included. ![The entity diagram, with the inspector of the Loan entity](/ext-diagram.png) Inverse declarations (Post `hasMany` Comment and Comment `belongsTo` Post) are merged into a single link with its cardinality, and a self-referential relation draws a small loop. Hovering a card highlights its connections. Drag the background or scroll to pan, and **Ctrl+wheel** (or a trackpad pinch) zooms toward the cursor. Cards stay draggable at any zoom. `Ctrl+F` searches an entity or a field, the minimap shows where you are, and the toolbar has **Show all**, **Arrange** and **Export**, to an SVG image or a Mermaid diagram (`.mmd`). Select a card to open its inspector, with the fields, the relations and the files of the entity, each file marked up to date, edited or missing. From there, **Add fields**, **Regenerate**, **Open the model** or delete the API. ![Select an entity, then browse its fields, relations and files](/ext-diagram.gif) ## The sidebar home The activity bar view opens on a home panel. ![The sidebar home above the entity tree](/ext-sidebar.png) At the top, the project with its Laravel and PHP versions and the state of the package. When the package is missing or too old, the Composer command that fixes it sits right there, and the gear opens the extension settings. Below, **New API** opens the [builder](/guide/extension/builder), **Generate from** lists the other [sources](/guide/extension/imports) (a description, the database, a schema file, a Mermaid diagram, an OpenAPI spec), and **Project** opens the entity diagram, the [migrations, tests and seeders](/guide/extension/quick-actions#project-actions), the snippets and this documentation. The panel follows your VS Code theme and the extension's language setting (English or French). ## The entity tree Below the home, the **Generated Entities** view tracks everything the generator created. Its title bar keeps **New API**, **Diagram** and **Refresh**, and its `...` menu lists the sources and the project tools. ![A file edited by hand, flagged in the tree](/ext-tree.png) Each entity expands into three groups: * **Files**: the files the package recorded in `.api-generator/manifest.json`, Store and Update requests, enums and `--add-fields` migrations included. Click one to open it. A file you edited by hand since the generation is flagged, and the entity shows how many. * **Fields**: read from the model's `$fillable`, or from its `#[Fillable]` attribute on Laravel 13. * **Relations**: extracted from the model's relation methods, shown as `belongsTo → Author`. Entities generated before the manifest show their conventional files. A file watcher keeps the tree and the status bar in sync when APIs are generated or deleted outside the extension, from the terminal or after a `git pull`. ## Entity actions Right-click (or use the inline icons) on any entity: * **Add Fields to Entity…**: type `excerpt:text,status:enum(draft,published)` and the package creates an incremental migration and patches the model, requests, factory and resource in place via `--add-fields`, with one click to run the migration after. See [Evolving Entities](/guide/evolving). * **Regenerate File(s)…**: the extension reads the field list back from the existing migration, then lets you multi-select which artifacts to rebuild. The underlying call is `make:fullapi --only=…`, so the migration, route and seeder registration are left untouched. * **Delete**: full cleanup via `delete:fullapi` (files, routes, seeder registration). ## Go to Related File `Ctrl+Alt+R` (`Cmd+Alt+R` on macOS) from any generated file jumps to its siblings (model to controller to service to test) without hunting through the tree. It knows the Store and Update requests, the enums named after their entity and, through the manifest, the migrations. --- --- url: /laravel-api-generator/guide/evolving.md --- # Evolving Entities Generators are great on day 1 and useless on day 30 when regenerating wipes your manual changes. Here, regenerating leaves the files you edited alone, and `--add-fields` patches the entities you want to extend. ## Add fields to an existing entity ```bash php artisan make:fullapi Post --add-fields="excerpt:text,status:enum(draft,published)" php artisan migrate ``` What happens: * An **incremental** `Schema::table()` migration is created (with a proper `down()`) * The fillable columns (`$fillable` or `#[Fillable]`), the casts (`casts()`, or `$casts` in a model written by 3.x) and the PHPDoc block of the existing model are **patched in place** * Validation rules go into both requests (with `sometimes` in the update one), factory values and resource fields where they belong * The enum class is generated when needed * Fields that already exist are skipped; **your custom methods are never touched** The DTO (constructor promotion) and the generated tests are left alone and reported as manual follow-ups. ## Your edits survive regeneration The generator records what it writes in `.api-generator/manifest.json`. Commit that file. On the next run, any generated file you edited by hand is left as it is, and the report names it: ``` kept app/Models/Post.php ! app/Models/Post.php was edited since it was generated, so it was kept. Use --force to overwrite it. ``` Files you never touched are refreshed as usual. Add `--force` to overwrite the edited ones too, or preview the whole run first with `--dry-run`. Entities generated before 3.11 are regenerated as before on their next run, then tracked. ## Regenerate specific files Changed your mind about a single artifact? `--only=` rewrites just the listed generators and leaves the migration, route and seeder registration untouched: ```bash php artisan make:fullapi Post --fields="title:string,content:text" --only=Resource php artisan make:fullapi Post --fields="title:string,content:text" --only=FeatureTest,UnitTest ``` Available types: `Model`, `Controller`, `Service`, `DTO`, `Request`, `Resource`, `Migration`, `Factory`, `Seeder`, `Policy`, `FeatureTest`, `UnitTest`. ## Delete cleanly ```bash php artisan delete:fullapi Post ``` Removes every generated file, unregisters the seeder from `DatabaseSeeder.php`, and strips the entity's routes from `routes/api.php` and `routes/web.php`. Migrations added with `--add-fields` go too, since the manifest knows them. Add `--dry-run` to see the list first; the confirmation also names any file you edited by hand. Enums and pivot migrations stay, because other entities may use them. ## Repair orphan routes If a route file still references a deleted controller (the classic `route:list` ReflectionException), purge orphan lines: ::: code-group ```bash [Preview] php artisan api-generator:clean-routes --dry-run ``` ```bash [Apply] php artisan api-generator:clean-routes ``` ::: The [VS Code extension](/guide/extension/quick-actions#orphan-route-repair) offers this fix when its route list fails on an orphan controller. --- --- url: /laravel-api-generator/guide/field-types.md --- # Field Types & Primary Keys Fields are declared as `name:type` pairs, comma-separated: ```bash php artisan make:fullapi Product --fields="name:string,price:decimal,stock:integer,meta:json" ``` ## Supported types | Type | Database column | PHP type | Validation rule | |------|----------------|----------|-----------------| | `string` | `VARCHAR(255)` | `string` | `string\|max:255` | | `text` | `TEXT` | `string` | `string` | | `integer` / `int` | `INTEGER` | `int` | `integer` | | `bigint` | `BIGINTEGER` | `int` | `integer` | | `boolean` / `bool` | `BOOLEAN` | `bool` | `boolean` | | `float` / `decimal` | `DECIMAL(8,2)` | `float` | `numeric` | | `json` | `JSON` | `array` | `array` | | `date` | `DATE` | `DateTimeInterface` | `date` | | `time` | `TIME` | `string` | `date_format:H:i,H:i:s` | | `datetime` | `DATETIME` | `DateTimeInterface` | `date` | | `timestamp` | `TIMESTAMP` | `DateTimeInterface` | `date` | | `uuid` | `UUID` | `string` | `uuid` | | `enum(a,b,...)` | `ENUM('a','b')` | backed enum + cast | `Rule::enum()` | Every type flows through the whole stack: migration column, validation rules, model cast, factory value, DTO property type and PHPDoc `@property`. ## Native enum fields ```bash php artisan make:fullapi Article --fields="title:string,status:enum(draft,published,archived)" ``` One field definition produces the entire chain. Here is the code the command above writes, trimmed to the lines the enum touches: ::: code-group ```php [Enum] namespace App\Enums; enum ArticleStatus: string { case Draft = 'draft'; case Published = 'published'; case Archived = 'archived'; } ``` ```php [Model] /** * @property int $id * @property string $title * @property ArticleStatus $status * @property Carbon|null $created_at * @property Carbon|null $updated_at */ class Article extends Model { use HasFactory; protected $fillable = ['title', 'status']; protected function casts(): array { return [ 'status' => ArticleStatus::class, ]; } } ``` ```php [Request] public function rules(): array { return [ 'title' => 'required|string|max:255', 'status' => ['required', Rule::enum(ArticleStatus::class)], ]; } ``` ```php [Factory] public function definition(): array { return [ 'title' => fake()->word(), 'status' => fake()->randomElement(ArticleStatus::cases()), ]; } ``` ```php [Migration] Schema::create('articles', function (Blueprint $table) { $table->id(); $table->string('title'); $table->enum('status', ['draft', 'published', 'archived']); $table->timestamps(); }); ``` ::: The enum is named after the entity and the field, `ArticleStatus` here, so two entities can each have their own `status`. In a schema file: ```yaml status: enum(draft,published) default=draft ``` ## Custom primary keys Append `:primary` (CLI) or the `primary` modifier (schema file) to make a field the primary key instead of the default auto-increment `id`: ```bash php artisan make:fullapi Country --fields="code:string:primary,name:string" ``` The whole stack follows automatically: * Migration: `$table->string('code')->primary()`, no `$table->id()` * Model: `$primaryKey`, `$incrementing = false`, `$keyType` declared * **Incoming relations**: the FK is named `country_code`, typed like the key, with `->references('code')` in the migration and `exists:countries,code` in validation * Generated tests use `getKey()` so they pass with either key style ## Nullable, unique and defaults The `--fields` string syntax keeps to `name:type`. For per-field constraints, use either the [interactive wizard](/guide/generating#interactive-wizard) or a [schema file](/guide/schema-files), which accepts a shorthand or a mapping: ```yaml fields: title: string slug: string unique content: text nullable views: { type: integer, default: 0 } ``` --- --- url: /laravel-api-generator/guide/from-database.md --- # From an Existing Database Working on a legacy project? Point the generator at the database and get a complete, tested, documented API for every table, without retyping a single schema. ## Usage ::: code-group ```bash [All tables] php artisan make:fullapi --from-database ``` ```bash [Specific tables] php artisan make:fullapi --from-database --tables=products,orders ``` ```bash [With migrations] php artisan make:fullapi --from-database --with-migrations ``` ::: The first form converts every user table; system tables are skipped automatically. `--tables=` narrows the run to the tables you list, and `--with-migrations` also writes the migration files, which is useful to version a hand-built database. ## What the introspection detects The introspection reads far more than column names: * **Columns** with their types and nullability, mapped to validation rules, casts, factories, DTO types and the model PHPDoc. A `VARCHAR(255) NOT NULL UNIQUE` becomes `required|string|max:255|unique:...` plus a unique factory value. * **Foreign keys** (real constraints, plus the `_id` naming convention) become `belongsTo` relations, with the inverse `hasMany` on the parent model: both sides typed in the PHPDoc. * **Pivot tables** (two foreign keys, nothing else) become `belongsToMany` on both models instead of a useless intermediate entity. * **Polymorphic pairs**: `commentable_type` + `commentable_id` columns are detected as a proper `morphTo` relation. * **Enum columns** become native PHP backed enums with casts and `Rule::enum()` validation. * **`deleted_at`** enables soft deletes (trait, restore/force-delete endpoints). ## Safety defaults * Migrations are **not** regenerated by default: the tables already exist. Pass `--with-migrations` when you want them as code-of-record. * The `users` table is skipped so your customized `app/Models/User.php` is never overwritten. Pass `--tables=users` explicitly if you really want it. ## Inspecting without generating The `api-generator:introspect` command emits the schema as JSON, so any tooling can build on top of it. Run it bare to list every user table (`migrations`, `sessions` and `personal_access_tokens` are filtered out), or point it at a table to get its column names, normalized types and soft-deletes flag: ::: code-group ```bash [List tables] php artisan api-generator:introspect ``` ```bash [One table] php artisan api-generator:introspect --table=products ``` ::: This powers the database imports of the [VS Code extension](/guide/extension/imports#from-the-database). ## The payoff Legacy database at 9:00, documented and tested REST API at 9:15: ```bash php artisan make:fullapi --from-database --tables=posts,categories,comments --pest --postman php artisan test php artisan serve ``` The test suite passes as generated, and if [Scramble](/guide/docs-and-postman) is installed the interactive documentation is already live at `/docs/api`. --- --- url: /laravel-api-generator/guide/testing.md --- # Generated Tests Most generators give you empty test skeletons. This one writes **real assertions**, and they pass right after generation. ## What gets covered Every entity ships with a feature test (`tests/Feature/PostControllerTest.php`) and a unit test (`tests/Unit/PostServiceTest.php`) covering: * Index: the paginated list and its `meta.total`, a filter and a sort * Store: creation persists and returns 201 * Show / Update / Delete round-trips * A partial update: the PATCH sends one field, and every other column keeps its value * Restore and force delete, when the entity uses soft deletes * Validation errors on bad input * The service layer in isolation ```php class PostControllerTest extends TestCase { use RefreshDatabase; public function test_can_list_posts(): void { Post::factory()->count(3)->create(); $response = $this->getJson('/api/posts'); $response->assertStatus(200)->assertJsonCount(3, 'data'); } public function test_can_create_post(): void { $data = ['title' => 'test_title', 'content' => 'Test text content']; $response = $this->postJson('/api/posts', $data); $response->assertStatus(201); $this->assertDatabaseHas('posts', $data); } // ... show, update, delete, validation tests } ``` ## Pest style ```bash php artisan make:fullapi Post --fields="title:string" --pest ``` Generates `it(...)` / `expect(...)` / `beforeEach(...)` style tests instead of PHPUnit classes. The coverage is the same, in the idiom new Laravel projects use by default: ```php it('creates a post', function () { $payload = Post::factory()->raw(); $this->postJson('/api/posts', $payload) ->assertCreated(); $this->assertDatabaseHas('posts', $payload); }); ``` Also available as `pest: true` in a schema file (globally or per entity). ## Independent of the primary key Generated tests use `getKey()` instead of hardcoding `->id`, so the same test suite passes whether the entity uses the default auto-increment `id` or a [custom primary key](/guide/field-types#custom-primary-keys). ## Seeding Generated seeders are registered in `DatabaseSeeder.php` automatically: each creates **10 records** through the generated factory: ```bash php artisan migrate:fresh --seed ``` --- --- url: /laravel-api-generator/guide/getting-started.md --- # Getting Started Laravel API Generator scaffolds a complete, production-style REST API from a single artisan command: model, migration, controller, service, DTO, form request, resource, policy, factory, seeder and **written tests**. ![The same entity by hand takes about two hours; make:fullapi does it in thirty seconds](/before-after.gif) ## Requirements * PHP >= 8.2 (>= 8.3 for Laravel 13) * Laravel 12.x or 13.x (Laravel 10 and 11 projects stay on `^3.15`, see [Upgrading to 4.0](/guide/upgrading)) ## Installation ```bash composer require --dev nameless/laravel-api-generator ``` The service provider is auto-discovered. No configuration required. ::: tip Zero lock-in The generator is a **dev dependency**: it never runs in production (`composer install --no-dev` leaves it out), and the generated code is plain Laravel with **no dependency on this package** (no base classes, no runtime helpers). You can even remove the generator afterwards and everything keeps working. ::: ## Your first API ```bash php artisan make:fullapi Post --fields="title:string,content:text,published:boolean" ``` Then: ```bash php artisan migrate php artisan test ``` The suite passes right after generation, with real assertions against real endpoints, where most generators leave you skeletons to fill in. ## What gets generated One command creates **13 files** per entity and registers the API route: | Layer | File | Location | |-------|------|----------| | Model | `Post.php` | `app/Models/` | | Controller | `PostController.php` | `app/Http/Controllers/` | | Service | `PostService.php` | `app/Services/` | | DTO | `PostDTO.php` | `app/DTO/` | | Requests | `StorePostRequest.php`, `UpdatePostRequest.php` | `app/Http/Requests/` | | Resource | `PostResource.php` | `app/Http/Resources/` | | Policy | `PostPolicy.php` | `app/Policies/` | | Factory | `PostFactory.php` | `database/factories/` | | Seeder | `PostSeeder.php` | `database/seeders/` | | Migration | `*_create_posts_table.php` | `database/migrations/` | | Feature Test | `PostControllerTest.php` | `tests/Feature/` | | Unit Test | `PostServiceTest.php` | `tests/Unit/` | | Route | `apiResource` entry | `routes/api.php` | ## The generated architecture Every request flows through a clean, layered structure: ```mermaid flowchart LR REQ(["HTTP request"]) --> FR["FormRequest
validation"] FR --> CTRL["Controller
thin"] CTRL -. "Gate::authorize" .-> POL["Policy
authorization"] CTRL <-- "DTO" --> SVC["Service
business logic"] SVC <--> MOD["Model"] MOD <--> DB[("Database")] CTRL --> RES["Resource
serialization"] RES --> OUT(["JSON response"]) ``` The controller stays thin. It asks the policy, then delegates to the service: ```php public function update(UpdatePostRequest $request, Post $post) { Gate::authorize('update', $post); $dto = PostDTO::fromRequest($request); return new PostResource($this->service->update($post, $dto)); } ``` Business logic lives in `PostService`, data crosses layers as a typed, `readonly` `PostDTO`, and `PostPolicy` decides who may do what. The generated policy lets everyone through, guests included, so the API works right away and restricting it means editing one method. Updates accept a partial payload: a PATCH changes the fields it sends and leaves the others alone. When your API grows, the right places to put things already exist. ## Models your IDE understands Every generated model ships a complete PHPDoc block: fields, FK columns, relations, timestamps: ```php /** * @property int $id * @property string $title * @property \App\Enums\Status $status * @property \Illuminate\Support\Carbon|null $published_at * @property-read \Illuminate\Database\Eloquent\Collection $comments */ class Post extends Model ``` Autocomplete works instantly in VS Code and PhpStorm, without `ide-helper` for the generated code. ## Next steps * [The `make:fullapi` command and its options](/guide/generating) * [Generate from an existing database](/guide/from-database) * [Describe your whole API in a YAML schema](/guide/schema-files) * [Use the VS Code extension](/guide/extension/) --- --- url: /laravel-api-generator/guide/mcp.md --- # MCP Server Coding agents such as Claude Code, GitHub Copilot or Cursor can call the generator directly through the [Model Context Protocol](https://modelcontextprotocol.io). Describe an API in plain words, and the agent turns it into a schema, shows you every file it would write, then generates the whole stack with the same engine as `make:fullapi`. ## Install The server runs on [Laravel MCP](https://laravel.com/docs/mcp), which needs Laravel 12.41 or later. Add it next to the package: ```bash composer require --dev laravel/mcp ``` The package registers its server on its own, so there is no route file to publish. Your agent starts it with `php artisan api-generator:mcp` whenever it needs it. ## Connect your agent With the [VS Code extension](/guide/extension/), there is nothing to configure. As soon as the package and `laravel/mcp` are installed, Copilot's agent mode lists a Laravel API Generator server, started with the PHP command of the extension settings, Sail and Docker included. Other clients need the command once. Claude Code registers it in one line, and most other clients read a JSON file at the root of the project: ::: code-group ```bash [Claude Code] claude mcp add -s project laravel-api-generator -- php artisan api-generator:mcp ``` ```json [.vscode/mcp.json] { "servers": { "laravel-api-generator": { "type": "stdio", "command": "php", "args": ["artisan", "api-generator:mcp"], "cwd": "${workspaceFolder}" } } } ``` ```json [.cursor/mcp.json] { "mcpServers": { "laravel-api-generator": { "command": "php", "args": ["artisan", "api-generator:mcp"] } } } ``` ::: With Claude Code, `-s project` writes `.mcp.json`, which you can commit so the whole team gets the server. Type `/mcp` in a session to check it: the server shows as connected, with its tools, its resource and its prompt. Use `-s local` to keep it to yourself. Any other client takes the same command, `php artisan api-generator:mcp`, run from the project root. When PHP runs in a container, prefix the command. Keep `-i` with Docker, since the server talks over stdin: ::: code-group ```bash [Sail] ./vendor/bin/sail php artisan api-generator:mcp ``` ```bash [Docker] docker exec -i my-app php artisan api-generator:mcp ``` ::: ## Ask for an API Ask in plain words, for example a blog with posts, categories and tags where a post can be a draft or published. The agent checks what already exists with `list-entities`, writes an [api-schema](/guide/schema-files) document and calls `plan-api`, which lists every file the generation would create or update without writing anything. Once you agree, `generate-api` writes them, and the agent can run `php artisan migrate` and the generated tests. ![Claude Code running the design-api prompt: the proposed schema and the 56 files, before anything is written](/mcp-plan.png) When the repository already holds a spec, ask for the API described in `docs/openapi.yaml`. The agent passes that path to `plan-api` instead of writing a schema, and the warnings tell it which schemas were left aside. Later, "add an excerpt to posts" goes through `add-fields`. It writes an incremental migration and patches the model, form requests, factory and resource in place, keeping what you changed in them. ![The four tools in Claude Code, the two that change nothing marked read-only](/mcp-tools.png) | Tool | What it does | |---|---| | `list-entities` | Reads `.api-generator/manifest.json` and returns each generated entity with its files, marked intact, edited or missing. Also names the schema file at the project root. | | `plan-api` | Previews the files of an api-schema document, or of an [OpenAPI spec](/guide/openapi) of the project given by its path, with warnings such as an unknown field type. Returns the content of the files on request. | | `generate-api` | Writes the files of an api-schema document or of an OpenAPI spec of the project, with `auth`, `postman` and `only` like the command line. | | `add-fields` | Adds columns to a generated entity, with an optional dry run. | The server also ships a `design-api` prompt, which most clients offer as a slash command. Give it the description, and it walks the agent through the steps above, waiting for your agreement before `generate-api`. The results use the same JSON document as [`make:fullapi --json`](/guide/integrations#machine-readable-output), so errors carry the same stable codes and hints. The server also exposes the JSON Schema of the api-schema format as the resource `api-generator://schema/api-schema.json`. ## What stays in your hands The server never overwrites a file you edited since it was generated. `generate-api` leaves it as it is and reports it with `"kept": true`. It never deletes a file and never runs a migration either. `list-entities` and `plan-api` are marked read-only, so your client knows they change nothing. Overwriting your edits with `make:fullapi --force`, removing an entity with `delete:fullapi` and migrating stay on the command line, in your hands. ## When the server does not start Run the command yourself from the project root: ```bash php artisan api-generator:mcp ``` Without `laravel/mcp`, it says so and exits. Otherwise it waits in silence for a client, which means it works. Stop it with `Ctrl+C`. --- --- url: /laravel-api-generator/guide/mermaid.md --- # Mermaid Diagrams The diagram in your README (the one GitHub renders natively) is a valid input. Sketch your data model as a Mermaid diagram, or ask an AI assistant to produce one, and generate the API from it. ## Usage ```bash php artisan make:fullapi --mermaid=blog.mmd ``` With a diagram like: ``` erDiagram USER ||--o{ POST : writes POST }o--o{ TAG : tagged POST { string title text content datetime deleted_at } TAG { string name UK } ``` ([Full example](https://github.com/Nameless0l/laravel-api-generator/blob/main/examples/blog.mmd)) Rendered, that source is this data model, and the generated API matches it exactly: ```mermaid erDiagram USER ||--o{ POST : writes POST }o--o{ TAG : tagged POST { string title text content datetime deleted_at } TAG { string name UK } ``` ## What the parser understands Both `erDiagram` and `classDiagram` are supported: * **Cardinalities** (`||--o{`, `"1" --> "*"`) become the right Eloquent relations **on both sides**: the inverse and its FK column are [synthesized](/guide/relationships#declare-one-side-get-both) * **Compositions / aggregations** (`*--`, `o--`) become `hasMany` * **`UK` markers** become unique fields with the matching validation rule * **`deleted_at`** columns enable soft deletes (trait + restore/force-delete endpoints) * **Markdown fences and comments are stripped**: paste diagrams exactly as your AI assistant produced them ## Design-first workflow 1. Sketch the ER diagram in `docs/erd.mmd`: GitHub renders it in the PR. 2. Review the *diagram*, not 40 files of generated code. 3. Merge, then `php artisan make:fullapi --mermaid=docs/erd.mmd`. Since the diagram is the input itself, the architecture doc in your repo describes exactly what was generated from it. --- --- url: /laravel-api-generator/guide/openapi.md --- # OpenAPI Specs A frontend team, an API design tool or a partner often hands you an OpenAPI document before any backend exists. Generate the Laravel side of it in one command, from OpenAPI 3.0, 3.1 or Swagger 2.0, in JSON or YAML. ## Usage ::: code-group ```bash [Preview] php artisan make:fullapi --openapi=openapi.yaml --dry-run ``` ```bash [Generate] php artisan make:fullapi --openapi=openapi.yaml ``` ```bash [From stdin] curl -s https://example.com/openapi.json | php artisan make:fullapi --openapi=- --dry-run ``` ::: Every other option works as with a schema file, including `--json`, `--auth`, `--postman`, `--pest` and `--query-builder`. ## What becomes what Each object schema of `components.schemas` (or `definitions` in Swagger 2.0) becomes an entity, and its properties become columns. | In the spec | In the generated API | |---|---| | `integer` (`int64`: `bigint`), `number` (`float`, `double`: `float`, otherwise `decimal`), `boolean` | the matching column | | `string` with `date`, `date-time`, `time` or `uuid` format | a `date`, `datetime`, `time` or `uuid` field | | `string` with `maxLength` above 255 | `text` | | `string` with `enum` | a PHP enum class, cast on the model and validated | | `array` or `object` without a reference | `json` | | A property absent from `required`, `nullable: true` or `type: [x, "null"]` | a nullable column | | `default` | the column default | | `author: { $ref: User }` | `author` relation (`belongsTo`) and its `author_id` column | | `posts: { type: array, items: { $ref: Post } }` | `hasMany`, or `belongsToMany` when both schemas list each other | | `post_id` or `postId` next to a `Post` schema | a `belongsTo` relation instead of a plain integer | | `deleted_at` or `deletedAt` | soft deletes | | `id` of type `string` | a custom primary key (`uuid` with the `uuid` format) | `id`, `created_at` and `updated_at`, in snake case or camel case, are left to the generator. Properties defined through `allOf` are merged, and a reference wrapped in `allOf`, `oneOf` or `anyOf`, the OpenAPI 3.0 way to make it nullable, still counts as a relation. ## Schemas left aside A spec also describes payloads that are not resources. These schemas are skipped, and each one is named in an `openapi_schema_skipped` warning: * errors and pagination: `Error`, `ErrorResponse`, `ValidationError`, `ProblemDetails`, `Pagination`, `Meta`, `Links`; * variants of another schema, such as `NewPet`, `CreatePetRequest`, `UpdatePetInput`, `PetResponse` or `PetList` next to a `Pet` schema; * object schemas without properties. A `LeaveRequest` or a `LandingPage` stays a resource, since no `Leave` or `Landing` schema exists next to it. String enums declared as their own schema, such as `OrderStatus`, become the type of the properties that reference them. Read the warnings of the dry run before generating, and rename or remove a schema in the spec when the guess is wrong. ## With an agent The [MCP server](/guide/mcp) takes the same input: `plan-api` and `generate-api` accept the path of a spec in the project instead of an api-schema document, so an agent can generate from `docs/openapi.yaml` without copying it into the conversation. --- --- url: /laravel-api-generator/guide/relationships.md --- # Relationships Relations can be declared in [schema files](/guide/schema-files), [Mermaid diagrams](/guide/mermaid), `class_data.json`, the interactive wizard, or detected automatically [from your database](/guide/from-database). ## Declare one side, get both In schema files, Mermaid diagrams and `class_data.json`, declaring one side of a `belongsTo` / `hasOne` / `hasMany` / `belongsToMany` is enough: the inverse relation **and its FK migration column** are synthesized automatically, exactly like `--from-database` does: ```yaml entities: Category: fields: name: string unique relations: posts: hasMany Post Post: fields: title: string ``` Here, `Post` gets the `belongsTo Category` and the `category_id` column without one more line. If both sides are declared, they are de-duplicated. ## Eloquent vocabulary Schema files use the Eloquent method names directly: | Declaration | Eloquent method | Foreign key | |-------------|----------------|-------------| | `author: belongsTo User` | `belongsTo()` | On current table | | `posts: hasMany Post` | `hasMany()` | On related table | | `profile: hasOne Profile` | `hasOne()` | On related table | | `tags: belongsToMany Tag` | `belongsToMany()` | Pivot table, created automatically | Entities are generated **parents-first** so migrations run in foreign-key-safe order, and pivot migrations are created automatically for every `belongsToMany`. ## Polymorphic relations Schema files support `morphTo`, `morphOne` and `morphMany`: ```yaml entities: Post: fields: title: string relations: comments: morphMany Comment Comment: fields: body: text relations: commentable: morphTo ``` `morphTo` emits `$table->nullableMorphs('commentable')` in the migration and `morphTo()` on the model; `morphOne` / `morphMany` point back with the right morph name. Database introspection detects `*_type` / `*_id` column pairs as `morphTo` automatically. ## Custom primary keys propagate When a related entity uses a [custom primary key](/guide/field-types#custom-primary-keys), every incoming relation follows: FK name (`country_code`), column type, `->references('code')` and the `exists:countries,code` validation rule. ## JSON mode (`class_data.json`) Bulk generation from JSON uses explicit relationship arrays: | JSON key | Eloquent method | |----------|----------------| | `oneToOneRelationships` | `hasOne()` | | `oneToManyRelationships` | `hasMany()` | | `manyToOneRelationships` | `belongsTo()` | | `manyToManyRelationships` | `belongsToMany()` | ```json [ { "name": "User", "attributes": [{ "name": "name", "_type": "string" }], "oneToManyRelationships": [{ "role": "posts", "comodel": "Post" }] }, { "name": "Post", "attributes": [{ "name": "title", "_type": "string" }], "manyToOneRelationships": [{ "role": "user", "comodel": "User" }] } ] ``` Model inheritance is also supported via the `"parent"` key. ## Relations in the PHPDoc Every relation lands in the model's docblock, so your IDE autocompletes `$post->comments` immediately: ```php /** * @property-read Category $category * @property-read \Illuminate\Database\Eloquent\Collection $comments */ ``` --- --- url: /laravel-api-generator/guide/extension/imports.md --- # Sources & Review You rarely start from a blank form. The extension generates the whole API from what you already have, a database, a versioned schema, a diagram or a spec, or from a description written in plain words. Every one of these sources ends on the same review screen, before anything is written. The sources are in the sidebar home under **Generate from**, in the `...` menu of the entities view and in the command palette. ## The review screen The package runs the generation as a dry run, and the panel shows what it would do. Each entity lists its fields, its relations and the files it would get, with a badge for the new ones or the entities already generated. The shared files, `routes/api.php` and `DatabaseSeeder.php`, have their own row. On the side, the summary counts the files to create and to update and the new routes, and the generation options (Pest tests, Postman collection, Sanctum auth, Spatie QueryBuilder, JSON:API resources) can still be switched. ![The review of an OpenAPI spec, then the generation of both entities](/ext-review.gif) A file you edited by hand since the last generation stays as it is. The screen names it, **View the diffs** compares it with what the generator would write, and **Overwrite anyway** includes it on purpose. Schemas the package left aside are listed with the reason, such as the error schema of a spec. **Generate** writes the files and opens the [API ready screen](/guide/extension/quick-actions) with the next steps. ## Describe an API with Copilot Start from a sentence. **A description** opens a panel where you write the API in plain words, for example rooms that members book by time slot, where a booking has a start, an end and a status. Three examples fill the box if you want to try first. ![The Describe your API panel](/ext-describe.png) Pick the chat model VS Code offers (GitHub Copilot by default) and choose whether it relates the new entities to the ones your project already has. The model drafts an `api-schema.yaml`, and the proposed entities show up as cards, marked new, changed or already in the project. Click a card to adjust the entity in the YAML draft, and the cards follow your edits. **Review the plan** opens the review screen. **Save as api-schema.yaml** keeps the draft at the project root instead, as the versioned source of the API. When the model cannot answer, the panel says why, whether Copilot is signed out, no model is installed or the provider returned an error, with the fix as a button when there is one, such as setting an API key. The panel needs VS Code 1.90 or later. ## From the database This is the legacy-project route. It generates complete REST APIs for **every table at once**, straight from the existing schema. A multi-select lists the tables with their column count, all preselected except `users`, so your customized `app/Models/User.php` is never overwritten by accident. The review screen follows, where **Migrations too** decides whether the migration files are written as well. Foreign keys become `belongsTo` and `hasMany`, pivot tables become `belongsToMany`, and `deleted_at` columns enable soft deletes. Details in [From an Existing Database](/guide/from-database). ## From a schema file Describe the whole API in a declarative, versionable YAML or JSON file. The extension picks up `api-schema.yaml`, `.yml` or `.json` at the project root, or lets you browse for one. Entities are generated parents first, with FK-safe migration ordering and automatic pivot migrations. See [YAML & JSON Schemas](/guide/schema-files). ## From a Mermaid diagram Turn a Mermaid `erDiagram` or `classDiagram`, hand-written or produced by an AI assistant, into a working API. The command uses the active `.mmd` file or lets you browse for one. Cardinalities (`||--o{`, `"1" --> "*"`) become the right Eloquent relations on both sides. See [Mermaid Diagrams](/guide/mermaid). ## From an OpenAPI spec Hand an OpenAPI 3.0, 3.1 or Swagger 2.0 spec, JSON or YAML, to the package. The command uses the active spec or lets you browse for one, and the review screen shows the schema count of the spec next to its name. A spec that lives outside the project is sent on stdin, so Sail and Docker projects work too. See [OpenAPI Specs](/guide/openapi) for what becomes what. ## Builder imports The builder's **Import** menu fills the form instead, so you can adjust one entity before generating it. * **A database table** lists the user tables, system tables such as `migrations`, `sessions` or `personal_access_tokens` left out. The columns of the table you pick are mapped to the generator's types, and the form gets the entity name (singular, PascalCase), the fields and soft deletes when a `deleted_at` column exists. * **A class\_data.json file** shows every entity it defines with its fields and relations, then generates them all in one click. Relationships (`oneToMany`, `manyToOne`, `manyToMany`, compositions, aggregations) are supported. [Download a sample class\_data.json](https://github.com/Nameless0l/laravel-api-generator/blob/main/examples/class_data.json) to try it, a blog with Author, Category, Article and Tag. * **An OpenAPI spec** leads to the review screen above. With a package older than 3.13, it falls back to the extension's own importer, which reads JSON specs only. --- --- url: /laravel-api-generator/guide/generating.md --- # The `make:fullapi` Command `make:fullapi` is the heart of the package. It accepts an entity name with inline fields, or reads from a [schema file](/guide/schema-files), a [Mermaid diagram](/guide/mermaid) or your [existing database](/guide/from-database). ## Basic usage ```bash php artisan make:fullapi Post --fields="title:string,content:text,published:boolean" ``` ## Soft deletes ```bash php artisan make:fullapi Post --fields="title:string,content:text" --soft-deletes ``` Adds the `SoftDeletes` trait, a `softDeletes()` migration column, `restore()` / `forceDelete()` methods, and two extra routes that still find a soft deleted post: ``` POST /api/posts/{post}/restore DELETE /api/posts/{post}/force-delete ``` ## Sanctum authentication ```bash php artisan make:fullapi Post --fields="title:string" --auth ``` Scaffolds a complete token-based auth system: `AuthController` (register, login, logout, user), `LoginRequest`, `RegisterRequest`, public auth routes, and wraps your API resource routes inside `auth:sanctum` middleware. | Method | Route | Access | |--------|-------|--------| | `POST` | `/api/register` | Public, limited to 6 requests per minute | | `POST` | `/api/login` | Public, limited to 6 requests per minute | | `POST` | `/api/logout` | `auth:sanctum` | | `GET` | `/api/user` | `auth:sanctum` | | `GET` | `/api/posts` | `auth:sanctum` (your resources require a token too) | Then install Sanctum if not already present: ```bash composer require laravel/sanctum php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider" php artisan migrate ``` ## Postman collection ```bash php artisan make:fullapi Post --fields="title:string" --postman ``` Exports a `postman_collection.json` (v2.1 schema) at the project root: a folder per entity with List, Create, Show, Update and Delete requests pre-filled with sample data. See [API Docs & Postman](/guide/docs-and-postman). ## Pagination, filters and sorting Every generated `index` endpoint is paginated, filterable and sortable: ``` GET /api/posts?filter[status]=draft&sort=-created_at,title&page=2&per_page=20 ``` The response carries `data`, `links` and `meta`. Filters match exact values on the primary key and the fillable columns (JSON columns excluded). `sort` takes a comma-separated list where a leading `-` means descending, and the default order is the primary key, newest first. Unknown filters and sorts are ignored. `per_page` defaults to 15 and stops at 100. To change these values, publish the config before generating. They are written into each generated service, so the generated code never reads the package at runtime. ```bash php artisan vendor:publish --tag=api-generator-config ``` ### With Spatie QueryBuilder ```bash composer require spatie/laravel-query-builder php artisan make:fullapi Post --fields="title:string,content:text" --query-builder ``` The same parameters then go through [spatie/laravel-query-builder](https://github.com/spatie/laravel-query-builder), with exact filters, the same sortable columns and the same pagination. Spatie answers 400 for an unknown filter or sort instead of ignoring it. For partial matches, swap `AllowedFilter::exact` for `AllowedFilter::partial` in the service. The flag works with every generation mode, and `query_builder: true` can be set globally or per entity in a schema file. ## Pest tests ```bash php artisan make:fullapi Post --fields="title:string" --pest ``` Generates `it(...)` / `expect(...)` style tests instead of PHPUnit classes, with the same coverage. See [Generated Tests](/guide/testing). ## Interactive wizard ```bash php artisan make:fullapi --interactive ``` A step-by-step guided setup: entity name, fields one by one (type, nullable, unique, default), relationships, options, and a full preview before generation. Ideal for configuring constraints not available in the `--fields` string syntax. ## Regenerate selected files with `--only=` To rebuild a `Resource` or a `Test` without touching everything else: ```bash php artisan make:fullapi Post --fields="title:string,content:text" --only=FeatureTest,UnitTest ``` When `--only=` is set, the migration, the `apiResource` route and the `DatabaseSeeder` registration are **left untouched**: only the listed artifacts are rewritten. A listed file you edited by hand is kept unless you add `--force` (see [Evolving Entities](/guide/evolving#your-edits-survive-regeneration)). Available types: `Model`, `Controller`, `Service`, `DTO`, `Request`, `Resource`, `Migration`, `Factory`, `Seeder`, `Policy`, `FeatureTest`, `UnitTest`. ## Deleting an entity ```bash php artisan delete:fullapi Post ``` After a confirmation, removes all generated files, unregisters the seeder from `DatabaseSeeder.php`, and cleans the entity's routes from `routes/api.php` and `routes/web.php`. Called without an entity name, it deletes every entity defined in `class_data.json`. Add `--force` to skip the question in scripts, or `--dry-run` to list what would be removed without deleting anything. If older deletions left routes pointing at controllers that no longer exist (the classic `route:list` ReflectionException), purge them: ::: code-group ```bash [Preview] php artisan api-generator:clean-routes --dry-run ``` ```bash [Apply] php artisan api-generator:clean-routes ``` ::: ## All options combined ```bash php artisan make:fullapi Post --fields="title:string,content:text" --soft-deletes --postman --auth --pest ``` The full flag list lives in the [CLI Reference](/reference/cli). --- --- url: /laravel-api-generator/guide/integrations.md --- # Tools & Agents Editors, scripts and AI agents can ask the generator what it would write before anything touches your project. Both entry points below run the same engine as `make:fullapi`, so a preview always matches the files a real run produces. ## Preview a generation Add `--dry-run` to any `make:fullapi` command. The generation runs completely, then lists every file it would create or update instead of writing it. ```bash php artisan make:fullapi Post --fields="title:string,body:text" --dry-run ``` Existing files show up as `update` when their content would change and `unchanged` when the generator would write the same bytes. A file you edited by hand since it was generated shows up as `kept`: the generator leaves it alone unless you pass `--force`. ## Machine-readable output `--json` replaces the text report with a single JSON document on the last line of the output. With `--dry-run`, every file comes with the content the generator would write. ```bash php artisan make:fullapi Post --fields="title:string" --dry-run --json ``` ```json { "protocol": 1, "dryRun": true, "files": [ { "path": "app/Models/Post.php", "kind": "Model", "entity": "Post", "action": "create", "content": "validated()` and remembers which fields the request sent. Its properties are nullable with a `null` default, and `toArray()` returns the sent fields only. The services save `$dto->toArray()`, so a PATCH leaves the other columns as they are. A DTO you build yourself, as the generated unit tests do, still saves every property. A field named `provided` is refused, since the DTO keeps its list of sent fields under that name. ## Paginated index The index is paginated, filterable and sortable without any extra package. `GET /api/posts?filter[status]=draft&sort=-created_at&page=2&per_page=20` answers `data`, `links` and `meta`, and the service method behind it, `getAll()`, becomes `paginate(array $query)`. Clients that read the whole list in one call now get 15 items per page, and the plain filters of 3.x (`?status=draft`) become `filter[status]=draft`. With `--query-builder`, filters match exact values instead of Spatie's default partial match. The page size comes from a new config file, read when you generate. Publish it with `php artisan vendor:publish --tag=api-generator-config` to change the default of 15 or the cap of 100. ## Models and enums On Laravel 13, the model declares its key and its fillable columns with class attributes. The generator reads the Laravel version when it runs, so a Laravel 12 project keeps the `$primaryKey`, `$keyType`, `$incrementing` and `$fillable` properties: ```php #[Table(key: 'code', keyType: 'string', incrementing: false)] #[Fillable(['code', 'name'])] class Country extends Model ``` `#[Table]` only appears with a custom primary key. On both versions, the casts move from the `$casts` property to a `casts()` method, and `--add-fields` adds to whichever one the model has. Enums are named after the entity and the field: `status` on `Post` gives `App\Enums\PostStatus` instead of `App\Enums\Status`, so two entities with a `status` field no longer write to the same enum. The enum written by 3.x stays in place. The generation names it in a `legacy_enum` warning, and you delete it once no code uses it. `delete:fullapi` removes the enums of the entity it deletes. ## Generated code The generated files pass `pint --test` with the Laravel preset: sorted imports and short class names, routes included. `routes/api.php` imports each controller, and regenerating an entity rewrites the fully qualified references written by 3.x. A few behaviors change along the way: * `json` fields validate with `array` instead of `json`. Clients send an object or a list, and a JSON-encoded string gets a 422. * The DTO casts string fields too, so a date or a code sent as a number, such as `20250101`, no longer ends in a 500. * The resource of an entity with a custom primary key no longer returns an `id` key, which was always `null`. * The columns of a `morphTo` relation are nullable (`nullableMorphs`), since the generated requests do not fill them. Attach the owner through the relation, for example `$post->comments()->create([...])`. ## Published stubs Stubs published under `stubs/vendor/laravel-api-generator` keep taking precedence, so compare them with the new ones. `php artisan api-generator:validate-stubs` points at what a 3.x stub misses: ::: v-pre * `request.stub` is no longer read. Copy your changes into `request.store.stub` and `request.update.stub`, then delete it. * `controller.stub` and `controller.query-builder.stub` need `{{routeParameter}}`, the variable the route binds. * `dto.stub` needs `{{attributesFromValidated}}` in place of `{{attributesFromRequest}}`. * `service.stub` and `service.query-builder.stub` must save `$dto->toArray()` instead of `get_object_vars($dto)`, or a PATCH would clear the fields it leaves out. * `policy.stub` needs `{{modelVariable}}`. * `service.stub` and `service.query-builder.stub` need `{{allowedFilters}}`, `{{allowedSorts}}`, `{{perPage}}` and `{{maxPerPage}}`. * `test.unit.stub` and `test.unit.pest.stub` must call `paginate()`, since `getAll()` no longer exists. * `model.stub` needs `{{members}}`, which holds the traits, the properties, `casts()` and the relations, and `{{classAttributes}}` right above `class`, where the Laravel 13 attributes go. A 3.x model stub still gets `{{traits}}`, `{{fillable}}` and `{{relationships}}`, so it keeps generating a working model, with properties. * `migrations.stub` needs `{{columns}}` for the whole table body. The 3.x placeholders are still filled. * `request.store.stub` and `request.update.stub` need `{{imports}}` after the `FormRequest` import, for `Rule` and the enums their rules use. The feature test stubs gain optional placeholders for the new cases: `{{patchFields}}`, `{{patchAssertion}}`, `{{patchedColumns}}`, `{{softDeleteTests}}`, `{{filterField}}`, `{{primaryKey}}` and `{{sortAssertion}}`. ::: ## Removed * **`config/laravel-api-generator.php`**. The generator never loaded it, so its paths, namespaces and field types had no effect. If you copied it into your project, delete it. * **`generateFromJson()` and `deleteCompleteApi()`** on `ApiGenerationServiceInterface`, deprecated since 3.8. Generate with `php artisan make:fullapi` (a schema file, `class_data.json` or any other source) and delete with `php artisan delete:fullapi`. --- --- url: /laravel-api-generator/guide/extension.md --- # VS Code Extension A free visual interface for the generator. Build an entity in a form while the package shows the files it will write, generate from your database, a spec or a plain description, then run the migrations and the tests from the same panel. [**Install from the Marketplace**](https://marketplace.visualstudio.com/items?itemName=Nameless0l.laravel-api-generator) · [Extension repository](https://github.com/Nameless0l/laravel-api-generator-vscode) ![The extension in VS Code: the sidebar home, the builder and the live preview of the files](/ext-overview.png) ## What it adds | | | |---|---| | [Entity Builder](/guide/extension/builder) | A form next to the live preview of every file, rendered by the package installed in your project | | [Sources & Review](/guide/extension/imports) | Generate from a description with Copilot, your database, a schema file, a Mermaid diagram or an **OpenAPI spec**, after reviewing the package's dry run | | [Diagram & Sidebar](/guide/extension/diagram-and-sidebar) | An entity canvas with an inspector, and the tree of every generated file, the ones you edited flagged | | [API Ready & Project Actions](/guide/extension/quick-actions) | Migrations, tests, seeding, API docs and stubs, run in place with their result | | [Copilot](/guide/extension/reference#copilot-and-schema-files) | The package's agent skill and its [MCP server](/guide/mcp), so Copilot's agent mode plans and generates APIs through the package | | [Commands & Settings](/guide/extension/reference) | Command palette reference, keybindings, settings, PHP snippets | The whole UI (panel labels, popups, prompts, error messages) is available in **English and French**, following VS Code's display language (forceable via the `laravelApiGenerator.locale` setting). ## Install 1. Search **"Laravel API Generator"** in VS Code Extensions (`Ctrl+Shift+X`), or install from the [Marketplace](https://marketplace.visualstudio.com/items?itemName=Nameless0l.laravel-api-generator). 2. Open a Laravel project: the extension activates when it finds an `artisan` file (monorepos are supported: Laravel apps up to two levels below the workspace root, e.g. `backend/` or `apps/api/`, are detected). 3. The extension drives the Composer package in your project: ```bash composer require --dev nameless/laravel-api-generator ``` If the package is missing, the extension offers to install it for you, as a dev dependency (nothing from the generator ships to production, and the generated code doesn't depend on it). If the installed version is too old for a feature, it explains why and offers to run `composer update`. A native **Getting Started walkthrough** (Help → Get Started) covers the package install, your first generation, database import and the sidebar. ## Requirements * VS Code 1.82+ * PHP 8.2+ on your PATH (or set `laravelApiGenerator.phpPath`, or `laravelApiGenerator.phpCommand` for Sail and Docker) * A Laravel 10 / 11 / 12 / 13 project. The package's 4.x line needs Laravel 12: on Laravel 10 and 11, the extension installs its 3.x line. ## Your first API, without a terminal 1. Click the **Laravel API Generator** icon in the activity bar, then **New API**. 2. Fill the form, start from the **Examples** menu, or bring an entity from the **Import** menu. The [live preview](/guide/extension/builder) follows every change. 3. Click **Generate the API** (`Ctrl+Enter`). The panel becomes the [API ready screen](/guide/extension/quick-actions), with the files written and the routes registered. 4. Run the migrations, then the tests. Each step shows its result in place, such as the number of tests passed. If `.env` is missing, the extension first offers to create it from `.env.example`. 5. **Open the API documentation** starts the development server if none is running and opens the interactive documentation of your new API. When Scramble is missing, the step offers to install it. ![One click on Generate the API, then the migrations and the tests run in place](/ext-generate.gif) --- --- url: /laravel-api-generator/guide/schema-files.md --- # YAML & JSON Schemas Describe your whole API in one declarative, versionable file: commit it, review it in PRs, regenerate at will. ## YAML schema Create `api-schema.yaml` at the project root: ```yaml options: query_builder: true pest: true entities: Category: fields: name: string unique relations: posts: hasMany Post Post: soft_deletes: true fields: title: string content: text nullable status: enum(draft,published) default=draft views: { type: integer, default: 0 } relations: tags: belongsToMany Tag Tag: fields: name: string unique ``` ```bash php artisan make:fullapi --schema=api-schema.yaml ``` When `api-schema.yaml` (or `.yml` / `.json`) exists at the project root, you can even drop the flag: a bare `php artisan make:fullapi` picks it up automatically. ## Field syntax Fields accept a shorthand (`title: string`) or a full mapping when you need extra keys like `rules`: ```yaml fields: title: string slug: string unique excerpt: text nullable code: string primary status: enum(draft,published) default=draft views: { type: integer, default: 0, rules: 'min:0' } ``` `unique`, `nullable` and `default=` decorate the shorthand, and `primary` promotes the field to [custom primary key](/guide/field-types). ## Options Options can be global (under `options:`) or per entity: | Option | Effect | |--------|--------| | `soft_deletes: true` | SoftDeletes trait + restore/force-delete endpoints | | `query_builder: true` | Spatie QueryBuilder filtering & sorting on index | | `pest: true` | Pest tests instead of PHPUnit | | `json_api: true` | JSON:API resources (Laravel 12.45+, standard resources on older versions) | ## Editor autocompletion The package ships a JSON Schema of this format. Point the first line of the file at it, and any editor running the YAML language server completes keys and types, and flags typos such as `strng` or `nulable` before you generate: ```yaml # yaml-language-server: $schema=https://nameless0l.github.io/laravel-api-generator/schema/api-schema.json ``` The [VS Code extension](/guide/extension/) applies the schema to `api-schema.yaml`, `api-schema.yml` and `api-schema.json` on its own. Offline, the same file sits in `vendor/nameless/laravel-api-generator/resources/schema/api-schema.json`. Outside the editor, `make:fullapi` still generates a field of unknown type as a string column, and reports it with an `unknown_field_type` warning that names the field. ## What you get for free * **Inverse relations synthesized**: declare `posts: hasMany Post` on `Category`, and `Post` receives the `belongsTo` and its `category_id` migration column. [Details](/guide/relationships). * **Foreign-key-safe ordering**: entities are generated parents-first so `php artisan migrate` never trips on a missing table. * **Automatic pivots**: every `belongsToMany` creates its pivot migration. ## JSON bulk mode (`class_data.json`) The original bulk format, still fully supported: create `class_data.json` at the project root and run `php artisan make:fullapi` with no arguments. See [Relationships → JSON mode](/guide/relationships#json-mode-class-data-json) for the format, or [download the sample Blog schema](https://github.com/Nameless0l/laravel-api-generator/blob/main/examples/class_data.json). ::: tip AI-friendly A single YAML file describing a whole API is an ideal target for AI assistants: ask your favorite model for a schema, review it, generate. The assistant cannot hallucinate file paths, since the generator decides the layout. With Laravel Boost, the agent learns the format from the package's skill: see [Tools & Agents](/guide/integrations#ai-coding-agents). :::