1

Our Drupal site utilizes a number of menu hooks to return JSON from an API we manage in a separate Web API. We also have a number of intensive tasks that happen on each page load via the hooks_init in several custom modules.

The issue we're facing is that the tasks in hook_init are only required for actual pages, and should not be executed when all we want is JSON output. Is there a way to ONLY execute the hook_menu endpoint, and no other Drupal code?

We have several pages that make 3-4 requests to Drupal JSON menu links, which means that we also run our unnecessary hook_init tasks 3-4 times as well -- plus once for the actual page request.

There must be a way to circumvent the usual Drupal pipeline to perform these actions?

Here is an example of one of our JSON menu hooks:

function membership_details()
{

    // Get membership details from API, and return as JSON
    $details =  sendCurlResponse(/* ENDPOINT */);
    drupal_json_output($details);
    drupal_exit();
}
4
  • According to the comments in _drupal_bootstrap_full() that's going to be difficult (if not impossible) inside a normal request. This comes just before hook_init is invoked (the only place it's invoked in the core codebase): Let all modules take action before the menu system handles the request. Sounds like hook_init happening before routing is intentional
    – Clive
    Aug 25, 2015 at 22:34
  • If that's the case, then is there a better way we could structure our JSON endpoints to avoid this issue altogether? Is there any known method of implementing JSON endpoints without using menu_hooks? Aug 25, 2015 at 22:35
  • I think you're on your own there sadly. I can't think of another mechanism Drupal offers that could help. Perhaps refactoring the code in hook_init not to respond on xmlhttprequests is an option? Unsavoury, I know. Or you could implement the routing in custom code and bootstrap Drupal to a lesser level for your JSON endpoints. Not sure of your exact use case there. No nice options spring to mind though I'm afraid
    – Clive
    Aug 25, 2015 at 22:45
  • Sounds like the best approach is not to use Drupal menu_hooks for simple JSON output... lol Aug 26, 2015 at 0:39

1 Answer 1

0

hook_init() is invoked before the menu system deals with the request, and in the confines of a normal Drupal bootstrap, no, it's not possible to circumvent that workflow.

It's by design though, if you look at the docs:

Perform setup tasks for non-cached page requests.

This hook is run at the beginning of the page request. It is typically used to set up global parameters that are needed later in the request. When this hook is called, the theme and all modules are already loaded in memory.

Emphasis mine.

So for its intended use, hook_init should only set up variables that are required for the current request. Whether that be a request for HTML, JSON, or whatever else.

You have two pretty reasonable options as far as I can tell:

  1. Augment the code you have in hook_init implementations to check whether it should be executed based on parameters from the request (accepted content type, file extension, whatever makes the most sense for you use case).
  2. Move the logic in hook_init to another hook, one that's invoked later in the process (I can't really say which hook that would be without knowing what the code does)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.