使用面向对象的方法生成 OpenAPI 规范,由 PHP 实现。

v2.10.0 2022-07-20 09:57 UTC

README

Object Oriented OpenAPI Specification

GitHub stars

GitHub tag (latest SemVer) Build status Packagist PHP from Packagist Dependency count Packagist

简介

使用面向对象的方法生成 OpenAPI 规范,由 PHP 实现。

您可以使用不可变的 PHP 类构建 API 规范,然后将其导出为 JSON(或使用其他包的帮助导出 YAML)。

此包无依赖项,并且大量使用 PHP 7 特性,主要是 类型提示 和启用 严格类型。这应该会使您在使用可以充分利用这些信息的良好 IDE 时的工作变得更加容易。

安装

您可以通过 composer 安装此包

composer require goldspecdigital/oooas

示例

请参见下面的代码示例,了解最基本的使用方法

use GoldSpecDigital\ObjectOrientedOAS\Objects\{
    Info, MediaType, Operation, PathItem, Response, Schema, Tag
};
use GoldSpecDigital\ObjectOrientedOAS\OpenApi;

// Create a tag for all the user endpoints.
$usersTag = Tag::create()
    ->name('Users')
    ->description('All user related endpoints');

// Create the info section.
$info = Info::create()
    ->title('API Specification')
    ->version('v1')
    ->description('For using the Example App API');
    
// Create the user schema.
$userSchema = Schema::object()
    ->properties(
        Schema::string('id')->format(Schema::FORMAT_UUID),
        Schema::string('name'),
        Schema::integer('age')->example(23),
        Schema::string('created_at')->format(Schema::FORMAT_DATE_TIME)
    );
    
// Create the user response.
$userResponse = Response::create()
    ->statusCode(200)
    ->description('OK')
    ->content(
        MediaType::json()->schema($userSchema)
    );
    
// Create the operation for the route (i.e. GET, POST, etc.).
$showUser = Operation::get()
    ->responses($userResponse)
    ->tags($usersTag)
    ->summary('Get an individual user')
    ->operationId('users.show');
    
// Define the /users path along with the supported operations.
$usersPath = PathItem::create()
    ->route('/users')
    ->operations($showUser);
    
// Create the main OpenAPI object composed off everything created above.
$openApi = OpenApi::create()
    ->openapi(OpenApi::OPENAPI_3_0_2)
    ->info($info)
    ->paths($usersPath)
    ->tags($usersTag);
    
header('Content-Type: application/json');
echo $openApi->toJson();

YAML 输出

使用上述相同代码将输出以下 YAML

在此示例中,YAML 可能看起来更简单,然而一旦规范开始增大,重用对象并将它们轻松拆分到单独的文件中将非常有帮助。

openapi: 3.0.2
info:
  title: API Specification
  description: For using the Example App API
  version: v1
paths:
  "/users":
    get:
      tags:
      - Users
      summary: Get an individual user
      operationId: users.show
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    format: uuid
                    type: string
                  name:
                    type: string
                  age:
                    type: integer
                    example: 23
                  created_at:
                    format: date-time
                    type: string
tags:
- name: Users
  description: All user related endpoints

输出为 JSON 或 YAML

故意省略了内置的 YAML 输出以保持此包无依赖项。然而,您可以使用多个开源包轻松地将数组转换为 YAML 字符串。下面是输出 JSON 和 YAML 的示例

use GoldSpecDigital\ObjectOrientedOAS\OpenApi;
use Symfony\Component\Yaml\Yaml;

$openApi = OpenApi::create();

$json = $openApi->toJson();
$array = $openApi->toArray();
$yaml = Yaml::dump($array);

指导

如果您想了解更多关于 OpenAPI 架构的信息,请查看官方的 OpenAPI 规范

或者,如果您需要一个快速参考,请查看由 Arnaud Lauret 创建的 OpenAPI Map 项目。

您可以使用这个交互式工具来找出对象在哪里以及它们如何相互关联。

用法

设置和取消设置属性

每个对象都有其支持的属性设置器方法。大多数这些方法允许 null 值,需要显式传递(请参阅下一个示例了解如何使用可变参数设置器方法取消设置)。这将取消设置属性

$info = Info::create()
    ->title('Example API');

$openApi = OpenApi::create()
    ->info($info);
echo $openApi->toJson(); // '{"info": {"title": "Example API"}}'

$openApi = $openApi->info(null);
echo $openApi->toJson(); // '{}'

对于可变参数设置器方法,如果您调用方法而不提供任何参数,则这将取消设置属性

