承接 psx/api-bundle 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

psx/api-bundle

Composer 安装命令:

composer require psx/api-bundle

包简介

Symfony bundle to build type-safe APIs

README 文档

README

The PSX API bundle integrates the PSX API components into Symfony which help to build fully type-safe REST APIs. Basically the bundle provides additional attributes which you can use at your controller to map HTTP parameters to arguments of your controller and commands to generate based on those attributes and type-hints different artifacts:

  • Generate Client SDKs for different languages i.e. TypeScript and PHP
    • php bin/console generate:sdk client-typescript
  • Generate OpenAPI specification without additional attributes
    • php bin/console generate:sdk spec-openapi
  • Generate DTO classes using TypeSchema
    • php bin/console generate:model

As you note this bundle is about REST APIs and not related to any PlayStation content, the name PSX was invented way back and is simply an acronym which stands for "PHP, SQL, XML"

Installation

To install the bundle simply require the composer package at your Symfony project.

composer require psx/api-bundle

Make sure, that the bundle is registered at the config/bundles.php file:

return [
    PSX\ApiBundle\PSXApiBundle::class => ['all' => true],
];

Controller

The following is a simple controller which shows how to use the PSX specific attributes to describe different HTTP parameters:

<?php

declare(strict_types=1);

namespace App\Controller;

use App\Model\PostCollection;
use App\Model\Post;
use App\Model\Message;
use PSX\Api\Attribute\Body;
use PSX\Api\Attribute\Param;
use PSX\Api\Attribute\Query;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Attribute\Route;

final class PostController extends AbstractController
{
    public function __construct(private PostService $service, private PostRepository $repository)
    {
    }

    #[Route('/post', methods: ['GET'])]
    public function getAll(#[Query] ?string $filter): PostCollection
    {
        return $this->repository->findAll($filter);
    }

    #[Route('/post/{id}', methods: ['GET'])]
    public function get(#[Param] int $id): Post
    {
        return $this->repository->find($id);
    }

    #[Route('/post', methods: ['POST'])]
    public function create(#[Body] Post $payload): Message
    {
        return $this->service->create($payload);
    }

    #[Route('/post/{id}', methods: ['PUT'])]
    public function update(#[Param] int $id, #[Body] Post $payload): Message
    {
        return $this->service->update($id, $payload);
    }

    #[Route('/post/{id}', methods: ['DELETE'])]
    public function delete(#[Param] int $id): Message
    {
        return $this->service->delete($id);
    }
}

In the example we use the #[Query], #[Param] and #[Body] attribute to map different parts of the incoming HTTP request. In the controller we use a fictional PostService and PostRepository but you are complete free to design the controller how you like, for PSX it is only important to map the incoming HTTP request parameters to arguments and to provide a return type.

Raw payload

We always recommend to generate concrete DTOs to describe the request and response payloads. If you need a raw payload we provide the following type-hints to receive a raw value.

  • Psr\Http\Message\StreamInterface
    • Receive the raw request as stream application/octet-stream
  • PSX\Data\Body\Json
    • Receive the raw request as JSON application/json
  • PSX\Data\Body\Form
    • Receive the raw request as form application/x-www-form-urlencoded
  • string
    • Receive the raw request as string text/plain

For example to write a simple proxy method which returns the provided JSON payload s.

#[Route('/post', methods: ['POST'])]
public function create(#[Body] Json $body): Json
{
    return $body;
}

Multiple response types

In case your method can return different response types you can use the #[Outgoing] attribute to define a response schema independent of the return type.

#[Route('/post', methods: ['POST'])]
#[Outgoing(201, Message::class)]
#[Outgoing(400, Error::class)]
public function create(#[Body] Post $body): JsonResponse
{
    if (empty($body->getTitle())) {
        return new JsonResponse(new Error('An error occurred'), 400);
    }

    return new JsonResponse(new Message('Post successfully created'), 201);
}

Generator

SDK

To generate an SDK you can simply run the following command:

php bin/console generate:sdk

This reads alls the attributes from your controller and writes the SDK to the output folder. At first argument you can also provide a type, by default this is client-typescript but you can also select a different type.

  • client-php
  • client-typescript
  • spec-openapi

SDKgen

Through the SDKgen project you have the option to generate also client SDKs for different programming languages, therefor you only need to register at the SDKgen website to obtain a client id and secret which you need to set as psx_api.sdkgen_client_id and psx_api.sdkgen_client_secret at your config. After this you can use one of the following types:

  • client-csharp
  • client-go
  • client-java
  • client-python

TypeHub

If you want to share your API specification it is possible to push your specification to the TypeHub platform with the following command:

php bin/console api:push my_document_name

Then you also need to provide a client id and secret for your account. The TypeHub platform basically tracks all changes of the API specification and it is possible to download different SDKs.

Model

This bundle also provides a model generator which helps to generate DTOs to describe the incoming and outgoing payload s.

php bin/console generate:model

This commands reads the TypeSchema specification located at config/typeschema.json and writes all model classes to src/Model. In general TypeSchema is a JSON specification to describe data models. The following is an example specification to generate a simple Student model.

{
  "definitions": {
    "Student": {
      "description": "A simple student struct",
      "type": "struct",
      "properties": {
        "firstName": {
          "type": "string"
        },
        "lastName": {
          "type": "string"
        },
        "age": {
          "type": "integer"
        }
      }
    }
  }
}

Configuration

The bundle needs the following psx_api.yaml configuration:

psx_api:
  base_url: 'https://api.acme.com'
  sdkgen_client_id: ''
  sdkgen_client_secret: ''

The base_url is the absolute url to your API so that you don't need to provide the base url at your client SDK.

The sdkgen_client_id and sdkgen_client_secret are credentials to the SDKgen app.

Technical

This bundle tries to not change any Symfony behaviour, for example we use the existing #[Route] attribute instead of the #[Path] attribute. This has some small tradeoffs, at first you are required to use the #[Route] attribute, YAML, XML or PHP routing is not supported, since otherwise the generate command will not be able to parse the routes, and second your route has to specify a concrete HTTP method filter, since the SDK generator needs a concrete HTTP method for every endpoint.

Basically the bundle only registers the following classes:

  • PSX\ApiBundle\ArgumentResolver\ValueResolver
    • To parse the attributes of each argument and transform the incoming value
  • PSX\ApiBundle\EventListener\SerializeResponseListener
    • To transform the response of the controller
  • PSX\ApiBundle\EventListener\ExceptionResponseListener
    • To transform the exception response

Community

Feel free to create an issue or PR in case you want to improve this bundle. We also like to give a shout-out to praswicaksono for implementing a first version of this bundle.

psx/api-bundle 适用场景与选型建议

psx/api-bundle 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 16 次下载、GitHub Stars 达 3, 最近一次更新时间为 2024 年 12 月 29 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「symfony」 「rest」 「api」 「specification」 「dto」 「code-generator」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 psx/api-bundle 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 psx/api-bundle 我们能提供哪些服务?
定制开发 / 二次开发

基于 psx/api-bundle 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 16
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 3
  • 点击次数: 21
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 3
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2024-12-29