api-ecosystem-for-laravel/dingo-api
Dingo API is a Laravel package for building REST APIs with versioning, content negotiation, authentication, rate limiting, and error/response formatting. It streamlines API routing and helps maintain multiple API versions cleanly.
Installation
composer require api-ecosystem-for-laravel/dingo-api
Publish the config and migrations:
php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider"
php artisan migrate
Register the Service Provider
Add to config/app.php under providers:
Dingo\Api\Provider\LaravelServiceProvider::class,
Define Your First Route
In routes/api.php:
$api->version('v1', function ($api) {
$api->get('users', 'App\Http\Controllers\UserController@index');
});
First Controller
namespace App\Http\Controllers;
use Dingo\Api\Routing\Helpers;
use App\Models\User;
class UserController extends Controller
{
use Helpers;
public function index()
{
return $this->response->array(User::all());
}
}
Test the API Use tools like Postman or cURL:
curl http://your-app.test/api/v1/users
config/dingo.php for API versioning, middleware, and routing defaults.app/Http/Middleware/ for custom API middleware.routes/api.php for API-specific routes.Create a versioned endpoint with custom middleware:
// routes/api.php
$api->version('v1', ['middleware' => 'auth.api'], function ($api) {
$api->get('protected-data', 'App\Http\Controllers\ProtectedController@index');
});
/api/v1/endpoint).config/dingo.php:
'versioning' => [
'accept_header' => true,
],
version() method for logical grouping.config/dingo.php:
'middleware' => [
'api' => \App\Http\Middleware\CheckForApiToken::class,
],
$api->get('admin', ['middleware' => 'admin'], 'AdminController@index');
Dingo\Api\Http\Response:
namespace App\Http\Controllers;
use Dingo\Api\Http\Response;
class UserController extends Controller
{
protected $response;
public function __construct(Response $response)
{
$this->response = $response;
}
public function show($id)
{
return $this->response->created('/users/' . $id, ['id' => $id]);
}
}
Request class:
use Dingo\Api\Request;
public function store(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:255',
]);
}
auth:api middleware (Laravel Passport integration):
$api->get('profile', ['middleware' => 'auth:api'], 'ProfileController@show');
config/auth.php and reference in routes:
$api->get('admin', ['middleware' => 'auth:admin-api'], 'AdminController@dashboard');
app/Exceptions/Handler.php:
public function register()
{
$this->renderable(function (\Symfony\Component\HttpKernel\Exception\HttpException $e) {
return response()->json([
'error' => [
'message' => $e->getMessage(),
'status_code' => $e->getStatusCode(),
],
], $e->getStatusCode());
});
}
ApiException:
throw new \Dingo\Api\Exception\StoreResourceFailedException('User not found');
Http facade:
$response = $this->get('/api/v1/users');
$response->assertStatus(200);
Request class in tests:
$request = \Dingo\Api\Request::createFromGlobals();
$this->app->instance('request', $request);
event(new UserCreated($user));
dispatch(new SendWelcomeEmail($user));
Middleware Order Matters
api middleware is registered in config/dingo.php after Laravel’s global middleware in app/Http/Kernel.php.auth:api fails, check if the api middleware group is misconfigured.Route Caching Conflicts
php artisan route:clear
'cache' => env('API_ROUTES_CACHE', false) in config/dingo.php).Versioning Headers vs. URLs
accept_header versioning, ensure the Accept: application/vnd.yourapi.v1+json header is sent. Mixing URL and header versioning can cause conflicts.CSRF Protection
app/Http/Middleware/VerifyCsrfToken.php:
protected $except = [
'api/*',
];
Dependency Injection
BindingResolutionException. Ensure all dependencies are properly registered.Route Debugging
php artisan route:list --path=api
dd($api->getRoutes()) in routes/api.php to inspect routes dynamically.Middleware Debugging
public function handle($request, Closure $next)
{
\Log::info('Middleware executed', ['path' => $request->path()]);
return $next($request);
}
Request/Response Logging
config/dingo.php:
'debug' => env('APP_DEBUG', false),
'log_request' => true,
'log_response' => true,
Common Errors
storage/logs/laravel.log) for exceptions.Default Response Format
config/dingo.php:
'default' => [
'format' => 'json',
'json' => [
'encoding' => 'UTF-8',
'options' => JSON_PRETTY_PRINT,
],
],
CORS Configuration
config/dingo.php:
'cors' => [
'paths' => ['api/*'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_headers' => ['*'],
],
allowed_origins to specific domains.Rate Limiting
$api->middleware(['throttle:60,1']);
$api->get('rate-limited', 'RateLimitedController@index');
How can I help you explore Laravel packages today?