gdbots/pbjc

将pbj模式转换为jsonschema、php、js等语言的编译器。

v0.4.0 2019-04-06 18:25 UTC

README

Build Status Code Climate

将pbj模式转换为jsonschema、php、js等语言的编译器。

语言指南

本指南描述了如何使用XML语言来结构化您的模式文件语法以及如何生成数据类文件。

参考

让我们首先定义编译器中使用的每个元素和关键选项。

  • Schema: Schema的作用是定义pbj消息,包括字段和相关混入(用于扩展schema功能的其他schema)。

  • Enum: Enum是一组键值,用于schema字段(见下文枚举)。

  • SchemaId: 一个Schema的完全限定名称(id)。

    • Schema Id: pbj:vendor:package:category:message:version
    • Schema Curie Major: vendor:package:category:message:v#
    • Schema Curie: vendor:package:category:message
    • Schema QName: vendor:message
  • SchemaVersion: 与语义版本类似,但使用短划线且不带“alpha、beta等”限定符。

    • Schema 版本格式: major-minor-patch

定义Schema

首先,让我们看一个非常简单的例子。假设你想要定义一个包含slug和name字段的mixin schema。这是你用来定义schema的.xml文件。

<?xml version="1.0" encoding="UTF-8" ?>
<pbj-schema xmlns="http://gdbots.io/pbj/xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://gdbots.io/pbj/xsd http://gdbots.io/pbj/xsd/schema.xsd">

  <schema id="pbj:acme:blog:entity:article:1-0-0" mixin="true">
    <fields>
      <field name="slug" type="string" pattern="/^[A-Za-z0-9_\-]+$/" required="true" />
      <field name="title" type="text" required="true" />
    </fields>
  </schema>
</pbj-schema>

每个schema都需要一些基本元素:id和fields。id是一个唯一的标识符,遵循基本的schema-id格式pbj:vendor:package:category:message:version(version = major-minor-patch)。fields是一个关联字段的数组,用于schema。在上面的例子中,store schema包含slug和title。

由于我们正在创建一个mixin schema,我们在第二行将mixin = true设置。

此外,我们允许添加语言特定的选项,这些选项将在生成语言输出文件时使用。

Schema 字段类型

以下列表包含所有可用的字段类型

- big-int
- binary
- blob
- boolean
- date
- date-time
- decimal
- dynamic-field
- float
- geo-point
- identifier
- float
- int
- medium-blob
- medium-int
- medium-text
- microtime
- signed-big-int
- signed-int
- signed-medium-int
- signed-small-int
- signed-tiny-int
- small-int
- string
- text
- time-uuid
- timestamp
- tiny-int
- uuid

默认值

当解析schema时,如果编码的schema不包含特定的单个元素,则解析对象中的相应字段将设置为该字段的默认值。这些默认值是类型特定的

- For strings, the default value is the empty string.
- For bytes, the default value is empty bytes.
- For bools, the default value is false.
- For numeric types, the default value is zero.
- For each of the other field types, the default value is null.

枚举

当你定义一个schema时,你可能希望其中一个字段仅具有预定义列表中的一个值。例如,假设你想要添加一个Reason枚举字段,其值可以是INVALIDFAILEDDELETED

<fields>
  <field name="failure_reason" type="string-enum">
    <default>invalid</default>
    <enum id="acme:blog:publish-status" />
  </field>
</fields>

enums.xml中定义枚举

<enums namespace="acme:blog">
  <enum name="publish-status" type="string">
    <option key="PUBLISHED" value="published" />
    <option key="DRAFT" value="draft" />
    <option key="PENDING" value="pending" />
    <option key="EXPIRED" value="expired" />
    <option key="DELETED" value="deleted" />
  </enum>
<enums>

从上面的例子中可以看出,我们定义了特定schema的枚举键和值,并直接从字段中调用。

注意:我们还可以定义枚举类将生成的PHP命名空间。

存在两种枚举类型,StringEnumIntEnum。我们将它们分开以简化字段类型和值。

注意:例如,MySQL、DynamoDB和其他数据库根据类型(字符串或整数)定义枚举。

使用消息类型

你可以使用MessageMessageRef作为字段类型。例如,假设你想要在Story schema中包含相关消息

<field name="failed_request" type="message">
  <any-of>
    <curie>gdbots:pbjx:mixin:request</curie>
  </any-of>
</field>

any-of属性定义将用于提取消息详细信息的消息ID。

完整的Schema选项

<?xml version="1.0" encoding="UTF-8" ?>
<pbj-schema xmlns="http://gdbots.io/pbj/xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://gdbots.io/pbj/xsd http://gdbots.io/pbj/xsd/schema.xsd">

  <schema
    id="{pbj:vendor:package:category:message:major-minor-patch}"
    mixin="{bool}"
    extends="{pbj:vendor:package:category:vmajor}"
  >
    <fields>
      <field
        name="{/^([a-zA-Z_]{1}[a-zA-Z0-9_]+)$/}"
        type="{\Gdbots\Pbjc\Type\Type}"
        required="{bool}"
        min="{int}"
        max="{int}"
        precision="{int}"
        scale="{int}"
        rule="{\Gdbots\Pbjc\Enum\FieldRule}"
        pattern="{string}"
        format="{Gdbots\Pbjc\Enum\Format}"
        use-type-default="{bool}"
        overridable="{bool}"
      >
        <default>{string}</default>

        <enum id="{vendor:package:enum}" />

        <any-of>
          <curie>{pbj:vendor:package:category}</curie>
          <!-- ... -->
        </any-of>

        <php-options>
          <imports>{string}</imports>
          <class-name>{string}</class-name>
          <default>{string}</default>
        </php-options>

        <js-options>
          <imports>{string}</imports>
          <class-proto>{string}</class-proto>
          <default>{string}</default>
        </php-options>
      </field>
    </fields>

    <mixins>
      <curie-major>{pbj:vendor:package:category:vmajor}</curie-major>
      <!-- ... -->
    </mixins>
  </schema>
</pbj-schema>
<?xml version="1.0" encoding="UTF-8" ?>
<pbj-enums xmlns="http://gdbots.io/pbj/xsd"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://gdbots.io/pbj/xsd http://gdbots.io/pbj/xsd/enums.xsd">

  <enums namespace="{vendor:package}">
    <enum name="{string}" type="int|string">
      <option key="{string}" value="{string}" />
      <!-- ... -->
    </enum>
  <enums>
</enums-mapping>

注意:对于每个php-options,你还可以添加动态标签。例如

<php-options>
  <insertion-points>
    <imports>
        <![CDATA[
use Gdbots\Pbj\MessageRef;
        ]]>
    </imports>
    <methods>
        <![CDATA[
/**
 * @param string $tag
 * @return MessageRef
 */
public function generateMessageRef($tag = null)
{
    return new MessageRef(static::schema()->getCurie(), $this->get('command_id'), $tag);
}
        ]]>
    </methods>
  </insertion-points>
</php-options>

基本用法

pbjc --language[=LANGUAGE] --config[=CONFIG]

pbjc.yml文件中定义编译设置

namespaces:
  - <vendor1>:<package1>
  - <vendor2>:<package2>

languages:
  php:
    output: <div>
    manifest: <dir>/<filename>

注意:默认情况下,编译器在根目录中搜索pbjc.yml