API Platform bundle下的自定义Symfony操作

4

我尝试使用Symfony Bundle API-Platform来构建API。

Api resource提供了自动的CRUD操作,支持HTTP动词POST、GET、PUT、DELETE。

我想要添加一个端点来处理自定义的POST操作,使用自定义的payload/body,不依赖于任何资源。

我遇到的问题是将此端点添加到自动API-Platform文档中。

在GitHub上寻找这种问题时,我发现API-Platform v2应该能够解决它。

请参见Issue #385 : Custom action + ApiDoc

看起来有些人找到了使用NelmioApiDoc @ApiDoc注释的方法。

请参见Issue #17 : Documentation for custom operation

4个回答

5

在https://api-platform.com/docs/core/operations中描述的自定义操作不允许自定义主体/负载。该操作仍然会获得一个`$data`参数,该参数是用于POST或PUT方法创建或更新的实体/资源。感谢Swagger链接,我会尽快查看。 - Noémi Salaün
1
覆盖Swagger仅允许手动为每个自定义操作添加自定义参数。它不像Nelmio那样提供参数或返回类型的自动文档。我不知道这是否是API-Platform的目标。但随着API-Platform的发展,并通过Symfony Flex与composer req api作为最佳API解决方案推出,我发现很难管理简单的自定义操作。 - Noémi Salaün
1
目前使用NelmioApiDoc的v3版本(目前处于beta测试阶段)似乎是一个不错的解决方案:https://github.com/nelmio/NelmioApiDocBundle/tree/v3.0.0-BETA4它很干净,可以保留API平台文档的内置UI,并使用所有NelmioApiDoc功能进行自定义操作。 - Kévin Dunglas
@KévinDunglas 你有这个问题的任何更新或新建议吗?谢谢。 - lavb

3
您可以使用@ApiResource()注释记录自己的路线:
/**
 * @ORM\Entity
 * @ApiResource(
 *     itemOperations={
 *         "get"={"method"="GET"},
 *         "put"={"method"="PUT"},
 *         "delete"={"method"="DELETE"},
 *         "send_reset_password_token"={
 *             "route_name"="user_send_reset_password_token",
 *              "swagger_context" = {
 *                 "parameters" = {
 *                     {
 *                         "name" = "email",
 *                         "in" = "path",
 *                         "required" = "true",
 *                         "type" = "string"
 *                     }
 *                 },
 *                 "responses" = {
 *                     "201" = {
 *                         "description" = "email with reset token has been sent",
 *                         "schema" =  {
 *                             "type" = "object",
 *                             "required" = {
 *                                 "email"
 *                             },
 *                             "properties" = {
 *                                  "email" = {
 *                                     "type" = "string"
 *                                  },
 *                                  "fullname" = {
 *                                     "type" = "string"
 *                                  }
 *                             }
 *                         }
 *                     },
 *                     "400" = {
 *                         "description" = "Invalid input"
 *                     },
 *                     "404" = {
 *                         "description" = "resource not found"
 *                     }
 *                 },
 *                 "summary" = "Send email with token to reset password",
 *                 "consumes" = {
 *                     "application/json",
 *                     "text/html",
 *                  },
 *                 "produces" = {
 *                     "application/json"
 *                  }
 *             }
 *         }
 *     },
 *     attributes={
 *         "normalization_context"={"groups"={"user", "user-read"}},
 *         "denormalization_context"={"groups"={"user", "user-write"}}
 *     }
 * )
 */

来源:https://github.com/api-platform/docs/issues/143#issuecomment-260221717

1
您可以像这样创建自定义帖子操作。 将资源配置映射到yaml。
# config/packages/api_platform.yaml
api_platform:
enable_swagger_ui: false
mapping:
    paths: ['%kernel.project_dir%/config/api_platform']

创建 resources.yaml 文件。
# config/api_platform/resources.yaml
resources:
App\Entity\User:
  itemOperations: []
  collectionOperations:
    post:
        method: 'POST'
        path: '/auth'
        controller: App\Controller\AuthController
        swagger_context:
            summary: your desc
            description: your desc

然后在 App\Entity\User 中添加公共属性。保留HTML,不做解释。
class User {
   public $login
   public $password
}

现在在Swagger UI中,您将看到具有登录和密码参数的POST /api/auth方法。在控制器中覆盖_invoke以执行您的逻辑。
class AuthController {
   public function __invoke()
   {
      return ['your custom answer'];
   }
}

0

我遇到了相同的情况,因为我试图把POST方法放在itemOperations中,但它只能驻留在collectionOperations中。 在后者中,我可以成功定义自己的自定义路径。

/**
 * @ApiResource(
 *     collectionOperations={
 *       "get"={
 *           "path"="/name_your_route",
 *       },
 *       "post"={
 *           "path"="/name_your_route",
 *       },
 *     },
 *     itemOperations={
 *       "get"={
 *           "path"="/name_your_route/group/{groupId}/user/{userId}",
 *           "requirements"={"groupId"="\d+", "userId"="\d+"},
 *       },
 *       "delete"={
 *           "path"="/name_your_route/group/{groupId}/user/{userId}",
 *       },
 *       "put"={
 *           "path"="/name_your_route/group/{groupId}/user/{userId}",
 *       }
 * })

希望对其他遇到类似问题的人有所帮助。

以下是来自相关文档的段落:

集合操作针对资源集合进行。默认情况下,实现了两个路由:POST和GET。项操作针对单个资源进行。定义了3个默认路由:GET、PUT和DELETE。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接