V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
nausea
V2EX  ›  Node.js

什么是 JSON Schema?

  •  
  •   nausea · 2019-05-30 22:18:13 +08:00 · 5741 次点击
    这是一个创建于 2023 天前的主题,其中的信息可能已经有所发展或是发生改变。
    如果你曾经使用过 XML Schema,RelaxNG 或 ASN.1,那么你很可能已经知道什么是 JSON Schema,并且可以跳过本文的阅读。如果你是头一次听说,或者听过过这个词汇但不了解,那么你来对地方了。
    要了解 JSON Schema 是什么,我们应该首先了解 JSON 是什么。
    JSON 代表“ JavaScript Object Notation ”,一种简单的互联网数据交换格式。由于 JavaScript 存在于绝大多数 Web 浏览器中,而 JSON 基于 JavaScript 而来,因此很容易在 JavaScript 中的得到支持。同时,它已被证明足够有用且足够简单,现在也被用于许多其他不涉及互联网数据交换的环境中。
    从本质上讲,JSON 建立在以下数据结构上:
    对象:
    { "key1": "value1", "key2": "value2" }
    数组:
    [ "first", "second", "third" ]
    数值:
    42 3.1415926
    字符串:
    "This is a string"
    布尔:
    true false
    空值:
    null
    以上这些类型在大多数编程语言中都有接近的对照类型,但它们可能有不同的名称。
    利用这些简单的数据类型,可以表示出各种结构化数据。然而,这种巨大的灵活性带来了巨大的责任,因为同样的概念可以用无数种方式表现出来。例如,你可以想象以不同方式表示有关 JSON 中某人的信息:
    {
    "name": "George Washington",
    "birthday": "February 22, 1732",
    "address": "Mount Vernon, Virginia, United States"
    }
    以及:
    {
    "first_name": "George",
    "last_name": "Washington",
    "birthday": "1732-02-22",
    "address": {
    "street_address": "3200 Mount Vernon Memorial Highway",
    "city": "Mount Vernon",
    "state": "Virginia",
    "country": "United States"
    }
    }
    以上这两种表述同样有效,但第二种显然比第一种更正式。数据记录的设计在很大程度上取决于其在应用程序中的预期用途,因此这里没有正确或错误的答案。但是,当应用程序通过 API 请求并期望得到一个人的 JSON 记录时,重要的是要确切知道该记录应该如何组织。也就是说,当我们需要知道 JSON 数据中预期的字段以及值的表示方式时,这就是 JSON Schema 的用武之地。
    以下 JSON Schema 片段描述了上面第二个例子是如何构建的。这里我们不对其中的细节解释,但如果仔细观察,你可以看到,以上第二个例子中的 JSON 数据结构,以及其中各个字段的类型信息在这里得到了很清晰的说明。
    {
    "type": "object",
    "properties": {
    "first_name": {
    "type": "string"
    },
    "last_name": {
    "type": "string"
    },
    "birthday": {
    "type": "string",
    "format": "date"
    },
    "address": {
    "type": "object",
    "properties": {
    "street_address": {
    "type": "string"
    },
    "city": {
    "type": "string"
    },
    "state": {
    "type": "string"
    },
    "country": {
    "type": "string"
    }
    }
    }
    }
    }
    通过“验证”针对此 JSON Schema 的第一个示例 JSON 数据,您可以看到它失败:
    {
    "name": "George Washington",
    "birthday": "February 22, 1732",
    "address": "Mount Vernon, Virginia, United States"
    }
    但是,第二个例子通过:
    {
    "first_name": "George",
    "last_name": "Washington",
    "birthday": "22-02-1732",
    "address": {
    "street_address": "3200 Mount Vernon Memorial Highway",
    "city": "Mount Vernon",
    "state": "Virginia",
    "country": "United States"
    }
    }
    您可能已经注意到,JSON Schema 本身是用 JSON 编写的。它是 JSON 数据的规范,而不是计算机程序。它只是“描述 JSON 数据结构”的声明格式。这既是它的优势,也是它的弱点(和其他 Schema 语言类似)。它很容易简洁地描述数据的表面结构,并可被用于在程序运行时自动验证数据。但是,由于 JSON Schema 不能包含任意代码,因此对无法表达的数据元素之间的关系存在某些限制。因此,对于足够复杂的数据格式的任何“验证工具”可能具有两个验证阶段:一个在结构级别,另一个在语义级别。对于结构级别的检查,可以使用 Schema 语言。对于语义级别的检查,可能需要使用更通用的编程语言来实现。
    JSON Schema 在 API 的设计与实现中具有相当重要的作用。具备 JSON Schema 校验能力的 API 实现可以帮助对来自用户输入数据的自动校验,以及应用在各类需要在程序运行时完成校验的场景中。这可以帮助开发者以更加规范、严谨的方式来描述自己的 API 上承载的 JSON 数据,同时少写许多手工校验的程序代码。
    遗憾的是,目前流行的 REST API 设计并不能直接使用 JSON Schema 带来的这种能力,这很大程度上在于,在 REST API 的设计理念中,API 请求的参数并不是一个 JSON 对象,而是以资源模型的方式来描述,这使得无法使用 JSON Schema 来描述和自动校验这类 API 上传递的数据。
    在灵长科技 CEAMS 通用企业应用接口管理系统上,系统并没有使用 REST API 的设计风格,而是参考了经典的 SOAP 协议设计,规定 API 的请求参数和返回结果必须是一个 JSON 对象或者数组,并且为开发者提供了包含 JSON Schema 支持的 API 规范设计向导,用户可以很方便地在这里设计和制定自己 API 上的 JSON 数据规范。同时,设计好的 JSON Schema 将在程序执行时,完成对请求和返回结果 JSON 数据的校验,帮助提高了 API 数据的安全性,并且避免了手写校验代码的繁琐。
    除了用于完成 JSON 数据校验外,由于可以为 JSON 数据提供清晰、严谨的声明,JSON Schema 在自动化 API 文档、自动化输入表单生成、JSON 数据可视化等方面也有很好的应用场景。有不少开源项目提供了基于 JSON Schema 的自动化输入表单生成能力。CEAMS 系统集成了其中知名的 Angular Schema Form,用于为开发者提供的清晰、直观的 API 测试工具。这样的工具帮助开发者进一步简化了 API 测试的过程,提高了测试的效率。
    11 条回复    2019-06-04 14:14:44 +08:00
    changwei
        1
    changwei  
       2019-05-31 05:28:00 +08:00
    看到倒数第二段我终于发现这是一篇软文了
    luozic
        2
    luozic  
       2019-05-31 06:25:20 +08:00 via iPhone
    yaml toml swagger 不比这个牛逼?
    zpf124
        3
    zpf124  
       2019-05-31 09:15:51 +08:00
    json 的特点不就是简单和灵活性高么?

    写 Schema 了 那和 xml 有什么区别吗?

    Restful 替代了 webService 之后, 自己又变成了 webService? 我们终将变成自己讨厌的样子?
    Raisu
        4
    Raisu  
       2019-05-31 09:42:03 +08:00
    2333 这代码格式谁看啊
    www5070504
        5
    www5070504  
       2019-05-31 11:18:09 +08:00
    @zpf124 做请求数据验证还挺好用的 避免别人调你的 api 给你传一堆不符合预设的数据。。
    www5070504
        6
    www5070504  
       2019-05-31 11:18:46 +08:00
    json schema 这玩意我以为普及度很高呢。。 不是早就有了么 跟你软文里边的公司有啥关系 没 get 到你的宣传点
    nausea
        7
    nausea  
    OP
       2019-06-03 00:03:48 +08:00
    @www5070504 这样就可以搞成一个 soap 了,相当于建立了一个 api 的规范,于是在经过系统后的不同 api 之间可以方便的实现联动,提高效率。
    nausea
        8
    nausea  
    OP
       2019-06-03 21:26:16 +08:00
    @luozic swagger 对 json schema 的支持是不完整的。yaml 能代替 json 吗?
    nausea
        9
    nausea  
    OP
       2019-06-03 21:27:15 +08:00
    @zpf124 现在有多少 API 是真正 RESTful 的?都是在挂羊头卖狗肉:)
    nausea
        10
    nausea  
    OP
       2019-06-03 21:29:12 +08:00
    @www5070504 json schema 是早有了。但是 json 版的 WSDL 和 SOAP 我们是第一家。建议联系一下目前乱七八糟的各种 API 风格,仔细想想这里的区别,为什么只有我们才能做到,schema 的作用是非常非常犀利的!
    azh7138m
        11
    azh7138m  
       2019-06-04 14:14:44 +08:00
    @luozic json yaml toml 只是载体,谁都可以承载这个 schema。
    swagger 只是使用了 json schema。
    json schema 是描述类型的一个事实标准。众多编辑器 /IDE 默认支持使用 json schema 来描述类型。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1660 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 16:30 · PVG 00:30 · LAX 08:30 · JFK 11:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.