Score:1

Custom REST resource throws 404

np flag

I have created a custom REST resource to create a specific node entry. (I need some additional checks, so I can't use the available node resource.) The endpoint has been enabled in the UI. However, when I make a POST call to the endpoint at /rest/ticketmatic, it returns a 404. The following is the code in the modules/custom/ticketmatic/src/Plugin/rest/resource/Ticketmatic.php file.

namespace Drupal\ticketmatic\Plugin\rest\resource;

use Drupal\Component\Serialization\Json;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
use Drupal\node\Entity\Node;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Symfony\Component\HttpFoundation\Request;

/**
 * Annotation for post method
 *
 * @RestResource(
 *   id = "ticketmatic",
 *   label = @Translation("Ticketmatic"),
 *   serialization_class = "",
 *   uri_paths = {
 *     "canonical" = "/rest/ticketmatic",
 *     "https://www.drupal.org/link-relations/create" = "/rest/ticketmatic"
 *   }
 * )
 */
class Ticketmatic extends ResourceBase {

  /**
   * @param Request $request
   *
   * @return ResourceResponse
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public function post(Request $request) {
    $response_status['status'] = false;
    $params = Json::decode($request->getContent());
    $timezone = new \DateTimeZone('UTC');
    $data = [
      'uid' => 2,
      'type' => 'concert',
      'title' => $params['title'],
      'field_concert_tm_id' => $params['ID'],
      'field_concert_location' => $params['location'],
      'field_concert_ticket_status' => $params['ticket_status'],
      'field_concert_datetime' => DrupalDateTime::createFromTimestamp($params->datetime, $timezone)
        ->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT),
    ];

    $existingNodes = \Drupal::entityTypeManager()->getStorage('node')
      ->loadByProperties(['field_concert_tm_id' => $params->ID]);

    if ($node = reset($existingNodes)) {
      $node->set('title', $params->title);
      $node->set('field_concert_location', $params->location);
      $node->set('field_concert_ticket_status', $params->ticket_status);
      $node->set('field_concert_datetime', DrupalDateTime::createFromTimestamp($params->datetime, $timezone)
        ->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT));
    }
    else {
      $node = Node::create($data);
    }

    if ($node->save()) {
      $response_status['status'] = true;
    }

    $response = new ResourceResponse($response_status);

    return $response;
  }

}

I'm at a loss, because similar code works in a different project; the only difference is the Drupal version used from that project.

Any help, tip, or pointer are greatly appreciated.

This is the endpoint configuration.

uuid: 8551c284-e6e5-4e28-9c39-6b4b4bc8a6d7
langcode: nl
status: true
dependencies:
  module:
    - basic_auth
    - serialization
    - ticketmatic
id: ticketmatic
plugin_id: ticketmatic
granularity: resource
configuration:
  methods:
    - POST
  formats:
    - json
  authentication:
    - basic_auth
Lambic avatar
ph flag
At first glance it looks like it should work. Some obvious questions: Is the module enabled? Have you cleared cache? Is there anything pertinent in the logs? What does the enabled endpoint config look like?
Stephan de Bruin avatar
np flag
The module is enabled, cache is cleared, logs are cleared (multiple times). I've added the endpoint config to the original post.
Lambic avatar
ph flag
Try changing "https://www.drupal.org/link-relations/create" to just "create". Try using the request_stack service to get the request instead of passing it as a parameter to post().
Stephan de Bruin avatar
np flag
Thanks @Lambic, the "create" change was what fixed it.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.