2023 年 2 月 22 日,星期三 ·7分钟阅读

自定义注解将继续存在

上次,我写了我们如何不得不移除对未知关键字的支持。我在文章末尾留下了一段话,说我们仍在寻找一种方法来支持非功能性自定义关键字,也就是简单的注解。

在这篇文章中,我想回顾一下解决方案以及我们是如何得出的,并简单介绍一下我们想到的其他一些解决方案。系好安全带,这将会是一段轻松的旅程!

解决方案是什么?

简而言之,未来 JSON Schema 将把所有以 x- 开头的关键字视为注解。

选择这种解决方案有几个原因。

  1. 特设关键字必然不能有任何功能与其绑定。也就是说,它们永远只是注解;它们的值只是被返回给用户或应用程序,而不会被模式进行任何处理。
  2. 特设注解遵循一种约定,这使得它们很容易识别。
  3. 前缀是一个很好的约定。
  4. 将此前缀保留用于特设注解意味着现在或将来不会与词汇表定义的关键字发生冲突(维护我们的兼容性承诺)。
  5. 开发人员普遍熟悉 x- 前缀,因为它在其他领域(如 HTTP 标头)中已经普遍使用,用于表示用于了解它的接收者的自定义数据。

我们对使用 x- 的唯一犹豫是,它的起源表示实验行为。然而,在实践中,此前缀似乎被相当随意地用于任何自定义数据。既然我们正在将自定义数据作为我们的明确目的,它似乎是一个不错的选择。

为什么使用前缀而不是其他解决方案?

在发布上一篇博文并尽可能广泛地将其发布到互联网之后,我们收到了反馈,自定义关键字被广泛使用,不支持它们会导致比我们想要的更严重的用户问题。虽然我们已经计划继续支持注解型自定义关键字,但我们不知道会是什么样子。因此,我启动了一个关于我们团队已经有一些松散想法的讨论

讨论中有很多内容和很多想法,但我这里只介绍一些重点。如果您有兴趣了解详细信息,请随时阅读讨论。

备选方案 #1 - 在新的关键字中定义前缀

此选项实际上是在我们选择的方案基础上构建的,通过定义一个新的核心关键字(以 $ 开头),该关键字将包含用于该模式的前缀。这是一个引人入胜的概念,它将允许模式作者使用他们想要的前缀。

然而,有人指出,为了让模式能够通过元模式进行验证,元模式需要能够读取这个新的关键字来获取前缀,以便它可以忽略以该前缀开头的关键字。这需要我们目前在 JSON Schema 中没有的许多新机制,因此在目前来说并不实用。

我们还注意到,我们无法弄清楚此关键字的范围是什么。它将仅限于使用该关键字的模式资源(由 $id 指示)吗?它会是整个文档吗?如果我们 $ref 到另一个没有定义前缀的模式资源或文档怎么办?在推断意图和要求过多重复之间存在着平衡。

备选方案 #2 - 在新的关键字中列出要忽略的自定义关键字

此选项定义一个新的核心关键字,例如 $ignored,它将保存一个要忽略的关键字名称数组。这将允许模式作者明确定义他们想要使用的关键字。

与备选方案 #1 一样,它存在的问题是,JSON Schema 目前没有执行所需元模式验证的机制,以及相同的范围问题。模式作者也可能忽略将来添加到规范或某个词汇表中的关键字,这意味着它不应该被忽略,从而导致出乎意料的错误验证,并且违反了我们的兼容性要求。

备选方案 #3 - 内联词汇表定义关键字

此选项允许在元模式的 $vocabulary 关键字中定义和描述词汇表。这与备选方案 #2 类似,不同之处在于,特设关键字由词汇表定义,因此执行“没有未知关键字”的正常 JSON Schema 过程不会发现它们;它们将是已知的。

我们反对这种方案,因为它需要对词汇表进行大量的进一步开发,而词汇表本身仍然处于开发阶段。这种方案还会使词汇表开发偏向于解决这个问题,而这可能不是词汇表概念的正确方向。

备选方案 #4 - 一个新的关键字来包含所有自定义注解

此选项创建一个新的核心关键字,例如 $extra,它只是保存模式作者可能想要使用的所有自定义关键字。

这种做法不可取,因为它会在注解和它们试图注解的数据之间创建一层隔离。但更重要的是,一个关键字只能创建一个注解(按照现在的定义),因此像 $extra 这样的关键字会将所有注解都集中在一个大型对象中,而不是像单独的关键字那样更具针对性。

备选方案 #5 - 通过选项支持未知关键字

最后,此选项只要求实现提供一个配置选项,以允许未知关键字,默认设置为“不允许”。虽然允许未知关键字会破坏我们的兼容性承诺,但用户明确设置此选项实际上是在承认这种风险。

这感觉像倒退了一步。这似乎与我们希望在这个项目中实现的可支持性精神不符。

我们是如何选择 x- 作为前缀的?

在上一篇文章中,我链接到讨论并邀请大家支持他们喜欢的想法或提出新的想法。我们看到了比以往更多的互动,这真是太好了!

此外,我们在社交媒体上发布了关于讨论的信息,我们甚至发现了其他人发布的几篇帖子(例如,在 reddit 上),这些帖子链接到博客文章或讨论(或两者),并在该平台上进行讨论。

一旦我们确定前缀选项看起来是最受欢迎的选择,我们的社区经理 Benjamin Granados 创建了一个调查,列出了前缀可能是什么的选项。它包括我们在讨论中提出的建议,x- 和一些容易键入的符号,以及一个“自己制作”的选项。

我们有 53 名受访者,这看起来可能不多,但比我们以前拥有的更多。结果清楚地表明,x-(获得 17 票)是最受欢迎的前缀。并列第二的是“at”符号 @ 和星号 *,分别获得了 12 票。

太长了;还是读一下吧

从现在开始,请用 x- 作为自定义注解关键字的前缀。

这种解决方案的另一个好处是,您不必等到下一个 JSON Schema 版本发布。您今天就可以开始更新您的模式。 x- 关键字与当前发布的所有 JSON Schema 版本兼容;它们仍然会被收集为注解。当下一个版本发布时,您已经迁移了!

封面照片来自 Mick HauptUnsplash