如何判断 Avro 消息中何时需要命名空间?

How to tell when namespace is needed in Avro message?

由于几个问题,我很难在 Avro 中推广名称空间的使用。最近的一项是消息何时应包含名称空间。我现在认为使用名称空间会因为感知到的不一致而变得太麻烦。最近我们一直在处理来自 Confluent Schema Registry 的以下错误:

"error_code": 42203,
"message": "Conversion of JSON to Object failed: Failed to convert JSON to Avro: Unknown union branch id"

此错误的来源似乎是正在发送的消息中缺少命名空间标识符。

例如,在我的架构中,我有一个名为 Component 的部分,其定义如下:

{
"name": "component",
"type": {
    "type": "array",
    "items": {
        "type": "record",
        "name": "Component",
        "fields": [
            {
                "name": "typeCode",
                "type": {
                    "type": "enum",
                    "name": "ComponentTypeCode",
                    "symbols": [
                        "PremiumDue",
                        "LoanInterestDue"
                    ]
                }
            },
            {
                "name": "messageFlag",
                "type": "YesNo",
                "doc": "Whether there is a message associated with this entry."
            },
            {
                "name": "amountDue",
                "type": "string",
                "doc": "Amount of the specified component. For example 123.78"
            }
        ]
    }
}

}

这可以在没有名称空间的情况下发送而不会出现问题:

{
    "component": [
        {
            "typeCode": "AppliedDividend",
            "messageFlag": "Yes",
            "amountDue": "192775.34"
        }
    ]
}

然而,在模式的另一部分,我有一个这样定义的枚举:

{
"name": "otherLetterCode",
"type": [
    "null",
    {
        "type": "enum",
        "name": "OtherLetterCode",
        "symbols": [
            "PaidUpDateModLetter",
            "IndemnityLetter"
        ]
    }
]

}

在消息中,必须这样发送:

"otherLetterCode": {
     "my.namespace.OtherLetterCode": "IndemnityLetter"
}

这似乎不一致。如果整个模式是在一个命名空间内定义的,我们是否应该 a) 在整个消息中使用命名空间或 b) 根本不必在消息中使用命名空间?我希望 component 看起来像这样:

{
    "my.namespace.component": [
        {
            "typeCode": "AppliedDividend",
            "messageFlag": "Yes",
            "amountDue": "192775.34"
        }
    ]
}

继续使用命名空间是否有意义,如果是这样,我们如何确保我们的各种系统客户端能够创建在适当位置拼写出命名空间值的消息,假设它们会无法使用自动代码生成实用程序?

区别在于otherLetterCode是两个可能值的并集。 JSON 的 avro 规范是大多数人期望的方式(即字段名称是键名,字段值是键值),联合的情况除外。您可以在此处查看规范:https://avro.apache.org/docs/current/spec.html#json_encoding,但在联合的情况下,如果值非空,则它期望包含命名空间类型。

具体来说:

For example, the union schema ["null","string","Foo"], where Foo is a record name, would encode:

- null as null;
- the string "a" as {"string": "a"}; and
- a Foo instance as {"Foo": {...}}, where {...} indicates the JSON encoding of a Foo instance.