digitalstate/platform-api-bundle
Installation
composer require digitalstate/platform-api-bundle
Add to config/app.php under ExtraBundles:
DigitalState\PlatformApiBundle\DigitalStatePlatformApiBundle::class,
First Use Case: Basic API Endpoint
Create a controller extending DigitalState\PlatformApiBundle\Controller\ApiController:
namespace App\Controller;
use DigitalState\PlatformApiBundle\Controller\ApiController;
use Symfony\Component\HttpFoundation\JsonResponse;
class TestController extends ApiController
{
public function index(): JsonResponse
{
return $this->json(['message' => 'Hello, Platform API!']);
}
}
Route it in routes/api.php:
use App\Controller\TestController;
Route::get('/test', [TestController::class, 'index']);
Key Configuration
Check config/packages/digitalstate_platform_api.yaml (if auto-generated) for:
API Resource Handling
Use DigitalState\PlatformApiBundle\Resource\AbstractResource for standardized responses:
use DigitalState\PlatformApiBundle\Resource\AbstractResource;
class UserResource extends AbstractResource
{
public function toArray($user)
{
return [
'id' => $user->id,
'name' => $user->name,
'email' => $user->email,
];
}
}
Request Validation
Leverage built-in validation via DigitalState\PlatformApiBundle\Validator\ApiValidator:
use DigitalState\PlatformApiBundle\Validator\ApiValidator;
public function store(Request $request)
{
$validator = new ApiValidator($request->all(), [
'name' => 'required|string|max:255',
'email' => 'required|email',
]);
if (!$validator->passes()) {
return $this->json(['errors' => $validator->errors()], 422);
}
}
Pagination
Use DigitalState\PlatformApiBundle\Pagination\ApiPaginator:
use DigitalState\PlatformApiBundle\Pagination\ApiPaginator;
public function index(Request $request)
{
$users = User::paginate(15);
return $this->json(ApiPaginator::make($users, $request->all()));
}
Authentication/Authorization
Extend DigitalState\PlatformApiBundle\Security\ApiAuthenticator:
use DigitalState\PlatformApiBundle\Security\ApiAuthenticator;
class CustomAuthenticator extends ApiAuthenticator
{
public function supports(Request $request)
{
return $request->headers->has('X-Custom-Token');
}
public function getCredentials(Request $request)
{
return ['token' => $request->headers->get('X-Custom-Token')];
}
}
Symfony Integration
DigitalState\PlatformApiBundle\EventListener\ApiExceptionListener for centralized error handling.config/packages/digitalstate_platform_api.yaml:
services:
App\EventListener\CustomApiListener:
tags: ['kernel.event_subscriber']
Testing
Mock the ApiController base class:
$controller = $this->getMockBuilder(ApiController::class)
->disableOriginalConstructor()
->onlyMethods(['json'])
->getMock();
Documentation
Generate OpenAPI/Swagger docs by extending DigitalState\PlatformApiBundle\OpenApi\ApiDocGenerator.
Missing Base Controller
Forgetting to extend ApiController may break response formatting and error handling.
Validation Overrides
Custom validators must implement DigitalState\PlatformApiBundle\Validator\ValidatorInterface or extend ApiValidator.
Pagination Conflicts
Ensure ApiPaginator is used instead of Laravel’s native paginate() to maintain consistent API responses.
Authentication Bypass
The bundle enforces API routes under /api/*. Misrouting may trigger unexpected behavior.
Enable API Logging
Add to config/packages/digitalstate_platform_api.yaml:
logging:
enabled: true
channel: api
Request/Response Dumping Use middleware to inspect payloads:
$this->json($request->getContent(), 200, [], JSON_PRETTY_PRINT);
Validator Debugging Enable detailed validation errors:
$validator->setMode(ApiValidator::MODE_DEBUG);
Custom Response Formats
Override DigitalState\PlatformApiBundle\Response\ApiResponse:
class CustomApiResponse extends ApiResponse
{
protected function customize(array $data): array
{
$data['meta'] = ['custom' => 'value'];
return parent::customize($data);
}
}
Dynamic Route Prefixes
Modify DigitalState\PlatformApiBundle\Routing\ApiRouter to support multi-tenant APIs:
public function getRoutes(): array
{
return [
'prefix' => '/api/{tenant}',
// ...
];
}
Event-Driven Extensions
Listen for api.request and api.response events to inject middleware logic:
use DigitalState\PlatformApiBundle\Event\ApiEvents;
$dispatcher->addListener(ApiEvents::REQUEST, function ($event) {
$event->getRequest()->attributes->set('custom_data', 'value');
});
Rate Limiting
Extend DigitalState\PlatformApiBundle\RateLimit\ApiRateLimiter for custom rules:
class CustomRateLimiter extends ApiRateLimiter
{
protected function getLimit(): int
{
return 100; // Custom limit
}
}
How can I help you explore Laravel packages today?