Include parameter doesn't work with different type of entities

Created on 24 September 2020, about 4 years ago
Updated 16 August 2024, 3 months 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

Needs work

Version

1.1

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 7 months ago
  • 🇺🇸United States mglaman WI, USA

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

  • Status changed to RTBC 7 months ago
  • 🇺🇸United States japerry KVUO
  • 🇺🇸United States mglaman WI, USA

    Saving issue credits. japerry helped review

  • Pipeline finished with Skipped
    7 months ago
    #162722
    • mglaman committed e6ba9a4c on 8.x-1.x
      Issue #3172884 by mglaman, lisotton, zenphp, japerry: Include parameter...
  • Status changed to Fixed 7 months ago
  • 🇺🇸United States mglaman WI, USA
  • Automatically closed - issue fixed for 2 weeks with no activity.

  • 🇮🇳India Anul Delhi

    I am still facing this issue using the stable latest release for this module. In my JSON API search it still throws the error and this time it actually shows multiple fields and same field it shows in Possible values also.

    When I am using the older version of this module with the patch: https://www.drupal.org/files/issues/2020-09-24/fix-include-3172884-2.patch

    It is working fine for me.

    I think we should reopen this bug and see what we can fix.

  • 🇮🇪Ireland jouwdan

    +1, this issue seems to have cropped back up again.

  • 🇮🇪Ireland jouwdan

    As above, the contents of this file: https://git.drupalcode.org/project/jsonapi_resources/-/blob/e6ba9a4c6e23...

    seems to fix it. Has this been overwritten?

  • Status changed to Needs work 3 months ago
  • 🇺🇸United States mglaman WI, USA

    I didn't see the newest comments. Reopening to review

Production build 0.71.5 2024