0

I try to create a REST resource. I used EntityResource as base. I would like to return my fields in html. Here is a exemple of my code :

public function get($id) {
    if (!$this->currentUser->hasPermission('access content')) {
      throw new AccessDeniedHttpException();
    }

    $entity = \Drupal::entityTypeManager()->getStorage('node')->load($id);
    $entity_access = $entity->access('view', NULL, TRUE);
    if (!$entity_access->isAllowed()) {
      throw new AccessDeniedHttpException($entity_access->getReason() ? : $this->generateFallbackAccessDeniedMessage($entity, 'view'));
    }

    $result = array();
    $other_entity_dependency = array();
    if ($entity instanceof FieldableEntityInterface) {
      $fields = array();
      $contentType = $entity->bundle();
      if (isset($contentType) && !empty($contentType)) {
        foreach (\Drupal::entityManager()->getFieldDefinitions('node', $contentType) as $field_name => $field_definition) {
          if (!empty($field_definition->getTargetBundle())) {
            $fields[] = $field_name;
          }
        }
      }
      foreach ($fields as $field_name) {
        $field = $entity->$field_name;
        $field_access = $field->access('view', NULL, TRUE);
        if ($field_access->isAllowed()) {
           $value = \Drupal::service('renderer')->render($field->view())
           $result[$field_name]['value'] = $value;
            $result[$field_name]['label'] = $field->getFieldDefinition()->getLabel();

        }
      }
    }


    $response = new ResourceResponse($result, Response::HTTP_OK);
    $response->addCacheableDependency($entity);
    $response->addCacheableDependency($entity_access);

      return $response;
  }

The problem is that when I use a render function, I have this error :

The controller result claims to be providing relevant cache metadata, but leaked metadata was detected. Please ensure you are not rendering content too early. Returned object class: Drupal\rest\ResourceResponse.

I haven't this issue when I use $field->value instead of \Drupal::service('renderer')->render($field->view()), but I would like to have the html render of fields, for file or image too (these types of fields are empty when I use $field->value).

How can I solve this problem ?

  • Don't render arrays get rendered anyway? Can't you just use $value = $field->view() and be done with it? – Clive Jan 31 '18 at 10:35
  • When use only $value = $field->view() I get this error : Uncaught PHP Exception Symfony\\Component\\Serializer\\Exception\\UnexpectedValueException: "Could not normalize object of type Drupal\\Core\\Url, no supporting normalizer found." – Lucuhb Jan 31 '18 at 10:47
  • Actually I guess that makes sense, there's no context available - how would it know what theme to use, for example? – Clive Jan 31 '18 at 12:02
0

The problem is, that render() produces metadata which leaks to the outside of the controller. You can try renderPlain() if you don't care about the metadata or see this question how to provide your own render context to catch the metadata and add it to the response:

How to get cache metadata from nested render array when returning response?

  • Thanks, I use the exemple that you give and now all metadata are catched. : the error is gone away. – Lucuhb Feb 6 '18 at 16:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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