mpociot/laravel-apidoc-generator
Generate API docs automatically from your existing Laravel, Lumen, or Dingo routes. Run php artisan apidoc:generate to produce up-to-date documentation from code and routes, with configurable output via an apidoc.php config file.
Installation:
composer require --dev mpociot/laravel-apidoc-generator
Publish the config file:
php artisan vendor:publish --provider="Mpociot\ApiDoc\ApiDocGeneratorServiceProvider" --tag=apidoc-config
Generate Documentation:
php artisan apidoc:generate
Outputs to storage/apidoc/index.html by default.
First Use Case:
Document a simple GET endpoint in a controller:
/**
* @group Users
* Get a user by ID
*
* @queryParam id integer The user ID
* @return \App\Http\Resources\UserResource
*/
public function show($id)
{
return User::findOrFail($id);
}
config/apidoc.php – Customize output paths, default groups, and strategies.storage/apidoc/index.html – View the interactive API docs.Annotate Controllers:
Use docblocks (@group, @queryParam, @bodyParam, @urlParam, @return) to define API behavior.
/**
* @group Products
* @bodyParam name string The product name (required)
* @bodyParam price float The product price
* @return \App\Http\Resources\ProductResource
*/
public function store(Request $request)
{
// ...
}
Generate Docs:
Run php artisan apidoc:generate to compile annotations into interactive HTML docs.
Integrate with CI/CD: Add to your deployment pipeline to auto-update docs on changes:
# .github/workflows/docs.yml
jobs:
generate-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: composer install
- run: php artisan apidoc:generate
- uses: actions/upload-artifact@v2
with:
name: apidoc
path: storage/apidoc/
Dynamic Groups: Use plugins to dynamically assign groups based on route attributes (e.g., middleware):
// In a custom strategy
public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
{
if ($route->hasMiddleware('auth:admin')) {
return ['groupName' => 'Admin'];
}
return null;
}
Postman Integration:
Enable Postman collection generation in config/apidoc.php:
'postman' => [
'enabled' => true,
'output' => 'storage/apidoc/collection.json',
],
Custom Templates:
Override Blade templates in resources/views/vendor/apidoc/ to modify the HTML output.
Testing Strategies: Mock responses in tests to avoid real API calls:
// In a test
$this->app->bind(\Mpociot\ApiDoc\Extracting\Strategies\Responses\ResponseCalls::class, function () {
return new class {
public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
{
return [['content' => '{"test": true}', 'status' => 200]];
}
};
});
DocBlock Parsing Quirks:
// ❌ Fails (extra line)
/**
* @group Users
*
*/
// ✅ Works
/**
* @group Users
*/
@queryParam inside @group).Circular Dependencies:
User resource with nested Address routes), ensure all related controllers are annotated to avoid missing docs.Dynamic Routes:
{id}) may not render correctly in the UI. Use @urlParam to clarify:
/**
* @urlParam id integer The user ID
*/
public function show($id) { ... }
Postman Collection Issues:
base_url in config/apidoc.php to avoid relative path issues:
'postman' => [
'base_url' => 'https://api.yourdomain.com',
],
Performance:
config/apidoc.php:
'routes' => [
'exclude' => [
'admin/*',
'web/*',
],
],
Check Generated Markdown:
Outputs to storage/apidoc/markdown/index.md. Inspect this file to debug rendering issues.
Enable Verbose Logging:
Run with -v to see strategy execution:
php artisan apidoc:generate -v
Validate DocBlocks: Use PHPStan or Psalm to catch syntax errors in docblocks early.
Test Strategies Isolated: Create a custom command to test a single strategy:
// app/Console/Commands/TestStrategy.php
public function handle()
{
$route = app()->router->getRoutes()->getByName('user.show');
$strategy = new \App\Strategies\CustomStrategy();
$result = $strategy($route, new ReflectionClass(UserController::class), new ReflectionMethod(UserController::class, 'show'), []);
dd($result);
}
Custom Strategies:
\Mpociot\ApiDoc\Extracting\Strategies\Strategy to add logic (e.g., auto-generate createdAt query params).config/apidoc.php under the appropriate stage.Override Templates:
Copy vendor/mpociot/laravel-apidoc-generator/resources/views/ to resources/views/vendor/apidoc/ to customize the HTML output.
Hook into Generation: Use events to modify the process:
// In a service provider
public function boot()
{
\Mpociot\ApiDoc\Events\Generating::subscribe(function ($event) {
$event->markdown .= "\n## Custom Section";
});
}
Add Sample Data:
Use the ParamsHelper trait to generate realistic test data:
use Mpociot\ApiDoc\Extracting\ParamsHelper;
class CustomStrategy extends Strategy
{
use ParamsHelper;
public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
{
return [
'userId' => $this->generateDummyValue('integer', ['min' => 1]),
];
}
}
Conditional Documentation: Skip documenting routes based on environment or features:
public function __invoke(Route $route, ReflectionClass $controller, ReflectionMethod $method, array $routeRules, array $context = [])
{
if (app()->environment('local')) {
return null; // Skip in local env
}
return ['metadata' => ['title' => 'Prod-only Endpoint']];
}
How can I help you explore Laravel packages today?