首先,我想告诉您,我已经阅读了有关今天遇到的问题的文档,并且我也在StackOverflow和Google上进行了搜索,但是没有找到合适的解决方案。
为了实践起见,我正在使用Symfony 4和API平台构建客户关系管理API。我已经学到了很多有关API平台的知识,即使我可以使用批注进行资源配置,但我还是强迫自己使用YAML来了解更多信息。
因此,我有一个Customer资源,该资源具有几个属性: id , firstname , lastname , emailAddress ,公司, createdAt , updatedAt 和所有者。我的目标是在此资源上(在YAML中)添加 SearchFilter ,并将大多数属性添加为此过滤器的属性。
我已经尝试过此处给出的解决方案:https://github.com/api-platform/core/issues/1755。问题是我无法使其正常工作。在services.yaml中,我看到可以添加参数,但是我不知道可以在注释中找到什么等效项...
在config/services.yaml
中:
# filters
app.my_filter:
parent: 'api_platform.doctrine.orm.search_filter'
tags: ['api_platform.filter']
autowire: false
autoconfigure: false
public: false
在resources/customer.yaml
中:
App\Entity\Customer:
collectionOperations:
get:
normalization_context:
groups: ['Customer:Get']
filters: ['app.my_filter']
我打算做的事情与此类似,src/Entity/Customer.php
中带有注释:
/**
* @ApiResource
*
* [...]
*
* @ApiFilter(SearchFilter::class, properties={
* "firstname": "partial",
* "lastname": "partial",
* "emailAddress": "partial",
* "company": "partial"
* })
*/
class Customer
{
...
}
我希望您能够提供帮助,并且我的问题已得到明确解释。如果没有,请告诉我,我会尽力为您提供更多详细信息。
谢谢!
答案 0 :(得分:1)
我找到了解决问题的方法。看来API平台文档离答案还不太远!在资源配置文件中尝试了一段时间之后,我最终决定给services.yaml
文件一个机会。 on this github issue对我有很大帮助。所以,这就是我所做的。
步骤1-在# filters
app.customer_resource.search_filter:
parent: 'api_platform.doctrine.orm.search_filter'
arguments: [ { 'firstname': 'partial', 'lastname': 'partial', 'emailAddress': 'partial', 'owner.emailAddress': 'exact' } ]
tags: [ { name: 'api_platform.filter', id: 'customer.search_filter' } ]
autowire: false # required, explained below
autoconfigure: false # required, explained below
中:
autowire
注释0:这里需要autoconfigure
和vendor/api-platform/core/src/Swagger/Serializer/DocumentationNormalizer::getFilter()
参数,否则会出现错误:
注释1:我注意到这里最重要的元素是“ tags” 参数的“ id” 元素。在寻找解决方案时,我发现了config/resources/customer.yaml
,这表明您必须提供一个过滤器ID才能起作用。在第二步中自己看看。
步骤2-在您的资源配置文件中(我的文件位于App\Entity\Customer:
collectionOperations:
get:
filters: ['customer.search_filter']
# ...
中)
PRODUCTS ||= [
[name: 'tennis_balls', description: 'you need em'],
[name: 'racquets', description: 'have at least one'],
[name: 'sneakers', description: 'run fast with these']
].freeze
class Product
def self.by_name(name)
PRODUCTS.flatten.find{|a| a[:name] == name.to_s}
end
def self.by_names(names)
names.map{|name| by_name(name)}.compact
end
end
我刚刚通过使用(如我所说的)重要过滤器ID添加了GET收集操作的过滤器。因此,这解决了我的问题。 但是,如果有人在那里有更好/更简单的解决方案,我很高兴知道。
Screenshot: What the API looks like when SearchFilter is in place