Skip to content

Search Filter does not filter collection by nested relation field in GraphQL #1714

Closed
@k911

Description

@k911

Hi!
I've been recently testing GraphQL endpoint provided by this amazing framework.
So I've encountered on follwing SearchFilter issue.

I've following entities (simplified):
// src/Entity/Article.php

/**
 * @ApiResource(
 *     attributes={
 *         "filters": {"app.article.search_filter", "app.article.group_filter"},
 *         "normalization_context": {"groups": {"ArticleRead"}},
 *     },
 *     graphql={
 *         "query": {
 *             "filters": {"app.article.search_filter"},
 *             "normalization_context": {"groups": {"ArticleRead", "CategoryRead"}},
 *         },
 *     },
 * })
 * @Entity
 */
class Article
{
    /**
     * @ORM\Id
     * @ORM\Column(type="uuid")
     * @ORM\GeneratedValue(strategy="CUSTOM")
     * @ORM\CustomIdGenerator(class="Ramsey\Uuid\Doctrine\UuidGenerator")
     *
     * @Groups({"ArticleRead"})
     */
    protected $id;

    ...

    /**
     * @ORM\ManyToOne(targetEntity="Category")
     * @ORM\JoinColumn(name="category_id", referencedColumnName="id", onDelete="CASCADE", nullable=false)
     *
     * @Assert\NotBlank
     *
     * @Groups({"ArticleRead"})
     */
    protected $category;
}
// src/Entity/Category.php

/**
 * @ApiResource
 * @Entity
 */
class Category
{
    /**
     * @ORM\Id
     * @ORM\Column(type="uuid")
     * @ORM\GeneratedValue(strategy="CUSTOM")
     * @ORM\CustomIdGenerator(class="Ramsey\Uuid\Doctrine\UuidGenerator")
     *
     * @Groups({"CategoryRead"})
     */
    protected $id;

    /**
     * @ORM\Column(type="string", unique=true)
     *
     * @Gedmo\Slug(fields={"name"}, separator="-", updatable=true, unique=true)
     *
     * @Groups({"CategoryRead"})
     */
    protected $code;

    /**
     * @ORM\Column(type="string", nullable=false)
     *
     * @Assert\NotBlank
     * @Assert\Length(min="3", max="100")
     *
     * @Groups({"CategoryRead"})
     */
    protected $name;
}
and I've declared following filters (old way):
app.article.search_filter:
        parent: 'api_platform.doctrine.orm.search_filter'
        arguments: [ { category.code: 'exact' } ]
        tags: [ 'api_platform.filter' ]

app.article.group_filter:
        parent: 'api_platform.serializer.group_filter'
        arguments: [ 'group', false, ['CategoryRead'] ]
        tags: [ 'api_platform.filter' ]

Filter works fine using normal REST:
GET /articles?category.code=news&group[]=CategoryRead

but using GraphQL:
GET /graphql?query={articles(category_code:"news"){edges{node{category{code}}}}}

It returns an unfiltered collection:
{
  "data": {
    "articles": {
      "edges": [
        {
          "node": {
            "category": {
              "code": "news"
            }
          }
        },
        {
          "node": {
            "category": {
              "code": "article"
            }
          }
        },
        {
          "node": {
            "category": {
              "code": "announcement"
            }
          }
        }
      ]
   }
}
I've tried also new way via annotation:
// src/Entity/Article.php

/**
 * @ApiFilter(SearchFilter::class, properties={"category.code": "exact"})
 */
class Article {
  ...
}

but the behaviour is exactly the same, in REST context works in GraphQL it does not.
I've checked and filtering works for not nested fields.

Stack:

  • api-platform/core v2.2.1, v2.2.2
  • symfony v4.0.4
  • php 7.1/7.2

Here I provide my test api endpoints, with symfony profiler enabled, so you can see the details, hope it helps:

REST
https://knit-test-api.tk/articles?category.code=news&group%5B%5D=CategoryRead
GraphQL:
https://knit-test-api.tk/graphql?query={articles(category_code:%22news%22){edges{node{category{code}}}}}
Travis CI build with feature tests:
https://travis-ci.org/knit-pk/api-v1-php/jobs/343330287#L708
Git branch (full codebase):
https://github.com/knit-pk/api-v1-php/tree/feature/graphql-filters-test

Thanks for your time.
PS: I appreciate your work very much, and really enjoy developing an API with API Platform!

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions