yapro/apiration-bundle

此包的最新版本(v1.0.6)没有可用的许可证信息。

API工具

v1.0.6 2023-04-27 08:26 UTC

This package is not auto-updated.

Last update: 2024-09-25 12:02:22 UTC


README

该库将JSON请求转换为您的对象,并将您的对象转换为JSON响应。

lib tests

如何使用

  1. 创建一个ApiRationObject,例如SimpleModel
<?php

declare(strict_types=1);

namespace App;

use YaPro\ApiRationBundle\Marker\ApiRationObjectInterface;

class SimpleModel implements ApiRationObjectInterface
{
    private string $varString;
    private bool $varBoolean;

    public function __construct(string $varString, bool $varBoolean) {
        $this->varString = $varString;
        $this->varBoolean = $varBoolean;
    }

    public function getVarString(): string
    {
        return $this->varString;
    }

    public function isVarBoolean(): bool
    {
        return $this->varBoolean;
    }
}
  1. 在控制器操作中使用SimpleModel(指定完整命名空间)
<?php

declare(strict_types=1);

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

class AppController extends AbstractController
{
    /**
     * @Route("/api-json-test/simple-model")
     *
     * @param \App\SimpleModel $model
     *
     * @return SimpleModel
     */
    public function getSimpleModel(SimpleModel $model, Request $request): SimpleModel
    {
        return $model;
    }
}
  1. 制作curl请求
curl -X GET "localhost/api-json-test/simple-model" -H 'Content-Type: application/json' -d'
{
  "varString": "string",
  "varBoolean": "true"
}
'
  1. 获取答案
{"varString":"string","varBoolean":true}

如你所见,任何实现ApiRationObjectInterface的对象都会自动转换为JSON。

更多示例测试

JsonRequest - 简单地处理Request

<?php

declare(strict_types=1);

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use YaPro\ApiRationBundle\Request\JsonRequest;

class AppController extends AbstractController
{
    /**
     * @Route("/search", methods={"POST"})
     *
     * @param JsonRequest           $request
     * @param ArticleRepository $articleRepository
     *
     * @return JsonResponse
     */
    public function search(JsonRequest $request): JsonResponse
    {
        $userAddresses = $request->getArray(); // request: ["foo@go.com", "bar@go.com"]
        // OR:
        $myFieldValue = $request->getObject()->myField; // request: {"myField": "my value"}

        return $this->json([]);
    }

如果您需要为创建操作创建JsonLd响应,请尝试

        return new ResourceCreatedJsonLdResponse(
            $article->getId(),
            [
                'title' => $article->getTitle(),
                'text' => $article->getText(),
            ]
        );

如果您需要为更新操作创建JsonLd响应,请尝试ResourceUpdatedJsonLdResponse

如何制作JsonLd响应(hydra:Collection)

CollectionJsonLdResponse自动支持分页

<?php

declare(strict_types=1);

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use YaPro\ApiRationBundle\Response\JsonLd\CollectionJsonLdResponse;

class AppController extends AbstractController
{
    /**
     * @Route("/list", methods={"GET"})
     */
    public function list(Request $request, ArticleRepository $articleRepository, SerializerInterface $serializer)
    {
        $collection = $articleRepository->getList();
        /*
            function getList(): array {
                return $this->createQueryBuilder('t')
                    ->select('t')
                    ->where('t.difficulty > 0')
                    ->getQuery()
                    ->getResult();
            }
        */
        $items = $serializer->normalize($collection, null, ['groups' => 'apiRead']);
        return (new CollectionJsonLdResponse($request))->initData($items);
    }
    
    /**
     * @Route("/search", methods={"GET"})
     *
     * @param Request           $request
     * @param ArticleRepository $articleRepository
     *
     * @return CollectionJsonLdResponse
     */
    public function search(Request $request, ArticleRepository $articleRepository): CollectionJsonLdResponse
    {
        $response = new CollectionJsonLdResponse($request);
        $searchValue = $request->query->get('searchValue', '');
        if (empty($searchValue)) {
            return $response;
        }

        $items = $this->getEntityManager()->getConnection()->fetchAll("
            SELECT 
                id,
                title
            FROM Article
            WHERE title LIKE :searchValue
            ORDER BY createdAt DESC
            LIMIT " . $response->getOffset() . ", " . $response->getLimit() . "
        ", [
             'searchValue' => $searchValue,
         ]);

        return $response->initData(
            $items,
            $this->getTotalItems()
        );
    }
}

注意:symfony 6.3支持类似功能,但该扩展包支持更多功能,例如,通过抛出BadRequestException响应无效请求

$message = 'Validation errors';
$errors = [
    'field_name' => 'The name cannot contain a number',
    'field_lastname' => [
        'The name cannot contain a number',
        'Name must be at least 2 characters long',
    ],
];
throw new BadRequestException($message, $errors);

客户端将收到状态为400的响应

{
    "message": "Validation errors",
    "errors": [
        {
            "fieldName": "field_name",
            "messages": [
                "The name cannot contain a number"
            ]
        },
        {
            "fieldName": "field_lastname",
            "messages": [
                "The name cannot contain a number",
                "Name must be at least 2 characters long"
            ]
        }
    ]
}

更多示例

在PHP 7上安装

在您的composer.json文件中添加要求或运行prod

composer require yapro/apiration-bundle laminas/laminas-code:3.4.1

在PHP 8上安装

在您的composer.json文件中添加要求或运行prod

composer require yapro/apiration-bundle

作为dev

composer require yapro/apiration-bundle dev-master

开发

docker build -t yapro/apiration-bundle:latest -f ./Dockerfile ./
docker run --rm --user=$(id -u):$(id -g) --add-host=host.docker.internal:host-gateway -it --rm -v $(pwd):/app -w /app yapro/apiration-bundle:latest bash
cp -f composer.lock.php7 composer.lock
composer install -o

调试测试

PHP_IDE_CONFIG="serverName=common" \
XDEBUG_SESSION=common \
XDEBUG_MODE=debug \
XDEBUG_CONFIG="max_nesting_level=200 client_port=9003 client_host=host.docker.internal" \
vendor/bin/simple-phpunit --cache-result-file=/tmp/phpunit.cache -v --stderr --stop-on-incomplete --stop-on-defect \
--stop-on-failure --stop-on-warning --fail-on-warning --stop-on-risky --fail-on-risky --testsuite=Unit,Functional

如果您需要php8

docker build -t yapro/apiration-bundle:latest --build-arg "PHP_VERSION=8" -f ./Dockerfile ./
cp -f composer.lock.php8 composer.lock

Cs-Fixer

wget https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/download/v3.8.0/php-cs-fixer.phar && chmod +x ./php-cs-fixer.phar
./php-cs-fixer.phar fix --config=.php-cs-fixer.dist.php -v --using-cache=no --allow-risky=yes

更新phpmd规则

wget https://github.com/phpmd/phpmd/releases/download/2.12.0/phpmd.phar && chmod +x ./phpmd.phar
./phpmd.phar . text phpmd.xml --exclude .github/workflows,vendor --strict --generate-baseline

CORS(可选功能)

    YaPro\ApiRationBundle\Cors\CorsResolver:
        tags:
            - { name: kernel.event_subscriber }

如果库不工作,请尝试在services.yml中添加以下行

    Symfony\Component\Serializer\Encoder\JsonDecode: ~
    Symfony\Component\Serializer\Encoder\JsonEncode: ~