1

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
4
  • 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?
    – Lambic
    Dec 23 '21 at 14:51
  • The module is enabled, cache is cleared, logs are cleared (multiple times). I've added the endpoint config to the original post. Dec 23 '21 at 14:58
  • 1
    Try changing "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().
    – Lambic
    Dec 23 '21 at 15:03
  • Thanks @Lambic, the "create" change was what fixed it. Dec 23 '21 at 15:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.