Last updated September 26, 2012. Created by Raphael Apard on November 7, 2011.
Edited by jackbravo, rachit_gupta, kylebrowning. Log in to edit this page.
Endpoint requirements :
- Set "Authentification" as "Session authentication"
- Set "Response formatters" as "json"
- Check resources "User > Login" and "Node > Create"
User requirements :
- Add permission to create content type "page" for user role
<?php
/*
* Server REST - user.login
*/
// REST Server URL
$request_url = 'http://your-drupal/rest_server_endpoint/user/login';
// User data
$user_data = array(
'username' => 'user_name',
'password' => 'user_password',
);
$user_data = http_build_query($user_data);
// cURL
$curl = curl_init($request_url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/json')); // Accept JSON response
curl_setopt($curl, CURLOPT_POST, 1); // Do a regular HTTP POST
curl_setopt($curl, CURLOPT_POSTFIELDS, $user_data); // Set POST data
curl_setopt($curl, CURLOPT_HEADER, FALSE); // Ask to not return Header
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_FAILONERROR, TRUE);
$response = curl_exec($curl);
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
// Check if login was successful
if ($http_code == 200) {
// Convert json response as array
$logged_user = json_decode($response);
}
else {
// Get error msg
$http_message = curl_error($curl);
die($http_message);
}
/*
* Server REST - node.create
*/
// REST Server URL
$request_url = 'http://your-drupal/rest_server_endpoint/node';
// Node data
$node_data = array(
'title' => 'A node created with services 3.x and REST server',
'type' => 'page',
'body[und][0][value]' => '<p>Body</p>',
);
$node_data = http_build_query($node_data);
// Define cookie session
$cookie_session = $logged_user->session_name . '=' . $logged_user->sessid;
// cURL
$curl = curl_init($request_url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/json')); // Accept JSON response
curl_setopt($curl, CURLOPT_POST, 1); // Do a regular HTTP POST
curl_setopt($curl, CURLOPT_POSTFIELDS, $node_data); // Set POST data
curl_setopt($curl, CURLOPT_HEADER, FALSE); // Ask to not return Header
curl_setopt($curl, CURLOPT_COOKIE, "$cookie_session"); // use the previously saved session
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_FAILONERROR, TRUE);
$response = curl_exec($curl);
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
// Check if login was successful
if ($http_code == 200) {
// Convert json response as array
$node = json_decode($response);
}
else {
// Get error msg
$http_message = curl_error($curl);
die($http_message);
}
print_r($node);
?>If Successful
Response code: 200 OK
return node nid and node uri as json
If Unsuccessful
Response codes
401 Unauthorized: Wrong username or password, or user doesn't have right permission.
406 Title field required / type field is required
Comments
Small bug
I think the first instance of
curl_setopt($curl, CURLOPT_POSTFIELDS, $node_data); // Set POST datashould in fact be:
curl_setopt($curl, CURLOPT_POSTFIELDS, $user_data); // Set POST dataYou right ;). Fixed. Thanks
You right ;). Fixed. Thanks
Raphael
Thanks, good example; But to
Thanks, good example;
But to return Json object after successful login You have to send httpheaders too,
Ad this code to first part of script (User login);
<?phpcurl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/json'));
?>
http://passivemanagement.net/
I added this for the second
I added this for the second part too (also get a json response).
Raphael
To get this to work in
To get this to work in Services 3.x in D6, I had to enable:
application/x-www-form-urlencodedin server->request parsing. Otherwise I would get:The requested URL returned error: 406Simplistech Solutions - Simplifying technology for small businesses and entrepreneurs.
406 errors
In fact, I use the last services version on drupal 7, and I have got 406 errors too.
When I enable "jsonp" and "application/x-www-form-urlencoded", the first 406 error disappear (during the authentication), but it still appears during the node.create request!
Any idea?
Same 406 error here when I
Same 406 error here when I specify the node author. Anyone have a fix?
'uid' => 10,
'name' => 'myusername',
Thanks.
rest_server_endpoint?
I am not clear on how the request url is constructed in the example:
<?php$request_url = 'http://your-drupal/rest_server_endpoint/user/login';
?>
Is rest_server_endpoint a canonical name or a placeholder? In the first case, can someone point met to the documentation, in the second case. how and where is set?
Re: rest_server_endpoint?
rest_server_endpoint is a placeholder. You define endpoints in the services configuration (admin/build/services/add)
image filed
if i have a image filed how i can create node content with image?
drupal_http_request vs cURL?
There are drupal_http_request function , why do you use cURL?
Yes, we can use
Yes, we can use drupal_http_request, but for my example, i call webservice from another device, not from a other drupal.
Raphael
wow.. very nice post. Thanks.
wow.. very nice post.
Thanks.
Trying to get this sample,
Trying to get this sample, the script is returning a 302 error in $http_code var and I don't know what's the problem.
Anybody got the same problem or knows how to resolve it?
Thanks.
Regards
302 isn't an error
302 is the http code for a redirect, it's not an "error" as such.
Finally I could solve this
Finally I could solve this removing a redirect URL Rule that I had activated in Rules Module. Then I got 200 http response. Thanks
Communication to the service depends on ... the widget !
I found something really strange.
I have some term references in my custom node so, when I build my node_data I use for instance
$node_data['field_something[und]'] = array(array("tid"=>294));where field_something is a custom term reference.
I can create a node with term references, using curl. It is working well.
Except for the well known "field_tags", when the default widget for autocomplete is activated.
If I use Autocomplete Deluxe widget for field_tags, the service with curl is working !
I am really surprised of this behavior, should I post it in issues ? and where ? (service ? core ?)
Yann
Revised Code
I could not get the above code to work, so I went through and made some revisions based on other Documentation snippets and got this to work:
<?php
/*
* Server REST - user.login
*/
// REST Server URL
$request_url = 'http://your-drupal/rest_server_endpoint/user/login.json';
// User data
$user_data = array(
'username' => 'testuser',
'password' => '1password',
);
// cURL
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $request_url);
curl_setopt($curl, CURLOPT_POST, 1); // Do a regular HTTP POST
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($user_data)); // Set POST data
curl_setopt($curl, CURLOPT_HEADER, FALSE); // Ask to not return Header
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_FAILONERROR, TRUE);
$response = curl_exec($curl);
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
// Check if login was successful
if ($http_code == 200) {
// Convert json response as array
$logged_user = json_decode($response);
}
else {
// Get error msg
$http_message = curl_error($curl);
die($http_message);
}
/*
* Server REST - node.create
*/
// REST Server URL
$request_url = 'http://your-drupal/rest_server_endpoint/node';
// Node data
$node = (object) NULL;
$node->title = 'A node created with services 3.x and REST server';
$node->type = 'page';
$node->body['und'][0]['value'] = '<p>Body</p>';
$node->path = '';
$node_data = (array) $node;
$node_data = json_encode($node_data);
// Define cookie session
$cookie_session = $logged_user->session_name . '=' . $logged_user->sessid;
// cURL
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $request_url);
curl_setopt($curl, CURLOPT_POST, TRUE); // Do a regular HTTP POST
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/json', 'Content-Type: application/json')); // Accept
curl_setopt($curl, CURLOPT_POSTFIELDS, $node_data); // Set POST data
curl_setopt($curl, CURLOPT_HEADER, TRUE); // Ask to not return Header
curl_setopt($curl, CURLOPT_COOKIE, $cookie_session); // use the previously saved session
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_FAILONERROR, FALSE); //True in prod, false for debugging
$response = curl_exec($curl);
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
// Check if login was successful
if ($http_code == 200) {
// Convert json response as array
$node = json_decode($response);
}
else {
// Get error msg
$http_message = curl_error($curl);
die($http_message);
}
print_r($node);
?>
It's definitely worth
It's definitely worth var_dump-ing the $http_code and $response after they've been defined to find out exactly where things have gone wrong. Particularly with regards to a 406 error (for instance the default D7 node type is basic_page which is easy to miss).
For some reason, I keep
For some reason, I keep getting error 401 although I'm really sure I got the $cookie_session set.
Edit: The solution was to enable "Session authentication" in the edit settings for the services.
I am also getting the 401
I am also getting the 401 error and do not understand it.
I tried the first code sample and only changed the endpoint url to match my site. When i ran this I got a 406 error in the node create section.
I changed to the second code sample and this time I am getting the 401 error suggesting an authorisation failure.
I have checked and I have "Session authentication" set in the edit settings for the service I have created in services.
I am using Drupal 7.14 and Services 3
I would appreciate any idea where to look for this authentication issue.
same here, but I'm using D6
same here, but I'm using D6 instead!!
Try the first code sample and
Try the first code sample and enable "application/x-www-form-urlencoded" in server tab, that's how I fix this problem.
That one works
I only had "application/json" and it was complaining that the title was missing. Then I enabled "application/x-www-form-urlencoded" and it works fine. Thanks.
how to post tags and categories with this script
Nice script, however I want to post tags and category along with node data how can I send it? what parameter should I add in node data array?
$node_data = array('title' => 'A node created with services 3.x and REST server',
'type' => 'page',
'body[und][0][value]' => '<p>Body</p>',
);