无实体经营 [英] Operation without entity

查看:115
本文介绍了无实体经营的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一段时间以来,我一直在寻找解决方案,但我找不到真正允许我做我想做的事情.我只想创建不一定需要使用实体或ID的路由.您能帮我说明一下文档尚不清楚吗?

I've been looking for a solution for a while but none of the one I find really allows me to do what I want. I would just like to create routes that don't necessarily require an entity or id to be used. Can you help me the documentation is not clear to do this.

谢谢你.

推荐答案

您可以在

As you can read in the General Design Considerations, just make an ordinary PHP class (POPO). Give it an ApiResource annontation like this:

 * @ApiResource(
 *     collectionOperations={
 *         "post"
 *     },
 *     itemOperations={}
 * )

确保您的课程所在的文件夹位于api/config/packages/api_platform.yaml的路径列表中.通常有以下配置:

Make sure the folder your class is in is in the paths list in api/config/packages/api_platform.yaml. There usually is the following configuration:

api_platform:
    mapping:
        paths: ['%kernel.project_dir%/src/Entity']

如果您的课程不在Entity文件夹中,则应添加路径.

You should add your path if your class is not in the Entity folder.

Api Platform希望发布json并尝试将其反序列化为类的实例.进行自定义 DataPersister 来处理实例,例如,如果您的类是App \ ApiCommand \ Doit:

Api Platform will expect json to be posted and try to unserialize it into an instance of your class. Make a custom DataPersister to process the instance, for example if your class is App\ApiCommand\Doit:

namespace App\DataPersister;

use ApiPlatform\Core\DataPersister\ContextAwareDataPersisterInterface;
use App\ApiCommand\Doit;
use App\ApiResult\DoitResult;

final class DoitDataPersister implements ContextAwareDataPersisterInterface
{
    public function supports($data, array $context = []): bool
    {
        return $data instanceof Doit;
    }

    public function persist($data, array $context = [])
    {
        // code to process $data

        $result = new DoitResult();
        $result->description = 'Hello world';
        return $result;
    }

    public function remove($data, array $context = [])
    {
      // will not be called if you have no delete operation
    }
}

如果您需要教义,请添加:

If you need Doctrine, add:

    public function __construct(ManagerRegistry $managerRegistry)
    {
        $this->managerRegistry = $managerRegistry;
    }

请参见注入扩展有关如何使用它.

See Injecting Extensions for how to use it.

请注意,:: persist返回的结果不是Doit的实例.如果您返回Doit api平台,则将根据操作结果尝试对其进行序列化.但是我们已经将Doit标记为ApiResource,因此(?)api平台会寻找可以检索它的项目操作,从而导致错误与App \ ApiCommand \ Doit类型关联的没有项目路线".为避免这种情况,您可以返回Symfonies序列化程序可以序列化的不是ApiResource的任何对象.在该示例中,DoitResult的实例.另外,您可以返回Symfony \ Component \ HttpFoundation \ Response的实例,但是您必须自己处理序列化.

Notice that the result returned by ::persist is not an instance of Doit. If you return a Doit api platform will try to serialize that as the result of your operation. But we have marked Doit as an ApiResource so (?) api platform looks for an item operation that can retrieve it, resulting in an error "No item route associated with the type App\ApiCommand\Doit". To avoid this you can return any object that Symfonies serializer can serialize that is not an ApiResource. In the example an instance of DoitResult. Alternatively you can return an instance of Symfony\Component\HttpFoundation\Response but then you have to take care of the serialization yourself.

发布操作应该已经可以使用,但是大胆的文档是由元数据制成的.要告诉api平台它应该期望返回DoitResult,请更改@ApiResource批注:

The post operation should already work, but the swagger docs are made from metadata. To tell api platform that it should expect a DoitResult to be returned, change the @ApiResource annotation:

 *     collectionOperations={
 *         "post"={
 *             "output"=DoitResult::class
 *         }
 *     },

这将为大张旗鼓的文档添加DoitResult的新类型,但是描述仍然是错误的.您可以使用 SwaggerDecorator 对其进行更正.这是201个帖子回复的答案:

This will the add a new type for DoitResult to the swagger docs, but the descriptions are still wrong. You can correct them using a SwaggerDecorator. Here is one for a 201 post response:

namespace App\Swagger;

use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

final class SwaggerDecorator implements NormalizerInterface
{
    private $decorated;

    public function __construct(NormalizerInterface $decorated)
    {
        $this->decorated = $decorated;
    }

    public function normalize($object, string $format = null, array $context = [])
    {
        $summary = 'short explanation about DoitResult';
        $docs = $this->decorated->normalize($object, $format, $context);
        $docs['paths']['/doit']['post']['responses']['201']['description'] = 'Additional explanation about DoitResult';

        $responseContent = $docs['paths']['/doit']['post']['responses']['201']['content'];
        $this->setByRef($docs, $responseContent['application/ld+json']['schema']['properties']['hydra:member']['items']['$ref'],
            'description', $summary);
        $this->setByRef($docs, $responseContent['application/json']['schema']['items']['$ref'],
            'description', $summary);

        return $docs;
    }

    public function supportsNormalization($data, string $format = null)
    {
        return $this->decorated->supportsNormalization($data, $format);
    }

    private function setByRef(&$docs, $ref, $key, $value)
    {
        $pieces = explode('/', substr($ref, 2));
        $sub =& $docs;
        foreach ($pieces as $piece) {
            $sub =& $sub[$piece];
        }
        $sub[$key] = $value;
    }
}

要配置服务,请在api/config/services.yaml中添加以下内容:

To configure the service add the following to api/config/services.yaml:

'App\Swagger\SwaggerDecorator':
    decorates: 'api_platform.swagger.normalizer.api_gateway'
    arguments: [ '@App\Swagger\SwaggerDecorator.inner' ]
    autoconfigure: false

如果您的发布操作实际上并未创建某些内容,则您可能不喜欢201响应.您可以通过在@ApiResource批注中指定响应代码来更改它,例如:

If your post operation is not actually creating something you may not like the 201 response. You can change that by specifying the response code in the @ApiResource annotation, for example:

 *     collectionOperations={
 *         "post"={
 *             "output"=DoitResult::class,
 *             "status"=200
 *         }
 *     },

您可能需要相应地调整SwaggerDecorator.

You may want to adapt the SwaggerDecorator accordingly.

创建获取"广告收集操作类似,但是您需要制作一个 DataProvider 而不是DataPersister.我的教程的Chapter9-api分支包含一个SwaggerDecorator的示例,用于收集响应.

Creating a "get" collection operation is similar, but you need to make a DataProvider instead of a DataPersister. The chapter9-api branch of my tutorial contains an example of a SwaggerDecorator for a collection response.

这篇关于无实体经营的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