$path = PathItem::create()
    ->route('/users');

$openApi = OpenApi::create()
    ->paths($path);
echo $openApi->toJson(); // '{"paths": {"/users": []}}'

$openApi = $openApi->paths();
echo $openApi->toJson(); // '{}'

检索属性

您可以使用魔法获取器轻松检索属性。这些方法已针对每个对象的每个属性实现。已提供 DocBlocks 以在 IDE 中提供更好的自动完成功能

$info = Info::create()->title('Example API');

echo $info->title; // 'Example API'

对象 ID

每个对象都有一个可选的 $objectId 属性,它是一个 string,可以在类构造函数或首选的 create() 方法中设置。当父对象需要使用名称引用子对象时,将使用此属性。

使用此属性的一个示例是当 schema 对象由其他 schema 属性组成时

$schema = Schema::create()
    ->type(Schema::TYPE_OBJECT)
    ->properties(
        Schema::create('username')->type(Schema::TYPE_STRING),
        Schema::create('age')->type(Schema::TYPE_INTEGER)
    );
    
echo $schema->toJson();
/* 
{
  "type": "object",
  "properties": {
    "username": {
      "type": "string"
    },
    "age": {
      "type": "integer"
    }
  }
} 
*/

如果对象包含任何辅助创建方法,则这些方法还允许您将 $objectId 属性作为参数指定。下面的代码示例与上面的代码功能相同

$schema = Schema::object()
    ->properties(
        Schema::string('username'),
        Schema::integer('age')
    );
    
echo $schema->toJson();
/* 
{
  "type": "object",
  "properties": {
    "username": {
      "type": "string"
    },
    "age": {
      "type": "integer"
    }
  }
} 
*/

$ref

$ref 的使用应用于每个对象,供您按需替换任何对象。您可以通过在对象类上调用 ref() 静态方法来将任何对象替换为 $ref

$schema = AllOf::create()
    ->schemas(
        Schema::ref('#/components/schemas/ExampleSchema')
    );
    
echo $schema->toJson();
/*
{
  "allOf": [
    ["$ref": "#/components/schemas/ExampleSchema"]
  ]
}
*/

规范扩展

您可以为所有对象添加规范扩展

$schema = Schema::create()
    ->x('foo', 'bar')
    ->x('items', Schema::array()->items(Schema::string()));
    
echo $schema->toJson();
/*
{
  "x-foo": "bar",
  "x-items": {
    "type": "array",
    "items": {
      "type": "string"
    }
  }
}
*/

echo $schema->{'x-foo'}; // 'bar'

您还可以通过调用x()方法并仅提供键来取消设置规范扩展

$schema = Schema::create()
    ->x('foo', 'bar')
    ->x('items', Schema::array()->items(Schema::string()));

$schema = $schema->x('foo');
    
echo $schema->toJson();
/*
{
  "x-items": {
    "type": "array",
    "items": {
      "type": "string"
    }
  }
}
*/

要获取所有规范扩展的数组,您可以调用$x属性

$schema = Schema::create()
    ->x('foo', 'bar')
    ->x('items', Schema::array()->items(Schema::string()));

echo json_encode($schema->x);
/*
{
  "x-foo": "bar",
  "x-items": {
    "type": "array",
    "items": {
      "type": "string"
    }
  }
}
*/

验证

为了执行模式验证,您必须首先安装justinrainbow/json-schema

composer require justinrainbow/json-schema:^5.2

安装完成后,您现在可以在OpenApi对象上使用validate()方法

$openApi = OpenApi::create();
$openApi->validate();

如果您尚未安装justinrainbow/json-schema包并尝试使用validate()方法,则会抛出RuntimeException异常。

如果模式验证失败,则会抛出GoldSpecDigital\ObjectOrientedOAS\Exceptions\ValidationException异常。您可以使用此异常上的getErrors()方法检索所有验证错误。

运行测试

要运行测试套件,您可以使用以下命令

# To run both style and unit tests.
composer test

# To run only style tests.
composer test:style

# To run only unit tests.
composer test:unit

如果您从样式测试中收到任何错误,您可以使用以下命令自动修复大多数,如果不是所有的问题

composer fix:style

贡献

请阅读CONTRIBUTING.md以了解我们的行为准则以及向我们提交拉取请求的过程。

版本控制

我们使用SemVer进行版本控制。有关可用的版本,请参阅此存储库上的标签

作者

还可以查看参与此项目的贡献者名单。

许可证

本项目采用MIT许可证 - 有关详细信息,请参阅LICENSE.md文件。