Install Dependencies Run:
composer require braune-digital/api-base-bundle "1.*" fos/rest-bundle white-october/pagerfanta-bundle fos/user-bundle jms/serializer-bundle
Ensure AppKernel.php includes:
new FOS\RestBundle\FOSRestBundle(),
new BrauneDigital\ApiBaseBundle\BrauneDigitalApiBaseBundle(),
Configure config.yml
braune_digital_api_base:
modules:
module1: [ROLE_USER] # Role-based module access
module2: [ROLE_ADMIN]
timeout: 3600 # Token expiry in seconds (0 = no expiry)
configuration:
app_version: "1.0.0"
environment: "production"
First Use Case: Extend BaseApiController
Create a controller:
use BrauneDigital\ApiBaseBundle\Controller\BaseApiController;
class UserController extends BaseApiController
{
public function getUsersAction()
{
return $this->handleList(new User(), [
'fields' => ['id', 'name', 'email'],
'page' => $this->get('request')->query->get('page', 1),
]);
}
}
Route the Controller
# app/config/routing.yml
user_api:
resource: "@YourBundle/Resources/config/routing.yml"
type: rest
handleList() for paginated collections:
$this->handleList($entityClass, [
'filter' => ['active' => true],
'sort' => ['name' => 'ASC'],
]);
handleGet():
$this->handleGet($entityClass, $id);
getConfiguration() to merge bundle config:
protected function getConfiguration()
{
return array_merge(parent::getConfiguration(), [
'custom_field' => 'value',
]);
}
api_token field (extend User entity if needed).ROLE_API in security.yml:
security:
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
api:
pattern: ^/api
stateless: true
anonymous: false
provider: fos_userbundle
fos_rest: ~
braune_digital_api_base.modules (YAML)._api_module:
path: /module1
defaults: { _controller: YourBundle:User:module1Action }
requirements:
_role: ROLE_USER
handleList() integrates WhiteOctoberPagerfantaBundle:
$this->handleList(User::class, [
'page' => 2,
'limit' => 10,
]);
getPagerfantaAdapter() in your controller.BaseApiController:
protected function getFilterCriteria()
{
return $this->get('request')->query->all();
}
Deprecated Dependencies
Token Timeout
timeout: 0 disables expiry, which is insecure for production. Use a realistic value (e.g., 3600 for 1 hour).Module Access Overrides
checkModuleAccess():
public function checkModuleAccess($module, User $user)
{
if (!parent::checkModuleAccess($module, $user)) {
return false;
}
return $user->hasRole('ROLE_SUPER_ADMIN');
}
CSRF Exemption
disable_csrf_role: ROLE_API must be set in fos_rest config. Forgetting this causes 403 errors on POST/PUT.Pagination Edge Cases
null instead of an empty array. Normalize in your controller:
$data = $this->handleList(...);
return $data ?: ['data' => []];
Token Validation
ROLE_API is assigned to the user entity. Debug with:
$this->get('security.token_storage')->getToken()->getUser()->getRoles();
Configuration Merging
getConfiguration() to inspect merged values:
dump($this->getConfiguration());
Query Filtering (Placeholder)
handleList():
$queryBuilder->andWhere('u.active = :active')->setParameter('active', true);
Custom Serialization
BaseApiController to modify serialization:
protected function customizeSerializer()
{
$serializer = $this->get('jms_serializer');
$serializer->configureHandlers(function (HandlerRegistry $registry) {
$registry->getOrCreateHandlerFor('Your\Entity', 'json')->setSerializationVisitor(...);
});
}
Dynamic Module Loading
braune_digital_api_base:
modules: "@=service('your_service').getModules()"
Event Listeners
api.base.response events to modify responses globally:
$dispatcher->addListener('api.base.response', function (ResponseEvent $event) {
$event->getResponse()->headers->set('X-Custom-Header', 'value');
});
Legacy Support
// composer.json
"repositories": [
{
"type": "vcs",
"url": "https://github.com/braune-digital/BrauneDigitalApiBaseBundle"
}
],
"extra": {
"symfony-endpoint": "https://api.github.com/repos/braune-digital/BrauneDigitalApiBaseBundle"
}
How can I help you explore Laravel packages today?