Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

POST method not allowed on custom Drupal 8 REST resource

Tags:

drupal

I've created a custom RestResource, it kind of looks like this:

/**
 * Provides a resource to get/create content data.
 *
 * @RestResource(
 *   id = "arcelor_content",
 *   label = @Translation("Arcelor content"),
 *   uri_paths = {
 *     "canonical" = "/api/content/{type}"
 *   }
 * )
 */
class ContentResource extends ResourceBase {

    public function get($type) {
        // Works
    }

    public function post($type) {
        // Doesn't work
    }
}

I've enabled the resource and set the permissions in RestUI.

The GET method works fine, but when I try to post I get this error:

{
"message": "No route found for \"POST /api/content/buffer\": Method Not Allowed (Allow: GET)"
}

Method not allowed! Even though the permissions have been set, post has been enabled, the cache has been flushed a million times, ...

I came across a question on the drupal site that said it could be fixed by adding another uri_path to the phpdoc tag, so I did:

/**
 * Provides a resource to get/create content data.
 *
 * @RestResource(
 *   id = "arcelor_content",
 *   label = @Translation("Arcelor content"),
 *   uri_paths = {
 *     "canonical" = "/api/content/{type}",
 *     "https://www.drupal.org/link-relations/create" = "/api/content/{type}"
 *   }
 * )
 */

Unfortunately that did nothing, and I still get the "not allowed" error.

So, does anyone know what's going on here?

like image 915
skerit Avatar asked Mar 29 '16 09:03

skerit


Video Answer


2 Answers

2 things were causing the "not allowed" problem:

  1. POST methods require the Content-Type header to be set to application/hal+json, that's the only thing they will accept. Even if you plan to do something different with regular JSON data, you'll have to work around this somehow (which I failed to do)
  2. POST methods also require the X-CSRF-Token header to be set, you can get a token by going to /rest/session/token

Now I am no longer getting the "not allowed" error! Unfortunately, because the body needs to be hal+json, I'm getting an "A fatal error occurred: Class does not exist" error now.

like image 115
skerit Avatar answered Nov 15 '22 07:11

skerit


For me, under Drupal 8.2.6, what solve the problem of Method not allowed for POST is that I forget to specify the create URI in the resource definition annotation:

/**
 * Provides a resource for clients subscription to updates.
 *
 * @RestResource(
 *   id = "updates_subscription",
 *   label = @Translation("Updates subscription"),
 *   uri_paths = {
 *     "canonical" = "/api/updates-subscription",
 *     "https://www.drupal.org/link-relations/create" = "/api/updates-subscription"
 *   }
 * )
 */

The fact is that if you forget to specify the "https://www.drupal.org/link-relations/create" URI path, Drupal defaults to the resource id path, updates_subscription in this case.

You can read this here, in the Creating REST resource plugins section.

No need for application/hal+json content type neither to use a X-CSRF-Token.

like image 45
Juanmi Sosso Avatar answered Nov 15 '22 09:11

Juanmi Sosso