Last updated May 17, 2015. Created on September 26, 2013.
Edited by Jaesin, askibinski, clemens.tolboom, juampynr. 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.

* Related issue to support application/json for POST

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
// Prepare entity data.
$serialized_entity = json_encode([
 
'title' => [['value' => 'Example node title']],
 
'type' => [['target_id' => 'article']],
 
'_links' => ['type' => [
     
'href' => 'http://example.com/rest/type/node/page'
 
]],
]);

// Create the Node.
$response = \Drupal::httpClient()
  ->
post('http://example.com/entity/node', [
   
// Username and password for HTTP Basic Authentication.
   
'auth' => ['admin', 'drupal'],
   
'body' => $serialized_entity,
   
'headers' => [
     
'Accept' => 'application/hal+json',
     
'Content-Type' => 'application/hal+json'
   
],
  ]);

// Check for the correct status code.
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

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

vivekvpandya’s picture

Vivek Pandya

christianmgrupp’s picture

Hello,

I am just jumping into Drupal 8 and familiarizing myself with HAL. I am able to successfully able to create a node of type "basic page" with the following CURL script:
curl --include --request POST --user test-user:XXXXXXX --header 'Content-type: application/hal+json' http://d8beta.dd:8083/entity/node --data-binary '{"_links":{"type":{"href":"http://d8beta.dd:8083/rest/type/node/page"}}, "title":[{"value":"My first page"}]}'

I have a custom content type with a machine name of "test_content_type"

When I try to submit the following it still adds it as a basic page:
curl --include --request POST --user test-user:XXXXXX --header 'Content-type: application/hal+json' http://d8beta.dd:8083/entity/node --data-binary '{"_links":{"type":{"href":"http://d8beta.dd:8083/rest/type/node/page"}}, "title":[{"value":"My first page"}],"type":[{"target_id":"test_content_type"}]}'

When I submit the following it gives me an error saying that: {"error":"Type http:\/\/d8beta.dd:8083\/rest\/type\/node\/test_content_type does not correspond to an entity on this site."} :
curl --include --request POST --user test-user:XXXXXX --header 'Content-type: application/hal+json' http://d8beta.dd:8083/entity/node --data-binary '{"_links":{"type":{"href":"http://d8beta.dd:8083/rest/type/node/test_content_type"}}, "title":[{"value":"My first page"}],"type":[{"target_id":"test_content_type"}]}'

I am running the latest version of the Drupal 8 beta (8.0.0-beta12).

Thanks in advance for the help!

likewhoa’s picture

@christianmgrupp just remove ""type":[{"target_id":"test_content_type"}]" as you are already referencing the content type.

Bending technology to fit business

christianmgrupp’s picture

{Edited out earlier reply of density}

Yep, that's it.

Thank you for the help.