php-openapi / yii2-openapi
从OpenAPI 3规范生成完整的REST API应用程序。
Requires
- php: >=7.1.0
- cebe/php-openapi: ^1.5.0
- fakerphp/faker: ^1.9
- insolita/yii2-fractal: ^1.0.0
- laminas/laminas-code: ^3.4
- sam-it/yii2-mariadb: ^2.0
- yiisoft/yii2: ~2.0.15
- yiisoft/yii2-gii: ~2.0.0 | ~2.1.0 | ~2.2.0| ~2.3.0
Requires (Dev)
- cebe/indent: *
- friendsofphp/php-cs-fixer: ~2.16
- phpunit/phpunit: ^6.5|^8.0|^9.0
- yiisoft/yii2-gii: >=2.1.0
- dev-master / 2.0.x-dev
- 2.0-beta2
- 2.0-beta1
- 2.0-alpha
- 1.0.2
- 1.0.1
- 1.0.0
- 0.9.0-beta
- dev-165-better-way-to-resolve-allof
- dev-27-change-namespace-form-cebeyii2openapi-to-phpopenapiyii2openapi-or-pertinent
- dev-29-extension-fk-column-name-cause-error-in-case-of-column-name-without-underscore
- dev-45-setting-dbtype-to-enum-is-not-totally-correct
- dev-43-use-only-required-params-in-routedata
- dev-41-model-scenarios-for-createupdate-actions
- dev-37-symfonypolyfill-php80-should-be-moved-to-require-section-in-composerjson-file
- dev-35-resolve-todo-re-check-options-route-in-fractal-action
- dev-controller-namespace-issue-for-modules-in-urlprefixes
- dev-33-allownull-corresponds-to-default-value-null
- dev-30-add-validation-rules-by-attribute-name-or-pattern
- dev-25-generate-inverse-relations
- dev-22-bug-rules-required-is-generated-before-_default
- dev-20-consider-openapi-spec-examples-in-faker-code-generation
- dev-17-use-cache-in-tests-in-github-action
- dev-15-remove-unnecessary-command-from-makefile
- dev-144-methods-naming-for-non-crud-actions
- dev-phpstorm-refactor-cleanup-optimize-ctrl-alt-ahift-l
- dev-151-remove-unnecessary-null-or-default-related-migrations-in-pgsql
- dev-6-run-generated-migration-in-multidbsecondarymigrationtest-and-other-pertinent-test-file
- dev-8-make-fix-style-stopped-working
- dev-3-bug-addremove-property-and-at-the-same-time-change-it-at-x-indexes
- dev-test/168-index-on-relation-field
- dev-wip
- dev-x-table-wip
This package is auto-updated.
Last update: 2024-09-13 12:52:15 UTC
README
Yii2的REST API应用程序生成器,支持openapi 3.0 YAML -> Yii2。
TLDR;这是什么?
一个基于OpenAPI和Yii框架的PHP API应用程序的代码生成器。
输入:OpenAPI 3.0 YAML或JSON(通过cebe/php-openapi)
输出:带有控制器、模型和数据库模式的Yii框架应用程序
功能
当前可用功能
- 生成路径映射、控制器和动作以供API端点使用。CRUD端点是可用的,其他端点是生成的抽象函数,需要实现
- 根据OpenAPI模式生成模型和验证
- 从OpenAPI模式生成数据库模式
- 生成模式更改的数据库迁移
- 通过Faker提供模拟数据以供开发使用
要求
- PHP 7.1或更高版本(与PHP 8兼容良好)
安装
composer require php-openapi/yii2-openapi:^2.0@beta
使用
您可以将此软件包用于现有应用程序,或使用yii2-app-api应用程序模板启动新项目。有关模板的使用说明,请参阅模板存储库的README。
在现有Yii应用程序配置中(适用于控制台和Web)
<?php $config = [ // ... this is your application config ... ]; if (YII_ENV_DEV) { // enable Gii module $config['bootstrap'][] = 'gii'; $config['modules']['gii'] = [ 'class' => \yii\gii\Module::class, 'generators' => [ // add ApiGenerator to Gii module 'api' => \cebe\yii2openapi\generator\ApiGenerator::class, // --------- OR --------- // to disable generation of migrations files or with default config change 'api' => [ 'class' => \cebe\yii2openapi\generator\ApiGenerator::class, 'generateMigrations' => false, # this config can also be applied in CLI command ], ], ]; } return $config;
要使用Web生成器,请打开index.php?r=gii
并选择REST API Generator
。
在控制台中,您可以使用./yii gii/api --openApiPath=@app/openapi.yaml
运行生成器。其中@app/openapi.yaml
应该是您的OpenAPI规范文件的绝对路径。这可以是JSON,也可以是YAML(有关支持的格式,请参阅php-openapi/php-openapi)。
运行./yii gii/api --help
查看所有选项。例如:禁用迁移文件的生成./yii gii/api --generateMigrations=0
有关示例OpenAPI规范,请参阅Petstore示例。
OpenAPI扩展
此库理解以下OpenAPI规范的扩展
x-faker
您可以为属性指定用于生成假数据的自定义PHP代码
Post: properties: id: type: integer tags: type: array items: type: string example: ['one', 'two'] x-faker: "$faker->randomElements(['one', 'two', 'three', 'four'])"
要避免为特定的模型属性生成faker代码,请使用值false
Post: properties: age: type: integer x-faker: false
与allOf
一起使用
Invoice: type: object required: - id properties: id: type: integer Order: type: object required: - id properties: id: type: integer invoice: allOf: - $ref: '#/components/schemas/Invoice' - x-faker: false
x-table
指定定义存储在数据库中的模型的Schema的表名。您可以根据\yii\base\Model生成非数据库模型,而不生成迁移,通过设置x-table: false
x-pk
显式指定与“id”不同的表的主键名称
Post: x-table: posts x-pk: uid properties: uid: type: integer title: type: string
x-db-type
显式指定列的数据库类型。(必须只包含真实的DB类型! (json
、jsonb
、uuid
、varchar
等.))。如果将x-db-type
设置为false
,则属性将作为虚拟属性处理;它将作为公共属性添加到模型中,但将跳过迁移的生成。
x-db-type
的示例值:
false
(布尔值假)- 作为字符串,其值可以是以下内容:
- text
- text[]
- INTEGER PRIMARY KEY AUTO_INCREMENT
- decimal(12,4)
- json
- varchar
- VARCHAR
- SMALLINT UNSIGNED ZEROFILL
- MEDIUMINT(10) UNSIGNED ZEROFILL COMMENT "comment"(注意这里的双引号)
不允许使用以下值
int null default null after low_price
(null 和 default 将分别由nullable
和default
键处理)- MEDIUMINT(10) UNSIGNED ZEROFILL NULL DEFAULT '7' COMMENT 'comment' AFTER
seti
,ADD INDEXt
(w
)
如果同时提供了 enum
和 x-db-type
,则在数据库列模式(迁移)中,只考虑 x-db-type
,忽略 enum
。
x-indexes
指定表索引
Post: x-table: posts x-indexes: - 'visible,publish_date' - 'unique:title' #for unique attributes also unique validation check will be added - 'gist:metadata' #for postgres will generate index using GIST index type properties: id: type: integer x-db-type: INTEGER PRIMARY KEY AUTO_INCREMENT title: type: string visible: type: boolean publish_date: type: string format: date metadata: type: object x-db-type: JSON default: '{}'
x-db-default-expression
能够通过数据库表达式提供默认值
created_at: readOnly: true type: string format: datetime x-db-type: datetime nullable: false x-db-default-expression: current_timestamp()
注意:如果同时存在 default
和 x-db-default-expression
,则考虑 default
。
created_at: readOnly: true type: string format: datetime x-db-type: datetime nullable: false x-db-default-expression: current_timestamp() # this will be ignored default: "2011-11-11" # this will be considered
另请参阅:https://dev.mysqlserver.cn/doc/refman/8.0/en/data-type-defaults.html
x-fk-on-delete
允许在迁移中设置数据库表中行 ON DELETE 事件的 foreign key 约束。例如
components: schemas: User: type: object description: x on-x (update|delete) foreign key constraint properties: id: type: integer name: type: string Post: type: object description: x on-x (update|delete) foreign key constraint properties: id: type: integer title: type: string user: allOf: - $ref: '#/components/schemas/User' - x-fk-on-update: CASCADE user_2: allOf: - $ref: '#/components/schemas/User' - x-fk-on-update: CASCADE - x-fk-on-delete: SET NULL user_3: allOf: - $ref: '#/components/schemas/User' - x-fk-on-delete: SET NULL user_4: $ref: '#/components/schemas/User' # without any constraints
x-fk-on-update
允许在迁移中设置数据库表中行 ON UPDATE 事件的 foreign key 约束。例如,请参阅上述 x-fk-on-delete
部分。
x-fk-column-name
在关系列的情况下提供自定义数据库表列名。这不会反映在模型关系、faker 等。
components: schemas: Webhook: type: object description: example for x-fk-column-name properties: id: type: integer name: type: string user: $ref: '../openapi.yaml#/components/schemas/User' # this will automatically create `user_id` column redelivery_of: allOf: - $ref: '../openapi.yaml#/components/schemas/Delivery' # this will automatically create `redelivery_of_id` column, but to avoid that use below extension - x-fk-column-name: redelivery_of # this will create `redelivery_of` column instead of `redelivery_of_id`
多对多关系定义
定义多对多关系有两种方式
简单多对多(无连接模型)
-
多对多关系的属性名称应与复数化的小写相关模式名称相等
-
引用模式应包含对当前模式的镜像引用
-
连接表的迁移可以自动生成 - 表名应为 [复数化,小写 schema_name1]2[复数化,小写 schema_name2],按字母顺序;例如,对于模式 Post 和 Tag - 表应为 posts2tags,对于模式 Post 和 Attachement - 表应为 attachments2posts
Post:
properties:
...
tags:
type: array
items:
$ref: '#/components/schemas/Tag'
Tag:
properties:
...
posts:
type: array
items:
$ref: '#/components/schemas/Post'
多对多(有连接模型)
这种方式允许在两个模型之间创建多个多对多关系
- 定义具有所有必要属性的连接模式。只有一个重要要求 - 连接模式名称必须以前缀 'junction_' 开始(此前缀仅用于内部使用,在表和模型生成之前将被删除)
# Model TeamMembers with table team_members will be generated with columns team_id, user_id and role
junction_TeamMembers:
team:
$ref: '#/components/schemas/Team'
user:
$ref: '#/components/schemas/User'
role:
type: string
- 两个多对多相关模式都必须具有引用 "junction_*" 模式的属性。这些属性将用作关系名称
Team:
properties:
...
team_members:
type: array
items:
$ref: '#/components/schemas/junction_TeamMembers'
User:
properties:
...
memberships: #You absolutely free with naming for relationship attributes
type: array
items:
$ref: '#/components/schemas/junction_TeamMembers'
- 请参阅以下示例 tests/specs/many2many.yaml
NOT NULL
约束的处理
数据库迁移中的 NOT NULL
由 OpenAPI 模式的 nullable
和 required
属性确定。例如,属性 = 'my_property'。
- 如果您没有通过 "required" 或 "nullable" 定义属性,则它默认为
NULL
ExampleSchema: properties: my_property: type: string
- 如果您在 "required" 中定义了属性,则它为
NOT NULL
ExampleSchema: required: - my_property properties: my_property: type: string
- 如果您通过 "nullable" 定义了属性,则它覆盖 "required",例如,在这种情况下允许
NULL
ExampleSchema: required: - my_property properties: my_property: type: string nullable: true
- 如果您通过 "nullable" 定义了属性,则它覆盖 "required",例如,在这种情况下为
NOT NULL
test_table: required: properties: my_property: type: string nullable: false
enum
的处理
它在所有 3 个数据库中工作:MySQL、MariaDb 和 PgSQL。
test_table: properties: my_property: enum: - one - two - three
注意:枚举值的变化不是很简单。对于 Mysql 和 Mariadb,将生成迁移,但在许多情况下需要对其进行自定义修改。对于 Pgsql,枚举值更改的迁移将不会生成。应手动处理。
如果提供了 x-db-type
,则将忽略数据库列模式(迁移)。
numeric
的处理
precision-default = 10 scale-default = 2
- 您可以将属性定义为 "numeric(precision,scale)"
test_table: properties: my_property: x-db-type: decimal(12,4)
数据库结果 = decimal(12,4)
- 您可以定义类似 "numeric(precision)" 的属性,默认缩放默认值为 2
test_table: properties: my_property: x-db-type: decimal(12)
数据库结果 = decimal(12,2)
- 您可以定义类似 "numeric" 的属性,精度默认值为 10,缩放默认值为 2
test_table: properties: my_property: x-db-type: decimal
数据库结果 = decimal(10,2)
处理数据库列数据类型 timestamp
如果字段定义为
created_at: type: string format: date-time # or datetime example: '2020-03-14T21:42:17Z' readOnly: true
则选定的数据库类型将是 timestamp
。这是设计意图。如果需要 datetime
数据类型,请使用 x-db-type
作为
created_at: type: string format: date-time # or datetime example: '2020-03-14T21:42:17Z' x-db-type: datetime readOnly: true
假设
在从 OpenAPI 描述生成代码时,有许多可能的方法来实现合适的结果。因此,目前应用了一些假设和限制,以确保其正常工作。以下是一个(可能不完整)的列表
- 当前的实现最适合遵循 JSON:API 指南的 OpenAPI 描述。
- 当前未从 OpenAPI 架构中提取请求和响应格式/模式,并且如果它不遵循 JSON:API,则可能需要手动调整。
- 具有名称
id
的列/字段/属性被视为该库的主键,并且由数据库/Yii 自动处理;因此,请从验证rules()
中删除它。- 其他字段当前可以使用
x-pk
OpenAPI 扩展(见下文)作为主键使用,但可能在所有情况下都不正确工作,如果发现任何问题,请报告错误。
- 其他字段当前可以使用
其他注意事项
向现有表添加列
在 API 模型中添加新字段时,将生成新迁移以将这些字段添加到表中。对于已经投入生产的项目,应考虑调整生成的迁移以添加现有数据记录的默认值。
这种情况很重要,例如添加具有 NOT NULL
约束的新列,它不提供默认值。此类迁移将在表不为空时失败
$this->addColumn('{{%company}}', 'name', $this->string(128)->notNull());
在 PostgreSQL 数据库上失败
向表 {{%company}} 添加列名称 string(128) NOT NULL ...异常:SQLSTATE[23502]:空值违反:7 错误:列 "name" 包含空值
解决方案是创建列,允许 NULL,设置默认值,然后稍后添加空值约束。
$this->addColumn('{{%company}}', 'name', $this->string(128)->null()); $this->update('{{%company}}', ['name' => 'No name']); $this->alterColumn('{{%company}}', 'name', $this->string(128)->notNull());
屏幕截图
Gii 生成器表单
生成的文件
开发
要贡献或尝试,请参阅本地设置此项目的步骤 CONTRIBUTING.md。
支持
需要帮助您的 API 项目吗?
提供专业支持、咨询以及软件开发服务。
https://www.cebe.cc/en/contact
本库的开发由 cebe.:cloud: "您的专业部署平台" 赞助。