WakeApp/api-platform-bundle

此包已被废弃,不再维护。未建议替代包。

扩展Symfony HttpFoundation,提供封装区域用于与REST API交互

安装量: 22,704

依赖者: 0

建议者: 0

安全性: 0

星标: 8

关注者: 7

分支: 0

公开问题: 0

类型:symfony-bundle

v2.1.0-RC1 2021-07-08 19:10 UTC

README

Latest Stable Version Total Downloads

介绍

此组件扩展了Symfony的http-foundation组件,允许将API的工作封装在独立的区域中。

通过ParameterBag提供对JSON格式请求内容的处理。组件架构禁止API区域发生致命错误,并始终返回带有相应错误代码的有效响应。完整的错误代码列表可以在ApiException类中找到。

描述API规范必须使用Swagger 2,并采用以下格式之一

安装

步骤1:下载组件

打开控制台,转到项目目录,然后执行以下命令下载最适合的稳定版本

    composer require wakeapp/api-platform-bundle

此命令假设Composer已安装并全局可用。

步骤2:连接组件

之后,将组件添加到项目中已注册的组件列表中,修改项目的app/AppKernel.php文件。

<?php declare(strict_types=1);
// app/AppKernel.php

class AppKernel extends Kernel
{
    // ...

    public function registerBundles()
    {
        $bundles = [
            // ...

            new Linkin\Bundle\SwaggerResolverBundle\LinkinSwaggerResolverBundle(),
            new Wakeapp\Bundle\ApiPlatformBundle\WakeappApiPlatformBundle(),
        ];

        return $bundles;
    }

    // ...
}

配置

要开始使用组件,需要创建和定义一个guesser对象,该对象包含确定项目API区域规则。

<?php

declare(strict_types=1);

namespace App\Guesser\ApiAreaGuesser;

use Symfony\Component\HttpFoundation\Request;
use Wakeapp\Bundle\ApiPlatformBundle\Guesser\ApiAreaGuesserInterface;

class ApiAreaGuesser implements ApiAreaGuesserInterface
{
    /**
     * {@inheritDoc}
     */
    public function getApiVersion(Request $request): ?int
    {
        $apiVersionMatch = [];
        preg_match('/^\/v([\d]+)\//i', $request->getPathInfo(), $apiVersionMatch);

        if (empty($apiVersionMatch)) {
            return null;
        }

        $apiVersion = (int) end($apiVersionMatch);

        return $apiVersion;
    }

    /**
     * {@inheritdoc}
     */
    public function isApiRequest(Request $request): bool
    {
        return strpos($request->getPathInfo(), '/api') === 0;
    }
}

注意:如果您不使用autowire,则必须将ApiAreaGuesser注册为服务。

# app/config.yml
wakeapp_api_platform:
    api_area_guesser_service:   App\Guesser\ApiAreaGuesser

完整参数集

# app/config.yml
wakeapp_api_platform:
    # полное имя класса DTO для стандартизации ответа
    api_result_dto_class:       Wakeapp\Bundle\ApiPlatformBundle\Dto\ApiResultDto

    # идентификатор сервиса для определения зоны API
    api_area_guesser_service:   App\Guesser\ApiAreaGuesser

    # идентификатор сервиса для глобального отлавливания ошибок и выдачи специализированных сообщений вместо 500
    error_code_guesser_service: Wakeapp\Bundle\ApiPlatformBundle\Guesser\ApiErrorCodeGuesser

    # Минимально допустимая версия API.
    minimal_api_version:        1

    # флаг для отладки ошибок - если установлен в true - ответ ошибки содержит trace.
    response_debug:             false

使用

要使用组件功能,首先需要在指定的API区域中创建控制器和第一个方法。以下示例将返回一个简单的用户配置文件。

首先,我们需要创建一个DTO来返回数据

<?php declare(strict_types=1);

namespace App\Dto;

use Swagger\Annotations as SWG;
use Wakeapp\Component\DtoResolver\Dto\DtoResolverTrait;
use Wakeapp\Component\DtoResolver\Dto\DtoResolverInterface;

/**
 * @SWG\Definition(
 *      type="object",
 *      description="Profile info",
 *      required={"email", "firstName", "lastName"},
 * )
 */
class ProfileResultDto implements DtoResolverInterface
{
    use DtoResolverTrait;
    
    /**
     * @var string
     *
     * @SWG\Property(description="Profile email", example="test@gmail.com")
     */
    protected $email;

    /**
     * @var string
     *
     * @SWG\Property(description="User's first name", example="John")
     */
    protected $firstName;

