Include parameter doesn't work with different type of entities

Created on 24 September 2020, almost 4 years ago
Updated 16 May 2024, about 1 month ago

Problem/Motivation

When returning a list of entities that are not the same, or a list of nodes with different content-types, if the "include" parameters is used, it checks for the first entity if this field can be included and if not possible, it raises an error with message:

title: "Bad Request",
status: "400",
detail: "`article_category` is not a valid relationship field name. Possible values: node_type, revision_uid, uid, menu_link, category, content_paragraphs, featured_image, related_content, tags, useful_links.",

An example of module that uses JSON:API Resources is JSON:API Search API β†’ , which makes a lot of sense to return node within different content types.

Proposed resolution

My suggestion is to receive the resource identifier as part of include path and check that before include it, something like ?include=node--article.article_category.

πŸ› Bug report
Status

Fixed

Version

1.0

Component

Code

Created by

πŸ‡§πŸ‡ͺBelgium lisotton Brussels

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡ΈUnited States mglaman WI, USA
  • πŸ‡ΊπŸ‡ΈUnited States mglaman WI, USA

    I don't like adding non-standard parameters for include.

    \Drupal\jsonapi\Context\FieldResolver::resolveInternalIncludePath is what throws this error.

        $public_field_name = $path_parts[0];
        $internal_field_name = $resource_type->getInternalName($public_field_name);
        $relatable_resource_types = $resource_type->getRelatableResourceTypesByField($public_field_name);
        if (empty($relatable_resource_types)) {
          $message = "`$public_field_name` is not a valid relationship field name.";
          if (!empty(($possible = implode(', ', array_keys($resource_type->getRelatableResourceTypes()))))) {
            $message .= " Possible values: $possible.";
          }
          throw new CacheableBadRequestHttpException($cacheability, $message);
        }
    

    The exploded paths is the include parameter

        // $include_parameter: 'one.two.three, one.two.four'.
        $include_paths = array_map('trim', explode(',', $include_parameter));
        // $exploded_paths: [['one', 'two', 'three'], ['one', 'two', 'four']].
        $exploded_paths = array_map(function ($include_path) {
          return array_map('trim', explode('.', $include_path));
        }, $include_paths);
    

    So we could follow the patch's approach of iterating over each data, getting the resource type and checking if the include applies to the resource object. Then run \Drupal\jsonapi\JsonApiResource\Data::deduplicate at the end. The main difference if performing the check ourselves versus ignoring the exception.

    Maybe we should provide our own include resolver which wraps \Drupal\jsonapi\IncludeResolver and supports missing relationships, only for jsonapi_resources resources. But I feel like there should still be some kind of error if a relationship is requested that doesn't exist, at all. Maybe.

    Instead of checking the resource types in the data, we could just check the resource types defined by the route? However, \Drupal\jsonapi_resources\Unstable\ResourceResponseFactory::create is not aware of the resource types used. πŸ’‘ but \Drupal\jsonapi_resources\Unstable\DocumentExtractor::extractResourceObject does this, which it also could!

        /** @var \Drupal\jsonapi\ResourceType\ResourceType[] $route_resource_types */
        $route_resource_types = $request->attributes->get('resource_types');
    
  • πŸ‡ΊπŸ‡ΈUnited States mglaman WI, USA

    Okay, I came back to this later than I wanted to, but I have an MR opened with a failing test.

  • Status changed to Needs review about 2 months ago
  • πŸ‡ΊπŸ‡ΈUnited States mglaman WI, USA

    Okay, I'm happy with the MR and approach.

  • Status changed to RTBC about 2 months ago
  • πŸ‡ΊπŸ‡ΈUnited States japerry KVUO
  • πŸ‡ΊπŸ‡ΈUnited States mglaman WI, USA

    Saving issue credits. japerry helped review

  • Pipeline finished with Skipped
    about 2 months ago
    #162722
    • mglaman β†’ committed e6ba9a4c on 8.x-1.x
      Issue #3172884 by mglaman, lisotton, zenphp, japerry: Include parameter...
  • Status changed to Fixed about 2 months ago
  • πŸ‡ΊπŸ‡ΈUnited States mglaman WI, USA
  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.69.0 2024