Creating a custom REST resource for an existing entity

Creating a custom REST resource for an existing entity

Drupal 8 provides a basic REST resource for every known entity in the system. For most use cases this is enough to get you going, but what if the default implementation doesn’t suffice your needs?

To create your own REST resource you have to create a Resource class which extends the EntityResource class. This way you can use the functionality provided by Drupal, but override it where you deem necessary. Here’s a short example:

  • Create a class located in your_module/src/Plugin/rest/resource and extend EntityResource
    class MyCustomEntityResource extends EntityResource {
     ...
    }
  • Add the required annotation so that Drupal knows this class exposes a resource. The annotation defines some properties of the resource: the label, the entity type id and the uri’s on which the resource can be used.
    /**
     * @RestResource(
     *   id = "my_custom_entity_resource",
     *   label = @Translation("My custom entity resource"),
     *   entity_type = "my_custom_entity_id",
     *   serialization_class = "Drupal\my_module\Entity\MyCustomEntityResource",
     *   uri_paths = {
     *     "canonical" = "/api/my-custom-entity/{my_custom_entity_id}",
     *     "https://www.drupal.org/link-relations/create" = "/api/create/my-custom-entity"
     *   }
     * )
     */
    class MyCustomEntityResource extends EntityResource {
    ...
    }
  • Implement the methods you want to override
    class MyCustomEntityResource extends EntityResource {
      /**
       * {@inheritdoc}
       */
      public function post(EntityInterface $entity= NULL) {
        // Let parent create new entity.
        $response = parent::post($entity);
    
        // Do own fancy stuff.
        ...
    
        // Return newly created entity.
        $url = $entity->urlInfo('canonical', ['absolute' => TRUE])->toString(TRUE);
        return new ResourceResponse($entity, 201, ['Location' => $url->getGeneratedUrl()]);
      }
    }

The above class only overrides the POST request whereas the GET, PUT, DELETE,... request are handled by the parent EntityResource class. This approach makes sure that your resources will still work after updating Drupal core, because we allow Drupal core to do the heavy lifting.

Tags