Services 3 - POST node.create with custom fields

Last updated on
30 April 2025

Using the module Services to create a node with required custom fields may be challenging. Most of the problems fall on formatting the data to be sent.

Here are three examples of how to figure out how format the data. The first example is the easiest, it will show how to post a Text field. The second example will use a fivestar field. Finally, the third example will show how to use a node reference field with auto complete widget.

I will send the data in JSON format, but this tutorial can be used for any format your web service accepts.

Tools I will use:

Step-by-step

  1. Figure out how Drupal wants to receive the data structure

  2. Build the data structure

  3. POST the data structure

  4. Verify if it worked

  1. Figure out how Drupal wants to receive the data structure

  2. For all examples, the first step is to figure out how Drupal handles the data object of that node. An easy way to do it is to use add a custom block to the page which has the form used to create the node. Use PHP format and input this code:

    <?php
    dpm($_POST);
    ?>
    

    This code will output the data object right after you create a new node.

    Then, try it once to see this structured data. You will see something like:
    dpm() example

    The important parts are:

    The Text field
    dpm() of Text field

    The fivestar field
    dpm() of Fivestar field

    The node reference field
    dpm() of Node Reference field

  3. Build the data structure

  4. The Text field is the easiest. You have to build the same structure you see on the dpm():

    {
       "field_review":[
          {
             "value":"The user comments"
          }
       ]
    }
    

    Compare with the dpm() data:
    Text field dpm()

    If you use http://braincast.nl/samples/jsoneditor/ to build your JSON tree, you can see the path as json['field_review'][0]['value'], which matches the Text field structure on the dpm(). The value "The user comments" is the text value sent for the Text field.

    Note that there is no "0" (zero) in the structure. In this very specific case, it would work. However, in other cases, such as the node review field with auto complete, it may lead errors!

    It works without the zero because JSON already put it on the path as the first index of arrays.

    The structure for the fivestar field is the following:

    {
       "field_fivestar_value":[
          {
             "rating":"100",
             "target":"0"
          }
       ]
    }
    

    Compare to:
    Fivestar dpm()

    Note again I did not use "0", even knowing it would work. Moreover, in this specific example, I'm not targeting the fivestar rating. In my case, the only allowed values for "rating" were "20", "40", "60", "80", or "100".

    The tricky part is the node reference field, when it is set to use the auto complete widget. You have to query "[nid:xxxx]" to avoid errors such as "found no valid post with that title".

    This field on JSON format looks like:

    {
       "field_establishment":[
          {
             "nid":{
                "nid":"[nid:26686]"
             }
          }
       ]
    }
    

    Compare to:
    Node reference dpm()

  5. POST the data structure

  6. The first thing you should know before posting is that a node requires a title field. In addition, to create the node, you have to specify the node type you are creating. Then, include this data:

    {
       "title":"Review",
       "type":"establishment_review"
    }
    

    Now, get everything together:

    {
       "title":"Review",
       "type":"establishment_review",
       "field_establishment":[
          {
             "nid":{
                "nid":"[nid:26686]"
             }
          }
       ],
       "field_fivestar_value":[
          {
             "rating":"20",
             "target":"0"
          }
       ],
       "field_review":[
          {
             "value":"comments about the restaurant"
          }
       ]
    }
    

    Note that there is no curly brackets ({ nor }) surrounding each field. This is very important, and it will not work if you leave them there.

    Your data is ready to be POSTed.

    Use the firefox add-on Poster to test it:
    Firefox Poster screenshot
    Note that the data is not indented and I am not using multiple lines to organize the data. This is to avoid errors. It happened once when I copied the code to OneNote, and later pasted again in Poster. The format changed with some extra unwanted spaces and it messed the data. It may lead to false errors!. Again, use a single line of data when using Poster.

    The URL is your Drupal web address + your Services endpoint + requested resource. In this case:
    Drupal address: http://example.com
    Services endpoint: /rest_api
    Requested resource: /node
    Also change the Content Type to application/json

    You should get a response like:

    Poster responseNote the HTTP 200 OK status. It means the web service processed your request.

    If you want the response also in JSON, change the URL to http://example.com/rest_api/node.json

  7. Verify if it worked

  8. A you can see on the response:

    <?xml version="1.0" encoding="utf-8"?>
    <result><nid>5138098</nid><uri>http://example.com/rest_api/node/5138098</uri></result>

    Just put write on your browser address bar: http://example.com/node/5138098. The browser should open your new node.

Add on for Field Collection

In case you are using Field Collection in your node here is example how to deal with such type of fields.

Example:
You have Field Collection for mobile number having two fields:
1. Mobile Number (Text Field)
2. Privacy Options (List Dropdown): Dropdown Values(1 => 'Private', 2 => 'Public')

Field Collection Example

Here is JSON Structure for this:

"field_mobile_number_collection": {
  "und": [ 
   {
    "field_mobile_number": {
	"und": [
	  {
	     "value": "123456789"
	  }
	]
     },
     "field_privacy_options": {
	"und": "1"
     }
   }
 ]
}

Help improve this page

Page status: Not set

You can: