Last updated July 15, 2014. Created on September 26, 2013.
Edited by clemens.tolboom, juampy, gavin.hughes, klausi. Log in to edit this page.

Introduction

Currently, the only core format which can handle POST requests is application/hal+json. Enable HAL module to support this media type.

In the following examples we use HTTP Basic Authentication to authenticate the request so make sure to enable the module.

Relations

As most of the content in Drupal has relations make sure the relations are properly added to the payload.

As we must use HAL the relations are currently through the _links entry. Issues in need to fix this are in both https://www.drupal.org/project/issues/search/drupal?version[]=8.x&compon... and https://www.drupal.org/project/issues/search/drupal?version[]=8.x&compon...

For instance if you want to POST a new comment you need a _link entry to the user and to the entity the comment is for. Best way to get this is to first GET an example and study its _links.

Never POST a uuid as you create a new entity.

Configuration

Follow the steps in the GET configuration instructions. To enable POSTing to a resource, you must add it to the nested array for the resource. For example, the following config enables both GET and POST on nodes.

# Example configuration for enabling REST resources.
resources:
  # Enable the node resource.
  'entity:node':
    GET:
      supported_formats:
        - json
        - hal_json
      supported_auth:
        - basic_auth
    POST:
      supported_formats:
        - hal_json
      supported_auth:
        - basic_auth

Setting permissions

Permissions are configured using the same steps as for GET requests. Typically, a limited number of roles will be given access to POST content entities.

Testing with a POST request

To follow these tests, grant access to the role which you are testing with. To ensure that authentication is working, you should not grant access to the anonymous user until you have verified that it is working.

cURL (command line)

curl --include \
  --request POST \
  --user klausi:secret \
  --header 'Content-type: application/hal+json' \
  http://drupal-8.localhost/entity/node \
  --data-binary '{"_links":{"type":{"href":"http://drupal-8.localhost/rest/type/node/page"}}, "title":[{"value":"test title"}]}'

Guzzle

<?php
use Guzzle\Http\Client;

$client = new Client('http://drupal-8.localhost');
// If in a Drupal environment use the HTTP client service.
$client = \Drupal::httpClient()->setBaseUrl('http://drupal-8.localhost');

$node = array(
 
'_links' => array(
   
'type' => array(
     
'href' => 'http://drupal-8.localhost/rest/type/node/page'
   
)
  ),
 
'title' => array(0 => array('value' => 'New node title')),
);
$data = json_encode($node);

$response = $client->post('entity/node', array(
   
'Content-type' => 'application/hal+json',
  ),
$data)
 
// Username and password for HTTP Basic Authentication.
 
->setAuth('klausi', 'secret')
  ->
send();
if (
$response->getStatusCode() == 201) {
  print
'Node creation successful!';
}
?>

Dev HTTP client

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

ambientdrup’s picture

I'm trying to run the post request via command line and I'm getting this error:

HTTP/1.1 400 Bad Request
Date: Thu, 17 Oct 2013 14:34:40 GMT
Server: Apache
X-Powered-By: PHP/5.3.20
Cache-Control: must-revalidate, no-cache, post-check=0, pre-check=0, private
X-UA-Compatible: IE=edge,chrome=1
Content-language: en
Last-Modified: Thu, 17 Oct 2013 14:34:40 GMT
ETag: "1382020480"
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Connection: close
Transfer-Encoding: chunked
Content-Type: application/hal+json

{"error":"The type link relation must be specified."}

ybabel’s picture

try this instead :
curl --include --request POST --user admin:admin --header 'Content-type: application/hal+json' http://localhost/drupal8/entity/node/ --data-binary '{"_links":{"type":{"href":"http://localhost/drupal8/rest/type/node/page"}},"title":[{"value":"test title"}]}'

Formateur, consultant, Drupal 6,7,8, symfony2

designdit’s picture

Hi,

Thanks for the guides - I've had success with the "Get on content entities" and "Get on Views-generates lists" guides, but can't get the post to work. I've tried to POST both a basic page and my own content entity and neither works. I've tried a lot of variations, including removing "entity" from the url as per the changes in Drupal 8, but the post still does not work. I'm using Postman in Chrome for testing and again, I can "GET" a basic page and my own content entity just fine, but with POST, I always get a return code of 200 "OK", never "201" and the nodes don't get created.

I've updated the rest.settings.yml and have established permissions for the user. Any idea what's missing? Do I need to add coding in my create entity form to "receive" the posted data? Where do I do this/in which directories should the files go? Is this required for the default Basic Page content type, too?

Thanks for any help...I've spent weeks on this and can't figure out what I'm missing.

Thanks,
designdit

designdit’s picture

Hi,

Can anyone get POST to work on D8 alpha 11 using this guide? Maybe it worked for a previous release, but I still can't get it to work on alpha 11, even for a basic page. Have there been any changes to the required config, etc.?

Thank you,
designdit

gavin.hughes’s picture

I was getting the same error.
Using the suggested code suggested by ybabel https://drupal.org/node/2098511#comment-8003819
Resolved the problem!
curl --include --request POST --user admin:admin --header 'Content-type: application/hal+json' http://localhost/drupal8/entity/node/ --data-binary '{"_links":{"type":{"href":"http://localhost/drupal8/rest/type/node/page"}},"title":[{"value":"test title"}]}'

updated the node

designdit’s picture

Hi gavin.hughes,

Thanks so much for your response. I've tried again as per the suggested solution, but it still does not work. I still get a status of 200 (OK) - I don't get the 400 error, but also don't get a new node/status of 201. Still lost.

Thank you,
designdit

designdit’s picture

Hi,

I am getting the 400 error now, but the suggested code (ybabel and gavin.hughes) does not work. I've tried this in the Chrome Rest Client, Postman, and Dev HTTP Client (of course, with my url and authentication) and still keep getting 400 Bad Request, "error": "The type link relation must be specified.":

curl --include --request POST --user admin:admin --header 'Content-type: application/hal+json' http://localhost/drupal8/entity/node/ --data-binary '{"_links":{"type":{"href":"http://localhost/drupal8/rest/type/node/page"}},"title":[{"value":"test title"}]}'

I've also tried it without the trailing "/": http://localhost/drupal8/entity/node (no "/" after node), and still getting the same error.

Thanks for any other suggestions.

hemantgoyal’s picture

Did you try looking in the db if the node was created or not. Usually nodes get created but are not published. you might want to add this to your POST function.

$node->promote = NODE_PROMOTED;

Hemant Goyal

vivekvpandya’s picture

Vivek Pandya

designdit’s picture

Hello Vivek,

The link you posted does not work (results in "page not found"). Does it address the specific return code issues or is it a general guide? The guides here on the drupal site are fine and I've been able to make the GET work as I've mentioned, so really just looking for what the specific issue might be with the POST, and not a general guide.

Thank you,
designdit

vivekvpandya’s picture

I am very sorry for this inconvenience.
Here is correct link
http://tntfoss-vivekvpandya.rhcloud.com/node/40

I have faced problem to edit my last comment due to spammer role.

Vivek Pandya