Installation
Add the bundle to composer.json:
"brightmarch/restful-bundle": "^1.0"
Run composer update and register the bundle in AppKernel.php:
new Brightmarch\Bundle\RestfulBundle\BrightmarchRestfulBundle(),
First Resource
Create a controller extending RestfulController:
namespace AppBundle\Controller;
use Brightmarch\Bundle\RestfulBundle\Controller\RestfulController;
class PostsController extends RestfulController
{
// Define your resource methods below
}
Routing
Configure routes in routing.yml:
app_posts:
resource: "@AppBundle/Controller/PostsController.php"
type: restful
prefix: /api/posts
First Action
Implement a basic indexAction to list resources:
public function indexAction()
{
return $this->getList(['id', 'title'], 'AppBundle:Post');
}
RestfulController methods (e.g., getList(), getItem(), createItem()).HttpUnauthorizedException.CRUD Operations Leverage built-in methods for standard REST actions:
// List resources (GET /posts)
public function indexAction() {
return $this->getList(['id', 'title'], 'AppBundle:Post');
}
// Get single resource (GET /posts/{id})
public function getAction($id) {
return $this->getItem($id, 'AppBundle:Post');
}
// Create resource (POST /posts)
public function postAction() {
return $this->createItem('AppBundle:Post');
}
// Update resource (PUT/PATCH /posts/{id})
public function putAction($id) {
return $this->updateItem($id, 'AppBundle:Post');
}
// Delete resource (DELETE /posts/{id})
public function deleteAction($id) {
return $this->deleteItem($id, 'AppBundle:Post');
}
Custom Logic Override methods to inject business logic:
public function getItem($id, $entity) {
$item = parent::getItem($id, $entity);
// Add custom logic (e.g., permissions, transformations)
return $item;
}
Validation
Use Symfony’s validator with $this->get('validator'):
public function postAction() {
$data = $this->getRequest()->request->all();
$errors = $this->get('validator')->validate($data);
if (count($errors)) {
throw new HttpBadRequestException('Validation failed');
}
return $this->createItem('AppBundle:Post');
}
Pagination
Configure pagination in getList():
public function indexAction() {
return $this->getList(
['id', 'title'],
'AppBundle:Post',
['limit' => 10, 'offset' => 0]
);
}
id field.RestfulController in PHPUnit tests:
$controller = $this->getMockBuilder('AppBundle\Controller\PostsController')
->setMethods(['getItem'])
->getMock();
Entity Not Found
getItem() throws HttpNotFoundException if the entity doesn’t exist.public function getItem($id, $entity) {
try {
return parent::getItem($id, $entity);
} catch (HttpNotFoundException $e) {
return $this->json(['error' => 'Resource not found'], 404);
}
}
CSRF Protection
config.yml:
framework:
csrf_protection:
enabled: false
Route Overrides
restful type.Deprecated Methods
get()) may be deprecated in newer Symfony versions.$this->get('service')) instead of $this->get().APP_DEBUG=true in .env to see detailed error messages.public function postAction() {
$this->get('logger')->info('POST request data:', $this->getRequest()->request->all());
return parent::postAction();
}
dump($this->getRequest()->headers) to inspect incoming headers.Custom Responses
Override createResponse() to modify JSON structure:
protected function createResponse($data, $status = 200, array $headers = []) {
$data['custom_field'] = 'value';
return parent::createResponse($data, $status, $headers);
}
Authentication Integrate with security bundles (e.g., LexikJWTAuthenticationBundle):
public function getAction($id) {
if (!$this->get('security.authorization_checker')->isGranted('ROLE_USER')) {
throw new HttpUnauthorizedException('Authentication required');
}
return parent::getAction($id);
}
Event Listeners Attach listeners to modify behavior:
// services.yml
services:
app.post_listener:
class: AppBundle\EventListener\PostListener
tags:
- { name: kernel.event_listener, event: restful.pre_list, method: onPreList }
Serialization Use JMS Serializer or Symfony’s serializer to customize output:
public function indexAction() {
$list = $this->getList(['id', 'title'], 'AppBundle:Post');
$serializer = $this->get('jms_serializer');
return new JsonResponse($serializer->serialize($list, 'json'));
}
BrightmarchRestfulBundle is loaded after FrameworkBundle in AppKernel.php.restful route type has low priority by default. Use _priority: 10 in routing.yml if needed.Doctrine\ORM\EntityManager. For multi-DB setups, inject the correct EM:
$this->get('doctrine.orm.entity_manager')->getRepository('AppBundle:Post');
How can I help you explore Laravel packages today?