How do I consume JSON data via a hook_menu callback?
Question
I'm trying to set up Tropo's WebAPI with a Drupal site, and I thought I'd just create a hook_menu() callback for example.com/tropo, then use the hook_menu callback I just created to consume the API call from Tropo (which contains a simple JSON array of data), then respond.
I can do the response part pretty easily... build the data, drupal_json_output() and exit (that just returns the JSON basically).
The part I'm having trouble with is getting the data that is sent to the /tropo menu callback... I can't access any data by using either of the following:
$json = file_get_contents("php://input"); // returns NULL
(below uses the inputstream module:)
$json = file_get_contents("drupal://input"); // also returns NULL
I checked what some other modules do, and it looks like they use hook_init to grab the JSON. Is this the preferred method? I'd love to be able to do it in hook_menu and use my own path and such...
Alternatively, would I be better off writing my own PHP script and running outside of Drupal, just doing a bootstrap for the database if I need to?
Solution
Well, it turns out I was getting the data, but I forgot to decode it...
In my hook_menu callback:
$received = file_get_contents("drupal://input"); // Use inputstream module.
$received = json_decode($received, TRUE);
Then I can play around as much as I'd like with the $received value.
Additionally, the inputstream module is invaluable in letting me get to the input stream more than once (if you try using php://input
more than once, the second time, and those following, will return NULL).
As an additional note, I just noticed today a new module that might be an even simpler way of handling this: Content as JSON
OTHER TIPS
The REST Server that is part of the Services module does this automatically for JSON as well as for other formats: http://drupal.org/project/services
It also supports Inputstream (Inputstream was built to handle both OAuth verification and Services decoding of the same stream).