dreadlabs/kunstmaan-content-api-bundle
Installation
composer require dreadlabs/kunstmaan-content-api-bundle
Register the bundle in AppKernel.php:
new DreadLabs\KunstmaanContentApiBundle\DreadLabsKunstmaanContentApiBundle(),
Configure Page Entities
Implement SlugActionInterface in your Page entity (e.g., HomePage):
use Kunstmaan\NodeBundle\Controller\SlugActionInterface;
class HomePage implements SlugActionInterface
{
public function getControllerAction()
{
return 'dreadlabs_kunstmaan_content_api.controller:getAction';
}
}
Ensure your controller is registered as a service in services.yml:
services:
acme.website.controller.homepage:
class: Acme\WebsiteBundle\Controller\HomePageController
tags: ['controller.service_arguments']
First Use Case
Access a page via /homepage?_media_type=json to trigger JSON serialization. The bundle uses willdurand/negotiation to auto-detect the _media_type request parameter (e.g., json, xml).
Media Type Delegation
The bundle injects a media_type attribute into the Request object via willdurand/negotiation. Use this to dynamically serialize responses:
$mediaType = $request->attributes->get('media_type');
if ($mediaType === 'json') {
return $this->serializeAsJson($node);
}
Custom Serialization
Implement SerializableInterface for custom entities:
use DreadLabs\KunstmaanContentApiBundle\Api\SerializableInterface;
class MyEntity implements SerializableInterface
{
public function serialize($mediaType)
{
return match ($mediaType) {
'json' => json_encode($this->toArray()),
'xml' => $this->toXml(),
default => throw new \InvalidArgumentException("Unsupported media type: $mediaType"),
};
}
}
Integration with Kunstmaan NodeBundle
Extend the Node entity to include serializable fields:
use Doctrine\ORM\Mapping as ORM;
use DreadLabs\KunstmaanContentApiBundle\Api\SerializableInterface;
#[ORM\Entity]
class MyNode extends AbstractNode implements SerializableInterface
{
// ...
public function serialize($mediaType): string
{
return $this->getSerializer()->serialize($this, $mediaType);
}
}
API Controller Usage
Override the default ApiController to add custom logic:
namespace Acme\WebsiteBundle\Controller;
use DreadLabs\KunstmaanContentApiBundle\Controller\ApiController as BaseApiController;
class ApiController extends BaseApiController
{
protected function customizeResponse($node, $mediaType)
{
// Add headers, modify payload, etc.
$response = parent::customizeResponse($node, $mediaType);
$response->headers->set('X-Custom-Header', 'value');
return $response;
}
}
Media Type Detection
_media_type query parameter. If omitted, it defaults to html._media_type=json (or other formats) in requests.Service Registration
controller.service_arguments will break routing.services.yml includes:
tags: ['controller.service_arguments']
Circular References in Serialization
Node entities may cause infinite loops.__toString() or use JsonSerializable for circular references:
public function jsonSerialize()
{
return [
'id' => $this->id,
'title' => $this->title,
// Avoid serializing recursive relations
];
}
Deprecated Negotiation Package
willdurand/negotiation is outdated (last update: 2015). May cause compatibility issues with newer Symfony versions.symfony/negotiation instead.Check Media Type Injection
Dump the Request attributes to verify media_type is set:
dump($request->attributes->get('media_type'));
Validate Serialization Test serialization manually:
$serializer = $this->get('dreadlabs_kunstmaan_content_api.serializer');
$result = $serializer->serialize($node, 'json');
Custom Serializers Register a custom serializer service:
services:
acme.custom_serializer:
class: Acme\Serializer\CustomSerializer
tags:
- { name: dreadlabs_kunstmaan_content_api.serializer, alias: 'custom' }
Override Default Controller
Replace the default ApiController by extending and configuring:
services:
dreadlabs_kunstmaan_content_api.controller.api:
class: Acme\WebsiteBundle\Controller\ApiController
public: true
Add Media Types Extend supported media types via configuration:
dreadlabs_kunstmaan_content_api:
media_types:
- json
- xml
- custom_format
How can I help you explore Laravel packages today?