詹姆斯-哈珀 / data-contracts
基于JSON模式创建可共享的数据合约
Requires
- php: ^7.4|^8.0
- illuminate/cache: ^8.12
- illuminate/container: ^8.12
- illuminate/database: ^8.12
- illuminate/filesystem: ^8.12
- illuminate/http: ^8.12
- opis/json-schema: ^1.0.19
- psr/simple-cache: ^1.0
- symfony/console: ^5.2
- symfony/process: ^5.2
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.18
- mockery/mockery: ^1.4.2
- pestphp/pest: ^1.0
README
在此定义的数据合约可以在多个服务之间共享。
最初是为与Laravel项目一起使用而设计的,因此有一些特定于Laravel的便利方法——例如处理验证规则或自动转换为API资源。
包含示例的Todo
和User
数据合约。以下命令可以运行以删除它们的全部痕迹。
php cli delete:contract Todo php cli delete:contract User
安装
这可以通过composer包含在其他包中。
composer require james-harper/data-contracts:^1.0
对于任何严重使用,建议您分支此存储库并添加适合您正在处理的域的数据合约。然后通过composer
使用分支版本。
定义合约
数据合约在遵循JSON模式规范的JSON文件中定义。
{ "$schema": "https://json-schema.fullstack.org.cn/draft-07/schema#", "title": "Person", "description": "A Person", "type": "object", "properties": { "id": { "type": "integer" }, "name": { "type": "string" } }, "required": [ "id", "name" ] }
可以使用以下命令验证模式定义是否符合规范
php cli validate:schema {name}
资源的id字段(默认为id
)将不会从describe()
方法返回。如果资源使用不同的标识符(例如guid
),则可以将合约的protected static $id
属性更新以反映这一点。
use DataContracts\DataContract; class User extends DataContract { protected $schema = 'path/to/file.json'; protected static $id = 'guid'; }
可以通过扩展DataContracts\DataContract
并设置$schema
属性为JSON定义的链接来创建PHP数据合约。模式路径应相对于项目根目录。如果没有定义模式,将抛出RuntimeException
。
use DataContracts\DataContract; class User extends DataContract { protected $schema = 'path/to/file.json'; }
可以使用以下composer命令生成数据合约
./cli make:contract {Name}
用法
每个数据合约都有一个静态的describe()
方法,它将返回合约上所有字段(非private
字段)和一个all()
方法,将显示所有内容。
还有一个validationRules()
方法可以用来获取合约的任何验证规则。这些规则应使用Laravel验证规则,以便可以直接用于Laravel项目中的请求验证。必须应用转换器才能从JSON模式获取有效的Laravel规则:这些可以在src/Rules
中找到。
use DataContracts\User as UserContract; UserContract::describe(); // ['first_name', 'last_name', 'email', 'role'] UserContract::all(); // ['first_name', 'last_name', 'email', 'role'] UserContract::validationRules(); // ['first_name' => ['required']...]
存在一些辅助函数,可以使处理验证规则更容易。validationRulesOptional()
获取所有规则,但删除任何required
规则。这在部分更新时非常有用,因为不是所有字段都会被期望。而rulesExcept($rule)
可以用来过滤掉选定的规则。
UserContract::validationRulesOptional(); // ['account_id' => ['numeric']...] UserContract::rulesExcept('numeric'); UserContract::rulesExcept(['numeric', 'min'])
数据合约可以在任何地方使用,但应定义在此存储库中以提高可共享性。
与Laravel Eloquent模型一起使用
可以使用数据合约将Eloquent模型过滤到仅在数据合约上的字段
$user = new User([ 'id' => 1, 'name' => 'James', 'email' => 'james@example.com', 'extraField' => 123, ]); UserContract::fromEloquent($user); // ['id' => 'James', 'name' => 'James', 'email' => 'james@example.com']
与Laravel API资源一起使用
同样,可以使用数据合约将Laravel API资源过滤到仅在数据合约上的字段
use Illuminate\Http\Resources\Json\JsonResource; class UserResource extends JsonResource { public function toArray() { return UserContract::fromResource($this); } }
如果需要执行任何其他转换,只需覆盖默认转换即可
use Illuminate\Http\Resources\Json\JsonResource; class UserResource extends JsonResource { public function toArray() { $user = UserContract::fromResource($this); $user['name'] = strtoupper($this->name); return $user; } }
CLI工具
已创建了一个CLI工具,用于简化常见任务并鼓励使用一致的模式。它类似于Laravel的artisan
设计,因此使用时应感到熟悉。可以使用./cli
或php cli
运行。在没有附加参数的情况下运行此工具将显示帮助屏幕,列出了所有可用命令。
以下命令可以用于
- 清除缓存
php cli flush:cache
php cli flush
- 运行代码风格检查
php cli lint:run
php cli lint
php cli lint --fix
- 生成控制台命令
php cli make:command <名称>
php cli new <名称>
- 生成数据契约
php cli make:contract <名称>
php cli schema <名称>
- 删除数据契约
php cli delete:contract <名称>
php cli delete <名称>
php cli remove <名称>
- 生成控制台格式化模式
php cli make:pattern <名称> <分隔符>
php cli make:pattern <名称> <开始分隔符> <结束分隔符>
php cli pattern <名称> <分隔符>
- 生成验证规则
php cli make:rule <名称>
php cli rule <名称>
- 运行测试
php cli test:run
php cli test
- 运行测试组
php cli test cache
php cli test rules,schemas
php cli test cache,contracts,rules,schemas,validation
- 更新CHANGELOG.md
php cli update:changelog
php cli changelog
php cli make:log
php cli generate:log
- 验证JSON模式
php cli validate:schema <名称>
php cli validate <名称>
- 验证所有JSON模式
php cli validate:all
对于任何命令的附加帮助,可以运行以下命令
php cli -h <命令>
- 例如
php cli -h make:command
php cli -h new
CLI文档存储在console/docs
中的Markdown文件中
可以通过运行以下命令启用CLI的Tab自动完成
source console/scripts/cli_autocompletion.sh
注意
- 由于
DataContracts
在更新此包之前不会改变,因此它们是缓存的好候选。有内置的缓存支持。默认情况下使用Illuminate\Cache
与file
驱动程序,但可以使用DataContract::setCache($cache)
设置任何PSR-16兼容的缓存 - 建议将
DataContracts
别名到带有Contract
后缀,以避免与模型混淆。例如:use DataContracts\User as UserContract
。一个如User::all()
的语句对Eloquent模型和数据契约都有效。UserContract::all()
可以更轻松地一眼看出。 - 为了避免自动加载问题,所有配置为使用PSR-4自动加载的目录(如
console/
、src/
、tests/
)中的子目录应以大写字母开头。不打算包含任何.php
文件的文件夹(如console/scripts
)不需要遵循此规则。 - 可以使用
composer test
来运行整个测试套件,或使用CLI测试命令php cli test cache,contracts,rules,schemas,validation
来运行特定的测试组。 - JSON Schema的日期/时间有时可能相当麻烦。以下是可以使用的一些格式示例。
"full-date full-time"
将匹配"Y-m-d h:i:s"
。"date-time"
期望在日期和时间部分之间有一个T。
date-fullyear = 4DIGIT
date-month = 2DIGIT ; 01-12
date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on
; month/year
time-hour = 2DIGIT ; 00-23
time-minute = 2DIGIT ; 00-59
time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second
; rules
time-secfrac = "." 1*DIGIT
time-numoffset = ("+" / "-") time-hour ":" time-minute
time-offset = "Z" / time-numoffset
partial-time = time-hour ":" time-minute ":" time-second
[time-secfrac]
full-date = date-fullyear "-" date-month "-" date-mday
full-time = partial-time time-offset
date-time = full-date "T" full-time