【问题标题】:Convert JSON to JSON Schema draft 4 compatible with Swagger 2.0将 JSON 转换为与 Swagger 2.0 兼容的 JSON Schema 草案 4
【发布时间】:2016-12-01 10:29:03
【问题描述】:

我收到了一些由具有大量属性的 REST API 生成的 JSON 文件。

我为此 API 创建了 Swagger 2.0 定义,需要为其提供相应的响应架构。

主要问题:这个 JSON 文件有很多属性。如果我手动编写模式,这将花费很多时间,而且我会犯很多错误。这不是我需要描述的唯一 API。

我知道有一些工具可以将 JSON 转换为 JSON 模式,但是,如果我没记错的话,Swagger 只有 $refs 到其他对象定义,因此只有一个级别,而我发现的工具只产生树结构模式. 我的问题:是否有任何工具可以将 JSON(或 JSON Schema)转换为与 Swagger 2.0 兼容的工具?

注意:我正在使用 YAML,但我不会成为问题,不是吗?

例如,我需要什么:

  List of Movements:
    type: "array"
    items:
      $ref: "#/definitions/Movement"
  Movement:
    properties:
      dateKey:
        type: "string"
      movement:
        $ref: "#/definitions/Stock"
    additionalProperties: false
  Stock:
    properties:
      stkUnitQty:
        type: "string"
      stkDateTime:
        type: "string"
      stkUnitType:
        type: "string"
      stkOpKey:
        type: "string"
    additionalProperties: false

对于我的 JSON 文档:

[
  {
    "dateKey": "20161110",
    "stkLvls": [
      {
        "stkOpKey": "0",
        "stkUnitType": "U",
        "stkDateTime": "20161110T235010.240+0100",
        "stkUnitQty": 30
      }
    ]
  },
  {
    "dateKey": "20161111",
    "stkLvls": [
      {
        "stkOpKey": "0",
        "stkUnitType": "U",
        "stkDateTime": "20161111T231245.087+0100",
        "stkUnitQty": 21
      }
    ]
  }
  ]

但是,http://jsonschema.net/#/ 给了我什么:

---
"$schema": http://json-schema.org/draft-04/schema#
type: array
items:
  type: object
  properties:
    dateKey:
      type: string
    stkLvls:
      type: array
      items:
        type: object
        properties:
          stkOpKey:
            type: string
          stkUnitType:
            type: string
          stkDateTime:
            type: string
          stkUnitQty:
            type: integer
        required:
        - stkOpKey
        - stkUnitType
        - stkDateTime
        - stkUnitQty
  required:
  - dateKey
  - stkLvls

我是新手,但很好奇,请不要犹豫深入解释。

提前感谢您的帮助!

