Adding new formats
This documentation needs work. See "Help improve this page" in the sidebar.
THIS IS ALL WRONG AND NEEDS TO BE UPDATED. See \Drupal\hal\HalServiceProvider for a correct example.
Core supports JSON and XML, as well as HAL-JSON. It is easy to add support for other formats.
Adding basic support
As explained in How the Serializer works, the serialization process has two parts, normalization and encoding.
If the array structure created by core's default Normalizers is acceptable for your format, then you can simply add an Encoder.
-
Create an encoder
Your Encoder should implement EncoderInterface. See Drupal\hal\Encoder for a simple example. Note that its parent class defines the required
encode
anddecode
methods.<?php namespace Drupal\tvml_base\Encoder; use Symfony\Component\Serializer\Encoder\EncoderInterface; use Symfony\Component\Serializer\Encoder\DecoderInterface; use Symfony\Component\Serializer\Encoder\XmlEncoder as BaseXmlEncoder; use Symfony\Component\Serializer\SerializerAwareInterface; use Symfony\Component\Serializer\SerializerAwareTrait; /** * Adds TVML support for serializer. * * This acts as a wrapper class for Symfony's XmlEncoder so that it is not * implementing NormalizationAwareInterface, and can be normalized externally. */ class TVMLEncoder implements SerializerAwareInterface, EncoderInterface, DecoderInterface { use SerializerAwareTrait; /** * The formats that this Encoder supports. * * @var array */ protected static $format = ['tvml']; /** * An instance of the Symfony XmlEncoder to perform the actual encoding. * * @var \Symfony\Component\Serializer\Encoder\XmlEncoder */ protected $baseEncoder; /** * Gets the base encoder instance. * * @return \Symfony\Component\Serializer\Encoder\XmlEncoder * The base encoder. */ public function getBaseEncoder() { if (!isset($this->baseEncoder)) { $this->baseEncoder = new BaseXmlEncoder(); $this->baseEncoder->setSerializer($this->serializer); } return $this->baseEncoder; } /** * Sets the base encoder instance. * * @param \Symfony\Component\Serializer\Encoder\XmlEncoder $encoder */ public function setBaseEncoder($encoder) { $this->baseEncoder = $encoder; } /** * {@inheritdoc} */ public function encode($data, $format, array $context = []) { print_r($data); exit(); return $this->getBaseEncoder()->encode($data, $format, $context); } /** * {@inheritdoc} */ public function supportsEncoding($format) { return in_array($format, static::$format); } /** * {@inheritdoc} */ public function decode($data, $format, array $context = []) { print_r($data); exit(); return $this->getBaseEncoder()->decode($data, $format, $context); } /** * {@inheritdoc} */ public function supportsDecoding($format) { return in_array($format, static::$format); } }
-
Register the encoder
You must register your custom encoder via a *.services.yml file.
services: serializer.encoder.tvml: class: Drupal\tvml_base\Encoder\TVMLEncoder tags: - { name: encoder, format: tvml }
If you want this format to be configurable via REST module, you must include the format attribute to the encoder tag.
-
Register MIME Type
If the MIME type of your format isn't registered, register it. The default MIME types are defined in
Request::initializeFormats()
. If the MIME type of your format is not listed there, you need to add it to the Request object. This can be done with an event subscriber.<?php namespace Drupal\tvml_base\EventSubscribers; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Event subscriber for adding additional content types to the request. */ class OnRequestMimeTypeTVML implements EventSubscriberInterface { /** * Register content type formats on the request object. * * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event * The Event to process. */ public function onKernelRequest(GetResponseEvent $event) { $event->getRequest()->setFormat('tvml', ['application/tvml']); } /** * Implements \Symfony\Component\EventDispatcher\EventSubscriberInterface::getSubscribedEvents(). */ static function getSubscribedEvents() { $events[KernelEvents::REQUEST][] = array('onKernelRequest'); return $events; } }
-
Your event subscriber must also be registered via *.services.yml.
services: serializer.encoder.tvml: class: Drupal\tvml_base\Encoder\TVMLEncoder tags: - { name: encoder, format: tvml } tvml_base.requestEventSubscribber: # Event subscriber class that will listen for the events. class: '\Drupal\tvml_base\EventSubscribers\OnRequestMimeTypeTVML' # Tagged as an event_subscriber to register this subscriber with the event_dispatch service. tags: - { name: 'event_subscriber' }
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion