【问题标题】:Kafka Connect JSON Schema does not appear to support "$ref" tagsKafka Connect JSON 模式似乎不支持“$ref”标签
【发布时间】:2021-12-05 17:49:41
【问题描述】:

我正在使用带有 JSONSchema 的 Kafka Connect,并且我需要在 Kafka Connect 插件中手动转换 JSON 模式(转换为“模式”)。我可以成功地从架构注册表中检索 JSON 架构,并且可以成功地使用简单的 JSON 架构进行转换,但是对于那些复杂且在单个 JSON 架构定义中引用组件的有效“$ref”标签存在困难。

我有几个问题:

  1. JsonConverter.java 似乎无法处理“$ref”。我是正确的,还是它在其他地方以其他方式处理它?
  2. 模式注册表是否处理子定义的引用?如果是,是否有代码显示如何处理取消引用?
  3. 在提交到 Schema Registry 之前,是否应该将 JSON Schema 解析为没有引用的字符串(即内联引用),从而消除“$ref”问题?

我在看下面的Kafka源码模块JsonConverter.java:

https://github.com/apache/kafka/blob/trunk/connect/json/src/main/java/org/apache/kafka/connect/json/JsonConverter.java#L428

下面显示了一个复杂模式的示例(取自 JSON Schema 站点)(注意 "$ref": "#/$defs/veggie" 标记引用后面的子定义)

{
  "$id": "https://example.com/arrays.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "A representation of a person, company, organization, or place",
  "title": "complex-schema",
  "type": "object",
  "properties": {
    "fruits": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "vegetables": {
      "type": "array",
      "items": { "$ref": "#/$defs/veggie" }
    }
  },
  "$defs": {
    "veggie": {
      "type": "object",
      "required": [ "veggieName", "veggieLike" ],
      "properties": {
        "veggieName": {
          "type": "string",
          "description": "The name of the vegetable."
        },
        "veggieLike": {
          "type": "boolean",
          "description": "Do I like this vegetable?"
        }
      }
    }
  }
}

以下是模式注册成功后从模式注册表返回的实际模式:

[
  {
    "subject": "complex-schema",
    "version": 1,
    "id": 1,
    "schemaType": "JSON",
    "schema": "{\"$id\":\"https://example.com/arrays.schema.json\",\"$schema\":\"https://json-schema.org/draft/2020-12/schema\",\"description\":\"A representation of a person, company, organization, or place\",\"title\":\"complex-schema\",\"type\":\"object\",\"properties\":{\"fruits\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}},\"vegetables\":{\"type\":\"array\",\"items\":{\"$ref\":\"#/$defs/veggie\"}}},\"$defs\":{\"veggie\":{\"type\":\"object\",\"required\":[\"veggieName\",\"veggieLike\"],\"properties\":{\"veggieName\":{\"type\":\"string\",\"description\":\"The name of the vegetable.\"},\"veggieLike\":{\"type\":\"boolean\",\"description\":\"Do I like this vegetable?\"}}}}}"
  }
]

实际的模式嵌入在上面返回的字符串中(“模式”字段的内容)并包含 $ref 引用:

{\"$id\":\"https://example.com/arrays.schema.json\",\"$schema\":\"https://json-schema.org/draft/2020-12/schema\",\"description\":\"A representation of a person, company, organization, or place\",\"title\":\"complex-schema\",\"type\":\"object\",\"properties\":{\"fruits\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}},\"vegetables\":{\"type\":\"array\",\"items\":{\"$ref\":\"#/$defs/veggie\"}}},\"$defs\":{\"veggie\":{\"type\":\"object\",\"required\":[\"veggieName\",\"veggieLike\"],\"properties\":{\"veggieName\":{\"type\":\"string\",\"description\":\"The name of the vegetable.\"},\"veggieLike\":{\"type\":\"boolean\",\"description\":\"Do I like this vegetable?\"}}}}}

【问题讨论】:

  • 根据您提交的架构,您为什么希望响应不包括 $ref
  • 是的,“$ref”是预期的,但问题实际上是关于如何/在哪里处理和解决“$ref”标签。
  • 我不希望您对它们进行预处理。它们是 JSON Schema 标准的一部分,因此 JSON Schema 实现应该理解它们。 $ref 不像某种模板命令。解决方案应由在验证数据时使用架构的实现来完成。

标签: apache-kafka apache-kafka-connect jsonschema confluent-platform


【解决方案1】:

同样,Apache Kafka 源代码中的 JsonConverter 没有 JSONSchema 的概念,因此,不,$ref 不起作用,它也没有与注册表集成。

您似乎正在寻找 io.confluent.connect.json.JsonSchemaConverter 类 + 逻辑

【讨论】:

  • 这提出了两个问题(我将把每个问题放在单独的 cmets 中): 1. 模式注册表是否处理具有有效“$ref”标签的有效 JSON 模式?现在,我可以成功地将它们提交到 Schema Registry 并且它保留了“$ref”标签……所以,假设它处理有效的 JSON Schema,那么它确实处理了“$ref”……但是在哪里?
  • 关于引用,您可以在此处找到 PR,在 Schema Registry 项目中,而不是 Kafka - github.com/confluentinc/schema-registry/pull/1280
  • 2.我看到我可以使用“$ref”标签来最初提交一个引用数组,但它们需要引用一个需要单独提交的单独模式。虽然这在某些情况下很有用,但它不能处理“$ref”嵌入到复杂模式中的情况......
  • 好的。我查看了 JsonSchemaConverter.java ,看起来(通过使用 org.everit.json 代码)$ref 得到了解析......所以,我想我可以假设(可能不正确)Schema Registry 可以解析 $ref 标签...但是为什么我在模式注册表的响应中得到未解析的 $ref 标记?我想我误解了你的意思(我很抱歉......顺便说一句:感谢你所有的帮助!)
  • 我没有深入研究注册表上的 JSON 支持,只有 Avro,但 AFAIK,引用仅在反序列化期间得到解析,而不是在服务器端,所以如果你使用 HTTP 请求,那么您只需按原样获取架构文本
猜你喜欢
  • 2018-03-20
  • 1970-01-01
  • 2018-12-13
  • 2020-10-26
  • 1970-01-01
  • 2017-06-17
  • 2018-03-10
  • 2021-09-25
  • 2012-06-02
相关资源
最近更新 更多