如何从OpenAPI/Swagger模型定义中生成JSON示例?

18

我正在为一个具有OpenAPI(Swagger)定义的REST API构建模糊测试器。

我想要测试OpenAPI定义中的所有可用路径,生成数据以测试服务器,分析响应代码和内容,并验证响应是否符合API定义。

我正在寻找一种从模型定义中生成数据(JSON对象)的方法。

例如,给定以下模型:

...
"Pet": {
  "type": "object",
  "required": [
    "name",
    "photoUrls"
  ],
  "properties": {
    "id": {
      "type": "integer",
      "format": "int64"
    },
    "category": {
      "$ref": "#/definitions/Category"
    },
    "name": {
      "type": "string",
      "example": "doggie"
    },
    "photoUrls": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "tags": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/Tag"
      }
    },
    "status": {
      "type": "string",
      "description": "pet status in the store"
    }
  }
}

我想生成随机数据,得到类似这样的东西:

{
  "id": 0,
  "category": {
    "id": 0,
    "name": "string"
  },
  "name": "doggie",
  "photoUrls": [
    "string"
  ],
  "tags": [
    {
      "id": 0,
      "name": "string"
    }
  ],
  "status": "string"
}
3个回答

9

Swagger Inflector库专门为此目的提供了ExampleBuilder类。它可以从OpenAPI(Swagger)定义中的模型生成JSON、XML和YAML示例。

OpenAPI 2.0示例

要使用OpenAPI 2.0 (swagger: '2.0')定义,请使用Swagger Java库1.x版本。

import io.swagger.parser.SwaggerParser;
import io.swagger.models.*;
import io.swagger.inflector.examples.*;
import io.swagger.inflector.examples.models.Example;
import io.swagger.inflector.processors.JsonNodeExampleSerializer;
import io.swagger.util.Json;
import io.swagger.util.Yaml;
import java.util.Map;
import com.fasterxml.jackson.databind.module.SimpleModule;

...

// Load your OpenAPI/Swagger definition
Swagger swagger = new SwaggerParser().read("http://petstore.swagger.io/v2/swagger.json");

// Create an Example object for the Pet model
Map<String, Model> definitions = swagger.getDefinitions();
Model pet = definitions.get("Pet");
Example example = ExampleBuilder.fromModel("Pet", pet, definitions, new HashSet<String>());
// Another way:
// Example example = ExampleBuilder.fromProperty(new RefProperty("Pet"), swagger.getDefinitions());

// Configure example serializers
SimpleModule simpleModule = new SimpleModule().addSerializer(new JsonNodeExampleSerializer());
Json.mapper().registerModule(simpleModule);
Yaml.mapper().registerModule(simpleModule);

// Convert the Example object to string

// JSON example
String jsonExample = Json.pretty(example);
System.out.println(jsonExample);

// YAML example
String yamlExample = Yaml.pretty().writeValueAsString(example);
System.out.println(yamlExample);

// XML example (TODO: pretty-print it)
String xmlExample = new XmlExampleSerializer().serialize(example);
System.out.println(xmlExample);

OpenAPI 3.0 示例

若要查看 OpenAPI 3.0 的示例,请参阅此答案。您需要使用 Swagger Java 库的 2.x 版本,并适当更新导入和类名,例如将io.swagger.parser.SwaggerParser更改为io.swagger.v3.parser.OpenAPIV3Parser等。


2
这个像桃子一样好用,经过一年的寻找解决方案,我终于找到了它! - InCh
不幸的是,ExampleBuilder 在创建 JSON 输出中的字符串字段时不尊重 minLength 和 maxLength 属性(它总是将“string”放入字符串字段中)。这可能会导致“格式错误”的 JSON。您可以通过创建自己的 StringProperty 对象来解决此问题,但这有点违背了构建器的目的。 - Joman68
@Joman68,你可以在https://github.com/swagger-api/swagger-inflector/issues上开一个问题(或者更好的方式是提交一个PR)。作为一种解决方法,你可以修改你的API定义,为每个属性提供一个自定义的“example”,Inflector将使用这些示例。 - Helen
swagger-inflector 只在模式定义为简单和基本时才能工作。它不识别 oneOfanyOfallOf,也不处理使用 $ref 的任何引用,也不遵循任何 pattern - Tiina
1
@Tiina ExampleBuilder 支持 allOf$refoneOfanyOf。对于 oneOf/anyOf,它应该使用第一个子模式。如果您得到不正确/不完整的示例,请在 https://github.com/swagger-api/swagger-inflector/issues 上打开问题。请确保使用 https://editor.swagger.io 和/或其他验证器检查您的 OpenAPI 定义中的语法错误。您还可以通过为 API 定义中的某些模式/属性提供自己的 example 来解决 ExampleBuilder 的限制。 - Helen

3

我的经验:

  1. 前往http://editor.swagger.io
  2. 文件 -> 导入文件(加载自己的Swagger描述)
  3. 生成客户端 -> Java(在我的情况下)
  4. 下载并提取客户端
  5. 将其模型包导入到任何简单项目中,实例化并填充模型类所需的数据
  6. 将实例化的对象编组成JSON(在我的情况下使用Gson,因为生成的模型由Gson注释)
  7. 获利

简而言之:基于Swagger定义生成客户端(在我的情况下是java-client),填充其模型并编组结果。


1

只需要将您的模型放在https://json-schema-faker.js.org/中,即可开始。

您提供的架构可以直接使用,只需进行轻微修改:删除“宠物”,并添加“类别”和“标签”的定义。如下所示。

然后点击“生成”,即可获得虚假数据。如果您不想通过网站进行操作(我自己还没有尝试过),似乎所有这些都可以通过库以编程方式完成。

{
  "definitions": {
    "description": "making this up so all refs resolve",
    "Category": {
      "type": "string"
    },
    "Tag": {
      "type": "string"
    }
  },
  "comment": "From here on down, it's exactly the same as the OP schema",
  "type": "object",
  "required": [
    "name",
    "photoUrls"
  ],
  "properties": {
    "id": {
      "type": "integer",
      "format": "int64"
    },
    "category": {
      "$ref": "#/definitions/Category"
    },
    "name": {
      "type": "string",
      "example": "doggie"
    },
    "photoUrls": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "tags": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/Tag"
      }
    },
    "status": {
      "type": "string",
      "description": "pet status in the store"
    }
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接