corey-mac/api-extension

Symfony API 扩展

安装: 4

依赖: 0

建议者: 0

安全: 0

星标: 0

关注者: 1

分支: 0

类型:symfony-bundle

1.0.3 2021-12-28 23:57 UTC

This package is auto-updated.

Last update: 2024-09-29 05:55:44 UTC


README

Packagist PHP Version Support GitHub issues Packagist License GitHub last commit

API 扩展

API 扩展允许您轻松创建自定义 API 端点

用法

API 实体

API 实体代表您想要公开的实体。您只需创建一个扩展 ApiEntity 的常规类。

<?php

namespace App\Api\Task;

use Cs\ApiExtensionBundle\Api\Entity\ApiEntity;
use Cs\ApiExtensionBundle\Api\Entity\Traits\IdAwareApiEntity;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Class TaskEntity
 * @package App\Api\Entity
 */
class TaskEntity extends ApiEntity
{
    use IdAwareApiEntity;

    /**
     * @Assert\NotBlank()
     * @var string
     */
    protected string $name;

    /**
     * @return string
     */
    public function getName(): string
    {
        return $this->name;
    }

    /**
     * @param string $name
     */
    public function setName(string $name): void
    {
        $this->name = $name;
    }
}

引用注解

如果您想使用引用,可以使用引用注解。现在 API 扩展将接受并提供 URI 而不是实际对象。

示例

use Cs\ApiExtensionBundle\Api\Entity\Annotations\ReferenceMany;
use Cs\ApiExtensionBundle\Api\Entity\Annotations\ReferenceOne;

class ... extends ApiEntity
{
    /**
     * @ReferenceOne(type=SomeEntity::class)
     * @var SomeEntity
     */
    protected SomeEntity $someEntity;

IdAwareApiEntity

IdAwareApiEntity 特性为您的实体提供一个 id 字段,该字段会自动用于您的请求中。

示例

use Cs\ApiExtensionBundle\Api\Entity\Traits\IdAwareApiEntity;

class ... extends ApiEntity
{
    use IdAwareApiEntity;

API 实体集合

实体集合包含多个 API 实体实例

namespace App\Api\Connection;

use Cs\ApiExtensionBundle\Api\Entity\ApiEntityCollection;

/**
 * Class ConnectionEntityCollection
 * @package App\Api\Entity
 */
class ConnectionEntityCollection extends ApiEntityCollection
{
    /**
     * @inheritDoc
     */
    public function getEntityClassName(): string
    {
        return ConnectionEntity::class;
    }
}

API 控制器

API 控制器是一个带有一些额外功能的常规 Symfony 控制器。

ApiControllerInterface 接口

为了让 API 扩展知道您的控制器(这是用于注册路由),您需要实现标记接口 ApiControllerInterface。

操作注解

操作注解告诉 API 您的动作是哪种操作。此信息将被用于生成路由。

  • @Annotations\Operation(type="collection-create")
  • @Annotations\Operation(type="collection-get")
  • @Annotations\Operation(type="item-get")
  • @Annotations\Operation(type="item-delete")
  • @Annotations\Operation(type="item-patch")

示例

<?php


namespace App\Api\Task;

use App\Api\Connection\ConnectionConverter;
use Cs\ApiExtensionBundle\Api\Controller\ApiControllerInterface;
use Cs\ApiExtensionBundle\Api\Controller\Annotations;
use Cs\ApiExtensionBundle\Api\Request\ApiEntityDeleteRequest;
use Cs\ApiExtensionBundle\Api\Request\ApiEntityGetRequest;
use Cs\ApiExtensionBundle\Api\Response\ApiCollectionPostResponse;
use Cs\ApiExtensionBundle\Api\Response\ApiCollectionResponse;
use Cs\ApiExtensionBundle\Api\Response\ApiEntityDeleteResponse;
use Cs\ApiExtensionBundle\Api\Response\ApiEntityGetResponse;
use Cs\ApiExtensionBundle\Api\Response\ApiEntityUpdateResponse;
use Cs\ApiExtensionBundle\Exception\ApiEntityNotFoundException;
use Cs\ApiExtensionBundle\Traits\ExceptionAwareApiController;

/**
 * Class TaskController
 * @package App\Api\Task
 * @Annotations\ApiController(entity=TaskEntity::class)
 */
class TaskController implements ApiControllerInterface
{
    use ExceptionAwareApiController;

    /**
     * @Annotations\Operation(type="collection-create")
     */
    public function create(TaskEntity $taskEntity): ApiCollectionPostResponse
    {
        return new ApiCollectionPostResponse($taskEntity);
    }

    /**
     * @Annotations\Operation(type="collection-get")
     * @return ApiCollectionResponse
     */
    public function getAll(): ApiCollectionResponse
    {
        $taskEntities = []; // some service that loads all tasks
        $totalEntityCount = 0; // total count of all entities
        return new ApiCollectionResponse(new TaskEntityCollection($taskEntities, $totalEntityCount));
    }

    /**
     * @Annotations\Operation(type="item-get")
     * @param ApiEntityGetRequest $request
     * @return ApiEntityGetResponse
     */
    public function get(ApiEntityGetRequest $request): ApiEntityGetResponse
    {
        $taskEntity = $this->someService->get($request->getId());
        $this->throwApiResponseEntityNotFoundExceptionIfNull($request->getId(), $task);
        return new ApiEntityGetResponse($this->convertTaskToApiEntity($task));
    }

    /**
     * @Annotations\Operation(type="item-delete")
     * @param ApiEntityDeleteRequest $request
     * @return ApiEntityDeleteResponse
     */
    public function delete(ApiEntityDeleteRequest $request): ApiEntityDeleteResponse
    {
        $success = $this->someService->delete($request->getId());
        
        if(!$success)
        {
            $this->throwApiResponseEntityNotFoundException($request->getId());
        }

        return new ApiEntityDeleteResponse();
    }

    /**
     * @Annotations\Operation(type="item-patch")
     * @param TaskEntity $taskEntity
     * @return ApiEntityUpdateResponse
     */
    public function update(TaskEntity $taskEntity): ApiEntityUpdateResponse
    {
        ...
        return new ApiEntityUpdateResponse();
    }
}