Description
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!