詹姆斯-哈珀/data-contracts

该包最新版本(1.0)没有可用的许可证信息。

基于JSON模式创建可共享的数据合约

1.0 2021-03-21 18:03 UTC

This package is auto-updated.

Last update: 2024-09-22 03:36:26 UTC


README

在此定义的数据合约可以在多个服务之间共享。

最初是为与Laravel项目一起使用而设计的,因此有一些特定于Laravel的便利方法——例如处理验证规则或自动转换为API资源。

包含示例的TodoUser数据合约。以下命令可以运行以删除它们的全部痕迹。

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设计,因此使用时应感到熟悉。可以使用./cliphp 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\Cachefile驱动程序,但可以使用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