I have custom module with some routes which return JSON, for instance terms of a vocabulary.
routing.yml
mymodule.terms:
path: '/api/terms/{vid}'
defaults:
_controller: '\Drupal\mymodule\Controller\MyModuleController::getTerms'
_title: 'Terms'
requirements:
_permission: 'access content'
vid: '^(foobar|barfoo)$'
Controller:
public function getTerms($vid) {
$response = $this->jsonifyVocabulary($vid);
return $response;
}
private function jsonifyVocabulary($vid) {
$request = \Drupal::request();
$lang = $request->query->get('lang', 'en');
$output = [];
$taxonomyManager = \Drupal::entityManager()->getStorage('taxonomy_term');
$terms = $taxonomyManager->loadTree($vid, 0, 1, false);
$response = CacheableJsonResponse::create($output);
debug(1);
foreach ($terms as $term) {
$term = Term::load($term->tid);
if ($term->hasTranslation($lang) && $lang !== $term->language()) {
$term = $term->getTranslation($lang);
}
$entry = [
'tid' => (int) $term->id(),
'label' => $term->getName(),
];
// $response->addCacheableDependency($term);
$output[$vid][] = $entry;
}
$response->setData($output);
$cacheMeta = (new CacheableMetadata())->addCacheContexts(['url.query_args:lang']);
$response->addCacheableDependency($cacheMeta);
return $response;
}
Thanks to this answer I know how to actually add the URL params as a cache context, but the
debug(1);
always gets called, I guess I just somehow have to tell Drupal that this JSON response's cache should relate to that route...
I don't use the core's REST module on purpose since I find it hard to configure to output exactly what I need.