在 API 平台中禁用自定义操作的 requestBody
Disable requestBody for custom action in API Platform
我想为没有参数的自定义 POST 路由操作禁用 openapi 的 requestBody 文档。
为此,我尝试像这样扩展 openapi_context:
/*
* @ApiResource(
* ...
* itemOperations={
* ...
* "post_clone" = {
* ...
* "openapi_context"={
* "requestBody"=null
* }
* }
* }
* )
*/
将 requestBody 设置为 null
或 false
与跳过该值相同,并导致 POST 路由的默认文档。
将requestBody设置为{}
在文档中写入空对象,但我需要的是在文档中跳过密钥
您执行 clone
操作的方式有误。 POST
操作是collection operations,不是物品操作。即使今天您能够将 POST
操作声明为项目操作,它更可能是 API-平台的副作用,而不是预期的行为。
为了尊重API-平台生命周期,我建议您做以下事情:
首先,将您的clone
操作声明为POST集合操作,使用as input DTO命名为MyEntityCloneDto
:
use App\Dto\MyEntityCloneDto;
/**
* @ApiResource(
* collectionOperations={
* "get",
* "post",
* "clone" = {
* "method" = "post",
* "path" = "/my_entities/clone",
* "input" = MyEntityCloneDto::class,
* }
* }
* )
* @ORM\Entity(repositoryClass=MyEntityRepository::class)
*/
class MyEntity
然后 创建输入 DTO:
namespace App\Dto;
use App\Entity\MyEntity;
use Symfony\Component\Validator\Constraints as Assert;
class MyEntityCloneDto
{
/**
* The entity to clone.
*
* @Assert\NotNull()
*/
public ?MyEntity $myEntity = null;
}
最后 创建 DataTransformer
:
namespace App\DataTransformer;
use ApiPlatform\Core\DataTransformer\DataTransformerInterface;
use App\Entity\MyEntity;
use ApiPlatform\Core\Validator\ValidatorInterface;
class MyEntityCloner implements DataTransformerInterface
{
private ValidatorInterface $validator;
public function __construct(ValidatorInterface $validator)
{
$this->validator = $validator;
}
public function transform($object, string $to, array $context = [])
{
$this->validator->validate($object);
return clone $object->myEntity; //add more logic if needed of course
}
public function supportsTransformation($data, string $to, array $context = []): bool
{
return MyEntity::class === $to;
}
}
使用 ID 5 克隆 MyEntity
:
curl --request POST \
--header 'content-type: application/json' \
--header 'accept: application/ld+json' \
--data '{"myEntity": "/my_entities/5"}' \
http://example.com/api/my_entities/clone
这样,OpenAPI
视图显示真相,您的操作保持稳定。
请注意,如果您需要对所有实体执行 clone
操作,则可以重新使用数据转换器,因为它的方法没有类型化。但是为了使 Serializer
工作,每个实体需要一个 DTO,因为它需要知道要克隆的实体的类型。
我想为没有参数的自定义 POST 路由操作禁用 openapi 的 requestBody 文档。 为此,我尝试像这样扩展 openapi_context:
/*
* @ApiResource(
* ...
* itemOperations={
* ...
* "post_clone" = {
* ...
* "openapi_context"={
* "requestBody"=null
* }
* }
* }
* )
*/
将 requestBody 设置为 null
或 false
与跳过该值相同,并导致 POST 路由的默认文档。
将requestBody设置为{}
在文档中写入空对象,但我需要的是在文档中跳过密钥
您执行 clone
操作的方式有误。 POST
操作是collection operations,不是物品操作。即使今天您能够将 POST
操作声明为项目操作,它更可能是 API-平台的副作用,而不是预期的行为。
为了尊重API-平台生命周期,我建议您做以下事情:
首先,将您的clone
操作声明为POST集合操作,使用as input DTO命名为MyEntityCloneDto
:
use App\Dto\MyEntityCloneDto;
/**
* @ApiResource(
* collectionOperations={
* "get",
* "post",
* "clone" = {
* "method" = "post",
* "path" = "/my_entities/clone",
* "input" = MyEntityCloneDto::class,
* }
* }
* )
* @ORM\Entity(repositoryClass=MyEntityRepository::class)
*/
class MyEntity
然后 创建输入 DTO:
namespace App\Dto;
use App\Entity\MyEntity;
use Symfony\Component\Validator\Constraints as Assert;
class MyEntityCloneDto
{
/**
* The entity to clone.
*
* @Assert\NotNull()
*/
public ?MyEntity $myEntity = null;
}
最后 创建 DataTransformer
:
namespace App\DataTransformer;
use ApiPlatform\Core\DataTransformer\DataTransformerInterface;
use App\Entity\MyEntity;
use ApiPlatform\Core\Validator\ValidatorInterface;
class MyEntityCloner implements DataTransformerInterface
{
private ValidatorInterface $validator;
public function __construct(ValidatorInterface $validator)
{
$this->validator = $validator;
}
public function transform($object, string $to, array $context = [])
{
$this->validator->validate($object);
return clone $object->myEntity; //add more logic if needed of course
}
public function supportsTransformation($data, string $to, array $context = []): bool
{
return MyEntity::class === $to;
}
}
使用 ID 5 克隆 MyEntity
:
curl --request POST \
--header 'content-type: application/json' \
--header 'accept: application/ld+json' \
--data '{"myEntity": "/my_entities/5"}' \
http://example.com/api/my_entities/clone
这样,OpenAPI
视图显示真相,您的操作保持稳定。
请注意,如果您需要对所有实体执行 clone
操作,则可以重新使用数据转换器,因为它的方法没有类型化。但是为了使 Serializer
工作,每个实体需要一个 DTO,因为它需要知道要克隆的实体的类型。