arseno25 / laravel-api-magic
This is my package laravel-api-magic
Fund package maintenance!
Requires
- php: ^8.2
- illuminate/contracts: ^11.0||^12.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.8
- orchestra/testbench: ^10.0.0||^9.0.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- spatie/laravel-ray: ^1.35
This package is auto-updated.
Last update: 2026-03-16 00:46:40 UTC
README
โจ Laravel API Magic
Generate a complete REST API with a single command โ Model, Migration, Controller, Request, Resource, and Tests.
โก Installation
composer require arseno25/laravel-api-magic
Publish the config file (optional):
php artisan vendor:publish --tag="laravel-api-magic-config"
๐ Features
| # | Feature | Description |
|---|---|---|
| 1 | One-Command API | Generate Model, Migration, Controller, Request, Resource & Test in one command |
| 2 | Schema Parsing | Define fields as title:string|required|max:255 with automatic validation |
| 3 | Relationships | --belongsTo, --hasMany, --belongsToMany with auto foreign keys |
| 4 | API Versioning | Multi-version endpoints with --v=2 flag |
| 5 | Auto Testing | Pest Feature test generation with --test flag |
| 6 | Docs UI | Swagger-like interactive documentation at /api/docs |
| 7 | OpenAPI 3.0 Export | Export to JSON/YAML for Postman, Insomnia, Redoc |
| 8 | #[ApiDeprecated] |
Mark endpoints deprecated with migration hints |
| 9 | #[ApiResponse] |
Define multiple response schemas per endpoint |
| 10 | #[ApiExample] |
Attach request/response example payloads |
| 11 | #[ApiWebhook] |
Document webhook events & payloads |
| 12 | Code Snippets | Auto-generated cURL, JavaScript, PHP, Python examples |
| 13 | TypeScript SDK | Full typed API client with php artisan api-magic:ts --sdk |
| 14 | Health Telemetry | Track response times, error rates per endpoint |
| 15 | API Changelog | Schema diff tracking between releases |
| 16 | Deep Type Extraction | Auto-extract JsonResource properties from toArray(), DocBlocks, and Model |
| 17 | Insomnia Export | Direct Insomnia v4 collection export with format=insomnia |
| 18 | Request Chaining | Pipe response values into the next request via {{response.field}} |
| 19 | Request History | Save, browse, and replay past API calls from the docs UI |
| 20 | GraphQL Schema | Auto-generate .graphql schema from REST endpoints |
๐ Usage
Interactive Mode
php artisan api:magic
Command Line Mode
php artisan api:magic Post \ "title:string|required|max:255,content:text|required,is_published:boolean|default:false" \ --belongsTo="User" --hasMany="Comment" --test --v=1
Command Options
| Option | Description | Example |
|---|---|---|
model |
Model name | Post |
schema |
Fields โ field:type|rule |
title:string|required |
--v= |
API version number | --v=2 |
--belongsTo= |
BelongsTo relationships | --belongsTo="Category,User" |
--hasMany= |
HasMany relationships | --hasMany="Comment,Review" |
--belongsToMany= |
BelongsToMany relationships | --belongsToMany="Tag,Role" |
--test |
Generate Pest Feature test | --test |
--factory |
Generate Model Factory | --factory |
--seeder |
Generate Database Seeder | --seeder |
--soft-deletes |
Add Soft Deletes | --soft-deletes |
--force |
Overwrite existing files | --force |
๐ API Documentation
Access your interactive docs at:
http://your-app.test/api/docs
Customize with PHP 8 Attributes directly in your controllers:
use Arseno25\LaravelApiMagic\Attributes\ApiGroup; use Arseno25\LaravelApiMagic\Attributes\ApiDescription; #[ApiGroup('User Management')] #[ApiDescription('Retrieves a paginated list of all users.')] public function index() { ... }
๐ท๏ธ PHP 8 Attributes
All attributes are in the
Arseno25\LaravelApiMagic\Attributesnamespace.
#[ApiGroup] โ Endpoint Grouping
Groups endpoints under a named section in the sidebar.
#[ApiGroup('Order Management')] public function index() { ... }
#[ApiDescription] โ Endpoint Description
Adds a detailed description below the endpoint summary. Supports Markdown.
#[ApiDescription('Returns a **paginated** list. Supports `search`, `sort`, and `filter` params.')] public function index() { ... }
#[ApiDeprecated] โ Mark as Deprecated
Marks an endpoint as deprecated with a warning banner, strikethrough path, and optional migration hints. Sets deprecated: true in the OpenAPI export.
#[ApiDeprecated(
message: 'This endpoint will be removed in v3.0.',
since: 'v2.1.0',
alternative: '/api/v2/users'
)]
public function index() { ... }
| Parameter | Type | Description |
|---|---|---|
message |
string |
Deprecation message |
since |
?string |
Version when deprecated |
alternative |
?string |
Replacement endpoint path |
#[ApiResponse] โ Multi-Response Definitions (Repeatable)
Define multiple response schemas per endpoint. Each is exported to the OpenAPI spec.
#[ApiResponse(status: 200, description: 'User found', resource: UserResource::class)] #[ApiResponse(status: 404, description: 'Not found', example: ['message' => 'User not found'])] #[ApiResponse(status: 422, description: 'Validation error')] public function show(User $user) { ... }
| Parameter | Type | Description |
|---|---|---|
status |
int |
HTTP status code (default: 200) |
resource |
?string |
Resource class name |
description |
string |
Response description |
example |
?array |
Example payload |
isArray |
bool |
Collection response |
#[ApiExample] โ Request/Response Examples
Attach example payloads displayed side-by-side in the docs UI.
#[ApiExample(
request: ['name' => 'John Doe', 'email' => 'john@example.com'],
response: ['id' => 1, 'name' => 'John Doe', 'created_at' => '2024-01-01T00:00:00Z']
)]
public function store(StoreUserRequest $request) { ... }
| Parameter | Type | Description |
|---|---|---|
request |
?array |
Example request body |
response |
?array |
Example response body |
#[ApiWebhook] โ Webhook Documentation (Repeatable)
Document webhook events. All webhooks are displayed in a dedicated sidebar panel.
#[ApiWebhook(
event: 'order.completed',
description: 'Fired when checkout completes',
payload: ['order_id' => 'integer', 'total' => 'float', 'currency' => 'string']
)]
public function store(StoreOrderRequest $request) { ... }
| Parameter | Type | Description |
|---|---|---|
event |
string |
Event name (e.g., order.completed) |
description |
string |
What triggers this webhook |
payload |
?array |
Expected payload structure |
#[ApiMagicSchema] โ Custom Resource Schema
Override the auto-detected resource schema with a custom definition.
#[ApiMagicSchema(['id' => ['type' => 'integer'], 'email' => ['type' => 'string', 'format' => 'email'])] public function index() { ... }
Can be applied to controller methods or resource classes.
#[ApiMagicHide] โ Hide from Documentation
Prevent a controller or method from appearing in the API documentation.
#[ApiMagicHide] public function internalMethod() { ... }
Apply to individual methods or entire controllers.
#[ApiMock] โ Mock Server
Return fake data based on your schema โ no backend logic needed.
#[ApiMock(statusCode: 200, count: 10)] public function index() { ... } // Or trigger via header: curl -H "X-Api-Mock: true" http://localhost:8000/api/products
Enable globally via
.env:API_MAGIC_MOCK_ENABLED=true
#[ApiCache] โ Response Caching
Automatically cache GET responses with a simple attribute.
#[ApiCache(ttl: 60)] // Cache for 60 seconds public function index() { ... }
Returns
X-Api-Cache: HIT/MISSheader to confirm caching status.
๐ Authentication
Sanctum Support
The docs UI supports Laravel Sanctum authentication. Toggle "Use Sanctum Cookie" in the auth modal to send credentials with requests.
// In your routes/api.php Route::middleware('auth:sanctum')->group(function () { Route::apiResource('products', ProductController::class); });
OAuth2 Integration
Configure OAuth2 for the documentation UI:
# .env
API_MAGIC_OAUTH_AUTH_URL=https://example.com/oauth/authorize
API_MAGIC_OAUTH_CLIENT_ID=your-client-id
API_MAGIC_OAUTH_SCOPES=read,write
Or in config/api-magic.php:
'oauth' => [ 'auth_url' => 'https://example.com/oauth/authorize', 'client_id' => 'your-client-id', 'scopes' => ['read', 'write'], ],
The docs UI will display a "Login with OAuth" button when configured.
Bearer Token Authentication
Set a bearer token in the docs UI by clicking "Set Auth" and entering your token.
๐ก WebSocket & Broadcasting Events
Laravel API Magic automatically discovers and documents your broadcasting events:
// app/Events/UserRegistered.php class UserRegistered implements ShouldBroadcast { public int $userId; public string $username; public function broadcastOn(): Channel { return new Channel('users.'.$this->userId); } public function broadcastAs(): string { return 'user.registered'; } }
Events implementing ShouldBroadcast or ShouldBroadcastNow will appear in the WebSockets panel with:
- Event name and channel
- Auto-extracted public properties as payload schema
- DocBlock descriptions via
@summary
WebSocket Live Tester
The docs UI includes a built-in WebSocket client for testing your broadcasting events in real-time.
โ๏ธ Artisan Commands
| Command | Description |
|---|---|
php artisan api:magic |
Generate a complete API stack (Model, Migration, Controller, Request, Resource, Test) |
php artisan api-magic:ts |
Generate TypeScript interfaces from your API schema |
php artisan api-magic:ts --sdk |
Generate a full TypeScript API client SDK |
php artisan api-magic:export |
Export as OpenAPI 3.0 JSON/YAML or Postman Collection |
php artisan api-magic:cache |
Cache API documentation schema for production |
php artisan api-magic:reverse |
Reverse-engineer database tables into API stack |
php artisan api-magic:snapshot |
Save API schema snapshot for changelog tracking |
php artisan api-magic:graphql |
Generate GraphQL schema from REST API endpoints |
php artisan install:api |
Create API routes file and install Laravel Sanctum/Passport |
TypeScript SDK
# Interfaces only php artisan api-magic:ts php artisan api-magic:ts --output=frontend/src/api-types.d.ts --namespace=Api # Full SDK with typed methods php artisan api-magic:ts --sdk php artisan api-magic:ts --sdk --output=frontend/src/api-client.ts
Generated SDK usage:
const api = createApiClient('http://localhost:8000', 'your-token'); const users = await api.getUsers({ page: 1, per_page: 15 }); const user = await api.createUser({ name: 'John', email: 'john@example.com' }); const item = await api.getProduct(42);
Schema Snapshots & Changelog
php artisan api-magic:snapshot
Output:
๐ธ Taking API schema snapshot...
โ
Snapshot saved: storage/api-magic/changelog/2024-01-15_120000.json
๐ Endpoints captured: 24
๐ Changes since last snapshot:
+ 2 endpoint(s) added
+ GET /api/v2/orders
+ POST /api/v2/orders
~ 1 endpoint(s) changed
~ GET /api/users
Enable in config:
'changelog' => ['enabled' => true]
Reverse Engineering
php artisan api-magic:reverse --table=products php artisan api-magic:reverse --all --exclude=users,migrations php artisan api-magic:reverse --all --v=1 --test --factory --seeder
OpenAPI & Postman Export
php artisan api-magic:export --format=json php artisan api-magic:export --format=yaml # Postman Collection via URL: curl http://localhost:8000/api/docs/export?format=postman -o postman.json
๐ฎ Advanced Features
Quick Installation
php artisan install:api
This command will:
- Create
routes/api.phpif it doesn't exist - Offer to install Laravel Sanctum or Passport for authentication
- Set up basic API structure
Code Snippets
Every endpoint has a "Snippets" button generating ready-to-use code in:
- cURL โ Terminal commands with proper headers and body
- JavaScript โ
fetch()with async/await - PHP โ Laravel
Http::facade - Python โ
requestslibrary - Dart โ
package:http/http.dartwithdart:convert - Swift โ
URLSessionwithFoundation - Go โ
net/httpwithioandfmt
Snippets auto-include your bearer token and request body. For POST/PUT/PATCH requests, example payloads are included.
API Health Telemetry
Track response times, error rates, and usage per endpoint:
Route::middleware(['api.health'])->group(function () { Route::apiResource('products', ProductController::class); });
GET /api/docs/health
{
"metrics": [
{
"endpoint": "GET /api/products",
"total_requests": 1250,
"avg_response_ms": 45.2,
"error_rate": 0.24
}
]
}
Enable in config:
'health' => ['enabled' => true]
Server Environments
Define multiple server environments for the docs UI dropdown and OpenAPI export:
// config/api-magic.php 'servers' => [ ['url' => 'https://api.example.com', 'description' => 'Production'], ['url' => 'https://staging-api.example.com', 'description' => 'Staging'], ['url' => 'http://localhost:8000', 'description' => 'Local'], ],
RBAC Auto-Detection
Automatically detects Spatie Permission middleware and displays badges:
- ๐ด Auth โ Bearer token required
- ๐ฃ Roles โ
role:admin|editor - ๐ก Permissions โ
permission:manage-users - ๐ต Rate Limited โ Throttle middleware detected
Deep Type Extraction
The ResourceAnalyzer automatically extracts real properties from your JsonResource classes using 3 strategies:
- Source parsing โ reads
$this->fieldfromtoArray() - DocBlock โ reads
@propertyannotations on the resource class - Model fallback โ uses
$fillable,$casts, and timestamps from the underlying Eloquent model
Insomnia Collection Export
curl http://localhost:8000/api/docs/export?format=insomnia -o insomnia.json
Exports a full Insomnia v4 collection with workspace, folders, environment variables (base_url, token), and request bodies.
Request Chaining
In the docs UI, use {{response.field}} in any input field to reference the last API response:
# Path param: {{response.data.id}}
# Body field: {{response.data.name}}
# Deep access: {{response.data.user.email}}
Request History
Click "Request History" in the sidebar to view past API calls. Each entry shows method, path, status code, and response time. Click any entry to replay it with the original request body.
- Max 50 entries, stored in
localStorage - One-click replay with auto-restored body
- Clear all history button
GraphQL Schema Generation
php artisan api-magic:graphql php artisan api-magic:graphql --output=frontend/schema.graphql
Auto-generates a complete GraphQL SDL from your REST endpoints:
- GET endpoints โ
Querytype - POST/PUT/DELETE โ
Mutationtype - Request bodies โ
inputtypes - Response schemas โ output
types
๐ก API Docs Routes
| Method | Route | Description |
|---|---|---|
GET |
/api/docs |
Interactive documentation UI |
GET |
/api/docs/json |
Raw JSON schema |
GET |
/api/docs/export |
OpenAPI 3.0 / Postman export |
GET |
/api/docs/health |
Health telemetry metrics |
GET |
/api/docs/changelog |
Schema diff between snapshots |
GET |
/api/docs/code-snippet |
Code snippets for an endpoint |
Export formats: openapi (default), postman, insomnia.
โ๏ธ Configuration
php artisan vendor:publish --tag="laravel-api-magic-config"
Key options in config/api-magic.php:
return [ 'docs' => [ 'enabled' => env('API_MAGIC_DOCS_ENABLED', true), 'prefix' => env('API_MAGIC_DOCS_PREFIX', 'docs'), // Route prefix (/api/docs) 'middleware' => [], // Middleware for docs routes 'exclude_patterns' => ['sanctum', 'passport', 'telescope', 'horizon'], ], 'generator' => [ 'default_version' => null, // Default API version for generated code 'seeder_count' => 10, // Default records per seeder ], 'servers' => [ ['url' => env('APP_URL', 'http://localhost'), 'description' => 'Current Environment'], ], 'mock' => [ 'enabled' => env('API_MAGIC_MOCK_ENABLED', false), // Mock API server ], 'cache' => [ 'enabled' => env('API_MAGIC_CACHE_ENABLED', true), // Response caching 'store' => env('API_MAGIC_CACHE_STORE', null), ], 'health' => [ 'enabled' => env('API_MAGIC_HEALTH_ENABLED', false), // Health telemetry 'store' => env('API_MAGIC_HEALTH_STORE', null), 'window' => 60, // Metrics window (minutes) ], 'changelog' => [ 'enabled' => env('API_MAGIC_CHANGELOG_ENABLED', false), 'storage_path' => storage_path('api-magic/changelog'), ], 'oauth' => [ 'auth_url' => env('API_MAGIC_OAUTH_AUTH_URL', ''), 'client_id' => env('API_MAGIC_OAUTH_CLIENT_ID', ''), 'scopes' => env('API_MAGIC_OAUTH_SCOPES', []), ], ];
Customize generated code stubs:
php artisan vendor:publish --tag="api-magic-stubs"
๐งช Testing
201 tests ยท 525+ assertions ยท PHPStan Level 5
composer test # or vendor/bin/pest vendor/bin/phpstan analyse
๐ Extensibility & Plugins
You can hook into the parsing engine to modify the generated schema or register your own parsers using LaravelApiMagic hooks. Add this inside your AppServiceProvider::boot method:
use Arseno25\LaravelApiMagic\LaravelApiMagic; public function boot() { // Register hook before schema generation LaravelApiMagic::beforeParse(function () { // Prepare global configurations... }); // Modify the generated OpenAPI schema array LaravelApiMagic::afterParse(function (array &$schema) { $schema['info']['termsOfService'] = 'https://example.com/terms'; $schema['info']['contact'] = [ 'name' => 'API Support', 'email' => 'support@example.com', ]; }); // Clear all registered hooks (useful for testing) LaravelApiMagic::clearParseCallbacks(); }
Facade Methods
| Method | Description |
|---|---|
LaravelApiMagic::version() |
Get package version |
LaravelApiMagic::docsEnabled() |
Check if docs routes are enabled |
LaravelApiMagic::docsPrefix() |
Get docs URL prefix |
LaravelApiMagic::excludePatterns() |
Get excluded route patterns |
LaravelApiMagic::beforeParse(callable) |
Register pre-parse hook |
LaravelApiMagic::afterParse(callable) |
Register post-parse hook |
LaravelApiMagic::clearParseCallbacks() |
Clear all hooks |
๐ Issues
If you discover any bugs, missing features, or issues, please open an issue on the GitHub repository.
When reporting an issue, please try to include:
- Your Laravel version
- Your
arseno25/laravel-api-magicpackage version - Clear steps to reproduce the issue
- Expected vs actual behavior
๐ค Contributing
Contributions are completely welcome! Whether it's adding a new feature, fixing a bug, or improving the documentation, we'd love your help.
How to Contribute:
- Fork the repository.
- Create a new branch for your feature or bugfix (
git checkout -b feature/amazing-feature). - Make your changes and ensure all tests are passing (
vendor/bin/pest && vendor/bin/phpstan analyse). - Commit your changes with descriptive messages (
git commit -m 'feat: add amazing feature'). - Push to your branch (
git push origin feature/amazing-feature). - Open a Pull Request against the main repository.
Note: Please ensure that you write unit/feature tests for any new features or bug fixes to maintain stability.
๐ License
This package is open-sourced software licensed under the MIT license.
Created with โค๏ธ by Arseno25
"Magic is just beautifully organized code."