How can you transfer data between websites? There are many options and modules for Drupal out there. You can use the Services, RESTful Web Services or Views Datasource module. However, using those modules can sometimes be a bit overkill. If all you want to do is expose some data via JSON so that it's accessible for other websites, then it’s easier to create a custom menu item and just return the exposed data as JSON from a menu callback.
In this article, we'll look at encoding and decoding JSON within Drupal as well as creating a JSON endpoint for content.
Drupal offers two functions for encoding and decoding JSON. To encode an array into JSON use drupal_json_encode()
and to decode a JSON object into an array use the – can you guess it? – drupal_json_decode()
function.
Encoding JSON
First, let’s look at encoding an array into JSON. Take this array for example:
$array = array('Boat', 'Car', 'Ship', 'Building');
If we were to encode the above array into JSON, you will get ["Boat","Car","Ship","Building"]
returned. Here is a code example:
$array = array('Boat', 'Car', 'Ship', 'Building'); $output = drupal_json_encode($array); // $output will be ["Boat","Car","Ship","Building"]
Decoding JSON
Now let's look at decoding a JSON object. If you were to running the following code:
$json = '["Boat","Car","Ship","Building"]'; return drupal_json_decode($json);
The drupal_json_decode()
function will return an array.
So far we have looked at the drupal_json_encode()
and drupal_json_decode()
function and have seen how simple they are to use.
Pulling In JSON Objects
The next example I want to demonstrate is how to pull in a Twitter account using Twitter's GET users/show REST API.
First, we’ll need to get the JSON object and for this we’ll use the drupal_http_request()
function:
$request = drupal_http_request('https://api.twitter.com/1/users/show.json?screen_name=TwitterAPI&include_entities=true');
Within the $request
variable, there will be a data property $request->data
. This stores the JSON object.
The only thing left to do is decode the data property to get access to all the information.
$request = drupal_http_request('https://api.twitter.com/1/users/show.json?screen_name=TwitterAPI&include_entities=true'); return drupal_json_decode($request->data);
Example of the decoded array:
JSON Endpoints
The last item I want to demonstrate is how to create a JSON endpoint for content on a Drupal site. For example, if you navigate to example.com/node/1/json the website will output a JSON version of the content. This will show you how to output a full JSON page using the drupal_json_output() function.
NOTE: If you want to create JSON or XML endpoints on a production site look at using the Services module.
1. First we must implement a menu item using the hook_menu. The menu item path needs to be "node/%node/json". For more details on how to use hook_menu check out the API documentation.
/** * Implements hook_menu(). */ function ww_json_example_menu() { $items['node/%node/json'] = array( 'page callback' => 'ww_json_example_endpoint', 'page arguments' => array(1), 'access arguments' => array('access content'), ); return $items; }
2. Create a "page callback" function for the menu item. Also, make sure that you add a $node variable to the function signature. For this example, the page callback is "ww_json_example_endpoint". Finally, we pass the $node object through to the drupal_json_output() function. If you go to node/1/json you should just see outputted JSON code.
function ww_json_example_endpoint($node) { drupal_json_output($node); }
If you have any questions please leave a comment below.
In the last part you wrote drupal_json_output($node). However the return value of this function is json and $node value is “nid” (a number). How is that going to print the content of that node? Or am I missing something?
The $node variable will be a full node object and not a single nid and here’s why.
The menu system has a feature called “auto-loader wildcard components”. What this means is that if you have a menu item path with “node/%node/json” the menu system will pass the nid ID in the URL through the
node_load()
function and pass loaded node object into the page callback function.From the hook_menu API documentation page:
Thanks, that explains everything and ties all loose ends.
Hi,
great tutorial, just one question.
Can any of theses modules also handel OAuth?! This is need for eg. the new Twitter API 1.1
Regards,
Tobi
Not out of the box, you’ll have to do some extra work for OAuth.
Hi,
I had created json endpoint using hook_menu and drupal_json_output in page callback. I noticed when we enable the drupal default caching mechanism json output also gets cached and behave weirdly if we clear browser cache. Can we disable cache for json endpoints ?
I read somewhere that we can user ”delivery callback’ in our hook_menu, So what’s the difference then ?
How does it behave? The browser cache and server side (Drupal) cache are two different things.
If you try and disable Drupal’s cache you could hit performance issues.
Kind of new to the json data feed using drupal. I have successfully uploaded your module and enabled it, but now how do I call it or use it by creating a page or similar content. How do I configure it to show the data onto a new page or article?
The module is just an example module. What do you want to achieve? Do you want to display a twitter user’s details on your website?
Yes I’d like to see how you mek a call to the module in order to see the actual data on a page or article view.
The code example above uses Twitters JSON API to pull in the user object. Then, use
drupal_json_decode
to decode the JSON data.Hi.. It may be something silly but,
I am using the devel execute php on drupal 7 and when executing
$request = drupal_http_request(‘https://api.twitter.com/1/users/show.json?screen_name=TwitterAPI&include_entities=true’);
return drupal_json_decode($request->data);
I am not able to explore the array, just getting Array on my output…
If you try and return an array it will simply output “Array”.
Try,
$request = drupal_http_request('https://api.twitter.com/1/users/show.json?screen_name=TwitterAPI&include_entities=true');
dpm(drupal_json_decode($request->data));
Use
dpm
to output the array.Hey, thank you so much, I found it yesterday just a second before to get really mad!!!! 🙂
thanks anyway, great post
Hi,
I’m new to drupal. My issue is am redirecting my user to payment gateway server using $form_state[‘redirect’]=’mylink external link’. Once he completed his payment, it gets redirected to same page(form) from where he started. How can i get response parameters?
ref: http://www.example.com/en/help/sciguide#paymentsuccessfulform
Thanks in advance
The `#paymentsuccessfulform` string is never set to the server. Meaning, there is no way of knowing if a `#some` is in the URL using PHP.
A simple solution would be to add an extra argument to the URL like `en/help/sciguide/payment`. Then use the `arg()` function to check for `payment`.
Great article once again Ivan!
I was wondering if you have any suggestions in outptting a whole panel page, with context-associated panes and views. (text, highcharts, table-views etc.)
My usecase is, that I need to send the whole panel page as json, to a external API for rendering a PDF. – The print module is not my best friend in this case.
What do you think?
Best regards,
Steffen
I’ve never done it with Panels so I don’t know which exact function you need to call.
But, you’ll still need a menu item (for the URL) and a callback function that returns the Panels page via the drupal_json_output function.
The tricky part will be finding which Panels function to use.
Any idea how to clear the page cache when the json updates?
You’ll have to handle this on a case by case basis. It also depends on how often your JSON feed needs to be updated.
Hi,
How can I change encoding to UTF-8 ?
Thanks
Found this link in Google. Hope it helps.
http://stackoverflow.com/a/9864952
Thanks a lot
$menu = menu_tree_all_data(‘main-menu’);
I used this code to return main menu as json:
drupal_add_http_header(‘Content-Type’, ‘application/json; charset=utf-8’);
echo json_encode($result, JSON_UNESCAPED_UNICODE);
I am working on webservices in drupal 7. To return response for mobile app i used drupal_output_json.
e.g.
return drupal_json_output(array(
‘status’ => ‘2000’,
‘message’ => ‘Thank you. Verfications is done successfully.’
));
but it responding like.
{“status”:”2000″,”message”:”Thank you. Verfications is done successfully”}null
The null came with response any idea about it.
I’ve never seen this issue. It could be another module causing this problem or something in your setup.
I would try the drupal_json_output on a brand new basic Drupal 7 site and see if you get the same problem.
Hello,
How can I create an output from a Jason file , which is located in the local hard drive. Can I attach it with a particular content type. Please help me out. I will be waiting for your early response.
Hi Rajesh,
1. First you’ll need to load the JSON file off the file system. http://stackoverflow.com/a/4343664
2. Normalize the data and add it to the node entity, then save the node.
There’s properly more to it but these are the two main steps.
Good luck.
Cheers,
Ivan