Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Api Generator Laravel Package

mitulgolakiya/laravel-api-generator

Laravel API Generator scaffolds complete RESTful APIs from your database tables: controllers, models, routes, requests, resources, and docs, with pagination, filtering, sorting, and relationship support built in.

View on GitHub
Deep Wiki
Context7

Getting Started

Know what you're installing first. This package is archived (last release May 2015) and targets the Laravel 5.0–5.3 era: service-provider registration in config/app.php, app/Http/routes.php-style routing, and controllers that call $this->middleware(...) in the constructor. It will not boot cleanly on Laravel 8+ without work. The realistic entry points are:

  1. A legacy Laravel 5.x app you're extending.
  2. A throwaway Laravel 5.x skeleton you spin up only to generate code, then copy the output into your modern app.

Minimal steps (legacy app):

# 1. Clean git tree — you want to diff everything it touches
git checkout -b api-generator-scaffold

# 2. Install as a dev dependency only
composer require --dev mitulgolakiya/laravel-api-generator

# 3. Register the provider in config/app.php 'providers'
Mitul\Generator\GeneratorServiceProvider::class,

# 4. Publish config and inspect it before running anything
php artisan vendor:publish

Where to look first, in this order:

  • php artisan list | grep -i api — confirm the actual command name and flags for your installed version before trusting any README. Then php artisan api:generate --help.
  • config/generator.php (whatever the publish tag drops) — this is where output paths, base namespaces, model/controller namespaces, and stub locations live. Read it fully; half the "wrong output location" complaints are just this file.
  • The package's src/ stubs directory — this is the real source of truth for what the generated code looks like in your version.

First use case: pick one small, well-normalized table with at least one real foreign key (e.g. products with category_id). Run the interactive command against it, then immediately git diff:

php artisan api:generate      # interactive: table, model, controller, routes
git status && git diff

Commit the raw, untouched generated output as its own commit before you edit a line. That commit is your reference for every later regeneration and merge.

Implementation Patterns

Schema-first, then generate. The generator reads information_schema — your database is the spec. Before running it, audit the table:

  • Real FOREIGN KEY constraints (not just _id columns) — relationship inference depends on them.
  • Explicit NULL / NOT NULL on every column — this drives required vs sometimes/nullable in the form requests.
  • varchar lengths, enum/set definitions, decimal(p,s) — these become max:, in:, and numeric rules.
  • A deleted_at timestamp if you want soft-delete detection, and standard created_at/updated_at if you want timestamps inferred.

If your schema is sloppy, you will spend longer fixing generated validation than writing the files by hand.

One table, one commit. The generator is interactive and table-at-a-time. Resist batching everything into one run — a single bad table makes the whole diff unreviewable.

php artisan api:generate   # products
git add -A && git commit -m "scaffold: products (generated, untouched)"
# tweak, then:
git commit -am "products: auth, eager loads, tightened validation"

Never regenerate over customized files. There is no safe merge or rollback. If a table's schema changes materially, generate into a scratch branch, diff against your hardened version, and hand-port the deltas. Treat the generator as a one-shot bootstrapper, not a codegen pipeline.

Harden immediately after generating. Generated controllers are scaffolding, not production code. The standard follow-up pass:

  • Add authentication — routes are emitted unauthenticated. Wrap them: Route::middleware('auth:api')->group(...).
  • Add authorization — generate policies (php artisan make:policy) and swap Model::findOrFail() for $this->authorize(...) calls.
  • Convert Route::resource to Route::apiResource (Laravel 5.5+) to drop create/edit routes that make no sense for an API.
  • Add with([...]) eager loads in index/show — the generated index paginates but typically doesn't eager-load, so relationships N+1 immediately.
  • Wrap responses in JsonResource/ResourceCollection if you're on 5.5+, replacing the raw response()->json() calls.
  • Clamp pagination input — see gotchas.

Porting into a modern app. Generate in the throwaway 5.x skeleton against a database dump, then copy files across and fix the known drift points:

Generated (5.x) Modern equivalent
app/Http/routes.php routes/api.php
$this->middleware('auth') in constructor Route::middleware() in route file
Route::resource Route::apiResource
response()->json($model) new ModelResource($model)
App\User namespace hardcodes your configured namespaces

Integration tip — generate before you write migrations for legacy schemas. The highest-value scenario is a database you inherited but didn't design: dump it, restore to a dev DB, point the generator at it, and get models with accurate $fillable, casts, and relationships in minutes. Then write migrations from the generated models if you need them.

Extend via stubs, not via post-processing scripts. If you find yourself applying the same five edits to every generated controller, publish/fork the stubs into your app and edit those. That's the only sustainable customization point this package offers.

Gotchas and Tips

It's abandoned — pin and isolate. Do not put this in require for production. require-dev, generate, commit, then composer remove --dev so future composer update runs can't resurrect it or pin you to an old framework.

Relationship inference is FK-only. No FK constraint = no belongsTo/hasMany. MyISAM tables, or columns named category_id without the constraint, silently produce a model with zero relationships and you'll blame the generator.

Validation is type-derived, not business-derived. Expect required|max:255 on a varchar(255) that actually accepts a comma-separated list, in: rules missing for enum-like columns stored as varchar, and unique: rules that ignore soft deletes. Always add Rule::unique(...)->ignore($id) manually and re-check sometimes vs required on PATCH-style updates.

Table prefixes and non-public Postgres schemas break things. If you use DB_PREFIX, generated unique: rules and FK lookups can reference unprefixed names. For Postgres, confirm the connection's search_path includes the schema holding your tables — the generator queries information_schema scoped to the current connection.

Reserved words and irregular plurals. A table named order or status produces a model whose class name collides with SQL keywords or Laravel internals; people/data-style irregular names get the wrong controller and route names. Rename in the interactive prompt rather than fixing ten files afterward.

Soft deletes and timestamps are heuristic. Detection is based on the presence of deleted_at / created_at. Custom timestamp column names or a boolean is_deleted flag won't be picked up — add SoftDeletes and $dates by hand.

The generated index is a pagination footgun. ?per_page=100000 will happily serialize your whole table. Add a clamp in the controller or a global per_page cap:

$perPage = min((int) $request->input('per_page', 15), 100);

Auth is wide open by default. Every generated route is publicly reachable. If you scaffold ten tables and deploy without wrapping them in auth:api, you've shipped ten open CRUD endpoints. Make the middleware group part of the same commit as the generated code.

No dry-run, no rollback, silent overwrite. The command writes files immediately and will clobber existing ones without confirmation in most versions. Always start from a clean git tree and commit before each run. If the output looks wrong, git checkout . is your undo.

Debugging a failed run: re-run with -v / -vvv, and check that (a) the table name matches exactly (it is case-sensitive on Linux/Postgres), (b) the DB user can read information_schema, and (c) the target directories in config/generator.php exist and are writable. Most failures are permissions or a namespace that doesn't map to a real PSR-4 root.

Extension points, ranked by usefulness: published config (paths, namespaces, base controller) → stubs (code shape) → a BaseApiController you point the config at, so cross-cutting concerns like pagination clamping and response formatting live in one place instead of in every generated file.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log