    /**
     * @var string
     *
     * @SWG\Property(description="User's last name", example="Doe")
     */
    protected $lastName;

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

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

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

现在,添加一个控制器和相应的处理方法。注意:示例使用NelmioApiDocBundle进行实现。

<?php declare(strict_types=1);

namespace App\Controller;

use App\Dto\ProfileResultDto;
use Nelmio\ApiDocBundle\Annotation\Model;
use Swagger\Annotations as SWG;
use Symfony\Component\Routing\Annotation\Route;
use Wakeapp\Bundle\ApiPlatformBundle\Factory\ApiDtoFactory;
use Wakeapp\Bundle\ApiPlatformBundle\HttpFoundation\ApiResponse;

/**
 * @Route("/api/profile")
 */
class ProfileController
{
    /**
     * Returns user profile
     *
     * @Route(methods={"GET"})
     *
     * @SWG\Response(
     *      response=ApiResponse::HTTP_OK,
     *      description="Successful result in 'data' offset",
     *      @Model(type=ProfileResultDto::class)
     * )
     *
     * @param ApiDtoFactory $factory
     *
     * @return ApiResponse
     */
    public function getProfile(ApiDtoFactory $factory): ApiResponse
    {
        // обработка данных

        $resultDto = $factory->createApiDto(ProfileResultDto::class, [
            'email' => 'test-user@mail.ru',
            'firstName' => 'Test',
            'lastName' => 'User',
        ]);

        return new ApiResponse($resultDto);
    }
}

附加内容

如何将body参数与query和/或path参数结合

DTO对象

<?php declare(strict_types=1);

namespace App\Dto;

use Swagger\Annotations as SWG;
use Wakeapp\Bundle\ApiPlatformBundle\Dto\MagicAwareDtoResolverTrait;
use Wakeapp\Component\DtoResolver\Dto\DtoResolverInterface;

/**
 * @SWG\Definition(
 *      type="object",
 *      description="Update profile info",
 *      required={"firstName", "lastName"},
 * )
 * 
 * @method getEmail(): string
 */
class UpdateProfileEntryDto implements DtoResolverInterface
{
    use MagicAwareDtoResolverTrait;
    
    /**
     * @var string
     */
    protected $email;

    /**
     * @var string
     *
     * @SWG\Property(description="User's first name", example="John")
     */
    protected $firstName;

    /**
     * @var string
     *
     * @SWG\Property(description="User's last name", example="Doe")
     */
    protected $lastName;

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

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

控制器

<?php declare(strict_types=1);

namespace App\Controller;

use App\Dto\UpdateProfileEntryDto;
use Nelmio\ApiDocBundle\Annotation\Model;
use Swagger\Annotations as SWG;
use Symfony\Component\Routing\Annotation\Route;
use Wakeapp\Bundle\ApiPlatformBundle\HttpFoundation\ApiResponse;

/**
 * @Route("/api/profile")
 */
class ProfileController
{
    /**
     * Update user password
     *
     * @Route("/{email}", methods={"PATCH"})
     *
     * @SWG\Parameter(name="email", in="path", type="string", required=true, description="User email")
     * @SWG\Parameter(name="body", in="body", @Model(type=UpdateProfileEntryDto::class), required=true)
     *
     * @param UpdateProfileEntryDto $entryDto
     *
     * @return ApiResponse
     */
    public function getProfile(UpdateProfileEntryDto $entryDto): ApiResponse
    {
        return new ApiResponse($entryDto);
    }
}

如何描述在注解中的响应封装格式

为了使用注解描述响应封装格式 Wakeapp\Bundle\ApiPlatformBundle\Dto\ApiResultDto,可以采用以下方法

步骤 1 创建自定义服务器响应

<?php declare(strict_types=1);

namespace App\Dto;

use Swagger\Annotations as SWG;
use Wakeapp\Bundle\ApiPlatformBundle\Dto\ApiResultDto as BaseApiResultDto;
use Wakeapp\Component\DtoResolver\Dto\DtoResolverInterface;

/**
 * @SWG\Definition(
 *      type="object",
 *      description="Common API response object template",
 *      required={"code", "message"},
 * )
 */
class ApiResultDto extends BaseApiResultDto
{
    /**
     * @var int
     *
     * @SWG\Property(description="Response api code", example=0, default=0)
     */
    protected $code = 0;

    /**
     * @var string
     *
     * @SWG\Property(description="Localized human readable text", example="Successfully")
     */
    protected $message;

    /**
     * @var DtoResolverInterface|null
     *
     * @SWG\Property(type="object", description="Some specific response data or null")
     */
    protected $data = null;
}

步骤 2 在配置中添加

# app/config.yml
wakeapp_api_platform:
    api_result_dto_class:       App\Dto\MyApiResultDto

步骤 3 为您的函数添加描述

<?php declare(strict_types=1);

use Nelmio\ApiDocBundle\Annotation\Model;
use Swagger\Annotations as SWG;
use Wakeapp\Bundle\ApiPlatformBundle\HttpFoundation\ApiRequest;
use Wakeapp\Bundle\ApiPlatformBundle\HttpFoundation\ApiResponse;
use Wakeapp\Bundle\ApiPlatformBundle\Factory\ApiDtoFactory;

class ProfileController
{
    /**
     * ...
     * 
     * @SWG\Parameter(name="username", in="query", type="string", required=true, description="User login")
     * @SWG\Response(
     *      response=ApiResponse::HTTP_OK,
     *      description="Successful result in 'data' offset",
     *      @Model(type=ProfileResultDto::class)
     * )
     * @SWG\Response(response="default", @Model(type=ApiResultDto::class), description="Response wrapper")
     *
     * @param ApiRequest $apiRequest
     * @param ApiDtoFactory $factory
     * 
     * @return ApiResponse
     */
    public function getProfile(ApiRequest $apiRequest, ApiDtoFactory $factory): ApiResponse
    {
        return new ApiResponse();
    }
}

许可

license