It's not about how you load the entity. It's how you build the response. You have to add the correct cache tags. A cacheable response has the method addCacheableDependency()
, which accepts objects which provide cache metadata:
$response->addCacheableDependency($entity);
This adds the tag custom_entity:[id]
to the cached response. All cached responses with this tag will be invalidated, when the entity is updated.
This is an example from core for the cache data and access checks you need in a response which contains entity data:
Drupal\rest\Plugin\rest\resource::get()
public function get(EntityInterface $entity) {
$entity_access = $entity->access('view', NULL, TRUE);
if (!$entity_access->isAllowed()) {
throw new AccessDeniedHttpException();
}
$response = new ResourceResponse($entity, 200);
$response->addCacheableDependency($entity);
$response->addCacheableDependency($entity_access);
if ($entity instanceof FieldableEntityInterface) {
foreach ($entity as $field_name => $field) {
/** @var \Drupal\Core\Field\FieldItemListInterface $field */
$field_access = $field->access('view', NULL, TRUE);
$response->addCacheableDependency($field_access);
if (!$field_access->isAllowed()) {
$entity->set($field_name, NULL);
}
}
}
return $response;
}