I'm trying to create a custom REST GET resource for a specific node type, and I have the class created and enabled via the REST UI module settings (using the current 1.x-dev release so configs are generated w/o me having to manually create a routing.yml file). For reference, here's the class code:

 * @file
 * Custom Rest resource for video nodes.

namespace Drupal\video_export\Plugin\rest\resource;

use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Drupal\Core\Session\AccountProxyInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Psr\Log\LoggerInterface;

 * Provides a resource for database watchdog log entries.
 * @RestResource(
 *   id = "video_export_source",
 *   label = @Translation("Video Export Source"),
 *   uri_paths = {
 *     "canonical" = "/videos/feed/{site}"
 *   }
 * )

class VideoExportResource extends ResourceBase {
   *  A curent user instance.
   * @var \Drupal\Core\Session\AccountProxyInterface
  protected $currentUser;

    * @param array $configuration
    *   A configuration array containing information about the plugin instance.
    * @param string $plugin_id
    *   The plugin_id for the plugin instance.
    * @param mixed $plugin_definition
    *   The plugin implementation definition.
    * @param array $serializer_formats
    *   The available serialization formats.
    * @param \Psr\Log\LoggerInterface $logger
    *   A logger instance.
    * @param \Drupal\Core\Session\AccountProxyInterface $current_user
    *   A current user instance.
  public function __construct(
    array $configuration,
    array $serializer_formats,
    LoggerInterface $logger,
    AccountProxyInterface $current_user) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger);

    $this->currentUser = $current_user;

   * {@inheritdoc}
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(

    * Responds to GET requests.
    * Returns a list of video nodes to be imported into the target site.
    * @return \Drupal\rest\ResourceResponse
    *   The response containing a list of bundle names.
    * @throws \Symfony\Component\HttpKernel\Exception\HttpException
  public function get($site = NULL) {
    $response = ['message' => 'Hello, this is a rest service'];
    return new ResourceResponse($response);

However, when I access my URL via http://mysite/videos/feed/sourcesite?_format=xml, all I get is this error:

No route found for "GET /videos/feed/newsbusters"

and my debugger doesn't even hit my get() function. In reading the RESTful Web Services API overview docs it appears that I might be missing the second part of the uri_paths setting in the class annotation. However, the example doesn't make sense to me for my use. if the canonical url is just /videos/export/{site} (where {site} is a parameter), what is the correct second part? Just http://myite.com/videos/export?



1 Answer 1


As far as I can see, the REST UI module is just thought to change the content of the YAML files for the REST resources. It is up to the module correctly define the URL to use.

In your case, the annotation of the class should contains:

 uri_paths = {
   "canonical" = "/videos/feed/{site}",
   "https://www.drupal.org/link-relations/create" = "/videos/feed"

I am not sure the placeholder makes any difference, but all the examples use {id}.

  • 4
    I don't understand the importance of the https://www.drupal.org/link-relations/create path. What is that supposed to do?
    – wonder95
    Apr 12, 2017 at 21:36
  • I'm wondering the same question as wonder95, what is the significance?
    – Amy
    May 5, 2017 at 16:27
  • 2
    I think this somehow related to fake a bit the core implementation. Otherwise, the API will expect the request to use the /entity/{entity_type} endpoint. May 28, 2018 at 17:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.