Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 自定义收集操作和IRI转换问题_Php_Symfony_Symfony4_Api Platform.com - Fatal编程技术网

Php 自定义收集操作和IRI转换问题

Php 自定义收集操作和IRI转换问题,php,symfony,symfony4,api-platform.com,Php,Symfony,Symfony4,Api Platform.com,当我需要在路由中手动要求参数时,Api平台和自定义收集操作有问题 我的第一个需要是走这条路线:query/userjob/[USER UUID]并检索给定用户的所有作业的集合 我的第二个需要是能够进入查询/userjob/[USER UUID]/[JOB UUID]并检索给定用户作业的详细信息 说我没有Api资源也没有实体用户可能很重要,所以我排除了所有类型的子资源映射或查询 假设我有一个UserJob ApiResource映射如下: App\Domain\User\Projection\Us

当我需要在路由中手动要求参数时,Api平台和自定义收集操作有问题

  • 我的第一个需要是走这条路线:
    query/userjob/[USER UUID]
    并检索给定用户的所有作业的集合
  • 我的第二个需要是能够进入
    查询/userjob/[USER UUID]/[JOB UUID]
    并检索给定用户作业的详细信息
  • 说我没有Api资源也没有实体用户可能很重要,所以我排除了所有类型的子资源映射或查询

    假设我有一个UserJob ApiResource映射如下:

    App\Domain\User\Projection\UserJob:               
            itemOperations:
                get: 
                    method: 'GET'
                    path: '/userjob/{userId}/{jobId}'
                    requirements:
                        userId: '%uuid_regex%'
                        jobId: '%uuid_regex%'
            collectionOperations:            
                get:
                    method: 'GET'
                    path: '/userjob/{userId}'
                    requirements:
                        userId: '%uuid_regex%'
            attributes:
                route_prefix: "/query"
    
    在课堂上,我有:

    
    最终类用户作业
    {
    public$id;//国际汽车公司
    public$userId;//一个UUID
    public$jobId;//一个UUID
    公共函数构造($userId,$jobId)
    {
    $this->userId=$userId;
    $this->jobId=$jobId;
    }
    公共函数getId():int
    {
    返回$this->id;
    }
    公共函数getUserId()
    {
    返回$this->userId;
    }
    公共函数getJobId()
    {
    返回$this->jobId
    }   
    
    我为这个类构建了一个自定义数据提供程序,其中我编写了从给定参数(userId)获取资源的方法:

    公共函数getCollection(字符串$resourceClass,字符串$operationName=null) { $userId=$this->request->getCurrentRequest()->attributes->get('userId'); 返回$this->repository->entityManager->getRepository($resourceClass)->findByUserId($userId); } 当我调用GET时,比如说,
    query/userjob/148e3200-f793-447b-bde8-af6b7b27372c
    它会抛出一个异常:

    无法为App\Domain\User\Projection\UserJob生成IRI

    如果我在IRIConverter类中进行更深入的调试,我会发现原始异常是从路由器抛出的:

    缺少用于生成路由“api\U用户\U作业\U获取\U集合”URL的一些必需参数(“userId”)

    然而,如果我转储
    $this->repository->entityManager->getRepository($resourceClass)->findByUserId($userId);
    的结果,我要查找的所有元素都可以从数据库中很好地获取

    因此,我的直觉是,不知何故,APIPlate进程未能构建我们通常可以在有效负载开始时找到的集合IRI,在我的例子中,该集合IRI是
    query/userjob/148e3200-f793-447b-bde8-af6b7b27372c

    它在规范化或序列化过程中失败,因为我的自定义操作(用户UUID)的“额外”参数没有传递给集合规范化器、iri转换器类,因此它无法将缺少的参数提供给路由器以构建“api\U用户\U作业\U获取\U集合”路由

    我在这里遗漏了什么?这是一个众所周知的问题,有我遗漏的现成解决方案吗

    或者我必须寻找:

    • 装饰IRI转换器
    • 使用自定义规范化器
    • 用复合ID做些什么
    • 还有别的吗

    您的用例可能有更多的解决方案,这取决于首选方案:

  • 装饰iri转换器,因为您在集合中使用标识符,据我所知,API平台不支持这种开箱即用的方式。如果像这样的url是您的API样式,这是最佳选择
  • 使用具有自定义url样式(文档:)的自定义控制器操作,如果这是api中罕见的url,则最好使用该操作
  • 在api资源类(文档:)中将ID注释为标识符 但我还没有尝试使用多个ID,这可能只适用于项目url
  • 您可以尝试使用自定义数据提供程序(docs:)。这需要按资源或全局(
    supports()
    method)执行,并且您需要以某种方式(regex?)从
    getCollection()和
    getItem()中的
    $context
    数组中提取ID
    methods。但由于ApiPlatform将尝试生成项iri,您最终可能会装饰iri转换器


    注释:在集合URL中使用ID可能导致其他问题,如OpenAPI文档生成。您可能会考虑,如果您想要的不是通过“ID”字段过滤集合,而是很好地支持或检索仅包含“您的”的集合。项目。如果有人使用条令,可以通过数据提供商注入安全性或条令查询扩展来完成。

    您找到解决问题的好方法了吗?
    /**
     * @var Uuid
     * @ApiProperty(identifier=true)
     */
    public $code;