2022 年 7 月 15 日,星期五 ·5分钟阅读

JSON Schema 的架构范围

最近,我进行了一些对话,让我开始思考 JSON Schema 在架构上的位置。今天我想分享一些想法。

什么是 JSON Schema?

JSON Schema 是一种规范,定义了一种机制来描述 JSON 值,可用于验证和注释该值。此机制组织成多个关键字,每个关键字都提供定义的行为。

一组关键字构成一个“模式”。

此系统接收一个模式作为输入,该模式本身可以用 JSON 值表示,以及一个 JSON 值(我们称之为“实例”),模式中的规则将应用于该值。为了便于理解,我们将这些规则的应用称为“评估”。(即,模式“评估”实例。)

评估的输出是每个规则的单个错误和/或注释的聚合。

但是,一般来说,行为系统有些抽象,因此在实践中并不实用。我们需要的是这个系统在代码中的实现。我们需要的是实现。

使 JSON Schema 有用

在使 JSON Schema 有用之前,我们需要问它应该对谁有用。为了回答这个问题,我们需要知道 JSON Schema 存在的理由。

嗯,我们在上一节中讨论过:模式评估实例以确保实例符合模式中表示的所有规则。如果实例符合模式中的规则,那么我们说它相对于该模式是“有效的”。

确保拥有有效 JSON 数据的原因可能很多:在反序列化到程序模型之前检查数据,在提交之前检查表单输入等。这些都是应用程序的需求。

所以应用程序是 JSON Schema 的消费者。

但是注释呢?嗯,注释专门用于应用程序,以便它们可以提供其他行为。因此,是的,应用程序仍然是这里的消费者。

但是应用程序无法在没有将规范实现到代码的情况下使用规范。这就是实现发挥作用的地方。

JSON Schema 的实现是规范的具象体现,可直接供应用程序使用。

细微差别

我最近经常看到,我认为在我的讨论中产生的一些混乱的根源是,应用程序可能仅仅是实现周围的可执行包装器。这往往会让人觉得应用程序本身就是实现,在这种情况下,应用程序将受规范要求的约束。但我并不这么认为。即使在这些情况下,应用程序和实现之间也存在区别,即使这种区别在实践中非常模糊。

注意重要的是要认识到这种区别实际上是模糊的。目前,这是一个公开讨论的话题,在该领域还没有正式定义。

应用程序通常具有三个基本组件:接口(用户体验或 API)、一些业务逻辑和数据持久性。所有应用程序都具有接口。但是,业务逻辑和数据持久性组件在一定程度上是可选的,因为您可以拥有其中一个、另一个或两个。(只有用户体验的应用程序通常没什么用。)

应用程序可能只提供数据持久性上的接口(例如,PostgreSQL Web 服务),这意味着不需要任何业务逻辑。相反,另一个应用程序可能提供计算服务(例如,图像处理),其中不需要持久化数据。

对于我最近进行的对话,这种情况似乎是第二个:创建一个应用程序,它只是根据模式评估实例。但这并不意味着应用程序和实现是同一个东西。

在这些应用程序中,实现(对于这些应用程序来说,它业务逻辑)仍然是与接口分离的组件。重要的是要认识到,作为规范的 JSON Schema 只能涵盖实现部分。

为什么这些很重要

这一切都回到我在开头提到的内容:JSON Schema 需要定义输入和输出。这包括一个最小 API,实现和应用程序可以使用它相互通信。

当实现和应用程序之间的界限模糊时,很自然地认为规范正在对应用程序如何与其用户通信施加要求。但事实并非如此。

JSON Schema 不可能知道应用程序用户的需求,因此,规范试图定义应用程序必须遵守的输入和输出要求是不切实际的。

不同应用程序的用户有不同的需求。即使您考虑两个基本上只提供实现用户体验的应用程序,比如 Web 应用程序和 CLI,它们的用户体验需求也大不相同,尽管这两个应用程序基本上做着相同的事情。

规范的范围

根据以上所有讨论,可以得出结论,规范的输入和输出要求仅适用于应用程序和 JSON Schema 实现之间存在明确通信缝隙的情况。

该规范认识到,编程语言和框架可能不会处理文本 JSON,而是会使用在该语言限制内定义的数据模型。因此,它以抽象 JSON 数据和 JSON Schema 模型的形式定义输入和输出,以便实现可以自由使用它们拥有的资源。

具体来说,这些要求只适用于作为 JSON Schema 规范的通用表示形式提供的独立实现,这些实现将被未知方使用。

具有集成实现或应用程序/实现对的应用程序,这些应用程序/实现对具有专门的契约,无需遵守这些要求,因为这些安排超出了规范的范围。

封面照片由我拍摄 😁