【问题讨论】:

    标签: json swagger jsonschema swagger-2.0


    【解决方案1】:

    我还需要一个转换器工具,但遇到了这个。到目前为止,它似乎工作得很好。它同时支持 JSON 和 YAML 格式。

    https://swagger-toolbox.firebaseapp.com/

    鉴于此 JSON(他们的示例):

    {
      "id": 1,
      "name": "A green door",
      "price": 12,
      "testBool": false,
      "tags": [
        "home",
        "green"
      ]
    }
    

    它生成了这个:

    {
        "required": [
            "id",
            "name",
            "price",
            "testBool",
            "tags"
        ],
        "properties": {
            "id": {
                "type": "number"
            },
            "name": {
                "type": "string"
            },
            "price": {
                "type": "number"
            },
            "testBool": {
                "type": "boolean"
            },
            "tags": {
                "type": "array",
                "items": {
                    "type": "string"
                }
            }
        }
    }
    

    【讨论】:

    • Mateuscb 是否有任何可用的 java 库可以将 Json Schema 转换为 Json 对象...
    • @VishwaPratap 我不确定。我还没有出现过。
    【解决方案2】:

    我知道有一些工具可以将 JSON 转换为 JSON 模式,但是,如果 我没记错,Swagger 只有 $refs 到其他对象定义 因此只有一层

    你错了。 Swagger 将尊重任何有效的 v4 JSON 模式,只要它只使用 supported subset

    模式对象...基于 JSON 模式规范草案 4 和 使用它的预定义子集。在这个子集之上,本规范提供了一些扩展,以允许更完整 文档。

    接着列出了 JSON 模式中支持的部分,不支持的位,以及被 swagger 扩展的位。

    【讨论】:

    • 嗨,汤姆,谢谢您的回答。在github.com/OAI/OpenAPI-Specification/blob/master/examples/v2.0/… 上,我可以看到定义标记处只有一层。当需要使用其他类型时,他们会为其他类型创建一个 $ref: '#/definitions/Activity'。但在 JSON Schema v4 中,它不是强制性的。有什么解决办法吗?
    • @tom redgen 是否有任何可用的 java 库可以将 Json Schema 转换为 Json 对象...
    【解决方案3】:

    您可以直接转到https://bikcrum.github.io/Swagger-JSON-Schema-In-YAML_webversion/进行在线转换。

    我编写了以下 python 脚本来生成在 Swagger 中使用的 YAML 格式(保留键顺序)的 JSON 模式。

    import json
    
    # input file containing json file
    with open('data.json') as f:
        json_data = json.load(f)
    
    # json schema in yaml format
    out = open('out.yaml','w')
    
    def gettype(type):
        for i in ['string','boolean','integer']:
            if type in i:
                return i
        return type
    
    def write(string):
        print(string)
        out.write(string+'\n')
        out.flush()
    
    def parser(json_data,indent):
        if type(json_data) is dict:
            write(indent + 'type: object')
            if len(json_data) > 0:
                write(indent + 'properties:')
            for key in json_data:
                write(indent + '  %s:' % key)
                parser(json_data[key], indent+'    ')
        elif type(json_data) is list:
            write(indent + 'type: array')
            write(indent + 'items:')
            if len(json_data) != 0:
                parser(json_data[0], indent+'  ')
            else:
                write(indent + '  type: object')
        else:
            write(indent + 'type: %s' % gettype(type(json_data).__name__))
    
    parser(json_data,'')
    

    更新:如果您想要带有排序键的 YAML(默认情况下),请使用 YAML 库

    import json
    import yaml
    
    # input file containing json file
    with open('data.json') as f:
        json_data = json.load(f)
    
    # json schema in yaml format
    
    def gettype(type):
        for i in ['string','boolean','integer']:
            if type in i:
                return i
        return type   
    
    def parser(json_data):
        d = {}
        if type(json_data) is dict:
            d['type'] = 'object'
            for key in json_data:
                d[key] = parser(json_data[key])
            return d
        elif type(json_data) is list:
            d['type'] = 'array'
            if len(json_data) != 0:
                d['items'] = parser(json_data[0])
            else:
                d['items'] = 'object'
            return d
        else:
            d['type'] = gettype(type(json_data).__name__)
            return d
    
    p = parser(json_data)
    with open('out.yaml','w') as outfile:
        yaml.dump(p,outfile, default_flow_style=False)
    

    【讨论】:

    • 我假设您打算使用indent 而不是intend。根据我的经验,最好使用一个整数作为缩进级别,并在最晚的可能时刻执行' ' * indent(这是一个由两个空格组成的字符串)。这样,如果您想要四个空格缩进,则只有一个地方可以更改。 (如果您使用 YAML 库,则不必首先跟踪缩进级别)。为什么要导入pprint?考虑使用isinstance(var, dict) 而不是type(var) is dict
    • @Authon 感谢您的建议。我已将更新放在 YAML 库用于从 JSON 转换为 YAML 但不会保留密钥顺序的位置。如果保留键顺序很重要,请考虑实现手动缩进的第一个代码块。
    • 如果您需要保留键的顺序,请使用 ruamel.yaml。(我是那个包的作者):而不是 import yamlimport ruamel.yaml。代替d = {} 执行d = ruamel.yaml.comments.CommentedMap() 并将dump(...) 行更改为两行:yaml = ruamel.yaml.YAML()yaml.dump(p, outfile)。那应该保持排序和块样式。如果你不能让它工作在这里发布一个问题并标记它yamlruamel.yaml,那么我会看到它
    • 那个链接正是我要找的!后来差不多 2000 行 Swagger 代码。希望我早点找到它:(但是非常感谢!
    • @bikram 是否有任何可用的 java 库可以将 Json Schema 转换为 Json 对象...
    猜你喜欢
    • 1970-01-01
    • 2018-03-24
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 2013-09-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-13
    相关资源
    最近更新 更多