How can I avoid to return HTML markup for access denied? I've developed a custom controller that serves as a simple endpoint, POST method.
This controller has custom access control.
Custom access is done by looking for a header in the HTTP request, by making the controller object a service as well.
Everything works great. Except that when I return AccessResult::forbidden() .. I get the HTML of the access denied page .. and I don't really want that .. I'd like to return just a short bit of JSON.
What can I do to return something that is JSON, and not the Access Denied page HTML, for this particular route, when the access() method returns AccessResult::forbidden() ?
I've read that appending ?_format=json to the url works, and in my case it does. Is there anyway to achieve the same result without adding this url parameter?
If you look into ParagraphAccessControlHandler you will find something similar.
Implement something similar in your Access callback.
protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {



// Allow paragraph entities to be created in the context of entity forms.
  if (\Drupal::requestStack()
    -&gt;getCurrentRequest()
    -&gt;getRequestFormat() === 'html') {
    return AccessResult::allowed()
      -&gt;addCacheContexts([
      'request_format',
    ]);
  }
  return AccessResult::neutral()
    -&gt;addCacheContexts([
    'request_format',
  ]);
}