首页 > 解决方案 > 如何判断 Avro 消息中何时需要命名空间?

问题描述

由于几个问题,我很难在 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"
        }
    ]
}

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

标签: avroconfluent-schema-registry

解决方案


不同之处在于它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.

推荐阅读