How to break swagger 2.0 JSON file into multiple m

2019-01-30 03:28发布

I'm trying to break my API document up into multiple JSON files that can be edited independently. All the examples I've been able to find use the Swagger 1.2 schema which has a "api":{} object for breaking it down. That appears to be missing from the 2.0 schema (http://json.schemastore.org/swagger-2.0). All that defines is a single "paths" array where it bundles all the API endpoints into that single array. The effect of this in the swagger-ui is there is a single "default" category that everything gets bundled into and no way that I can tell to split it up.

TLDR: How do you split operations from paths in the swagger 2.0 schema

{
  "swagger": "2.0",
  "info": {
    "description": "My API",
    "version": "1.0.0",
    "title": "My API",
    "termsOfService": "http://www.domain.com",
    "contact": {
      "name": "support@domain.com"
    }
  },
  "basePath": "/",
  "schemes": [
    "http"
  ],
  "paths": {
    "Authorization/LoginAPI": {
      "post": {
        "summary": "Authenticates you to the system and produces a session token that will be used for future calls",
        "description": "",
        "operationId": "LoginAPI",
        "consumes": [
          "application/x-www-form-urlencoded"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [{
          "in": "formData",
          "name": "UserName",
          "description": "Login Username",
          "required": true,
          "type": "string"

        }, {
          "in": "formData",
          "name": "Password",
          "description": "Password",
          "required": true,
          "type": "string"

        }],
        "responses": {
          "200": {
            "description": "API Response with session ID if login is allowed",
            "schema": {
              "$ref": "#/definitions/Authorization"
            }
          }
        }
      }
    }
  }
}

7条回答
我只想做你的唯一
2楼-- · 2019-01-30 03:47

Note that RepreZen API Studio now supports multi-file Swagger/Open API projects via the $ref syntax discussed here. So you can break up large Swagger projects into modules to enable re-use and team collaboration. You can then use the built-in Swagger normalizer to create a single, consolidated Swagger file when you need to take your API model outiside the design/development environment.

Note: in the interests of full disclosure, I am Product Manager at RepreZen. I stumbled across this thread last week and thought I'd chip in.

查看更多
放我归山
3楼-- · 2019-01-30 03:47

I'm trying to figure this out as well, and there's some useful info in the Swagger Google group. It looks like the consensus is that you can break the definitions out into separate files as long as the $ref is pointing to an absolute url. Example here:

https://github.com/swagger-api/swagger-spec/blob/master/fixtures/v2.0/json/resources/resourceWithLinkedDefinitions.json#L32

https://github.com/swagger-api/swagger-spec/blob/master/fixtures/v2.0/json/resources/resourceWithLinkedDefinitions_part1.json

查看更多
乱世女痞
4楼-- · 2019-01-30 03:48

I wrote a Swagger/OpenAPI preprocessor to ease authoring of specifications.

https://github.com/dolmen-go/openapi-preprocessor/

In particular it supports $ref pointing to external files and allows to edit your spec as multiple files, but produce a single file for maximum compatibility with tools that will consume it.

查看更多
闹够了就滚
5楼-- · 2019-01-30 03:49

You actually ask several questions in one, and I'll try answering them all.

In Swagger 1.2 and prior to it, the file splitting was mandatory and artificial. It was meant as a way to group operations, and Swagger 2.0 offers and alternative method to do that (more on it soon).

Swagger 2.0 is indeed a single file, which allows for external files wherever $ref is used. You cannot split a single service into several files and combine them as one, but you can specify operations for specific paths externally (again, using the $ref property).

We're currently in the process of finalizing the ability to collate several micro-services into a single collection, but eventually, each micro-service is still going to be a single file.

As mentioned, the grouping of operations in Swagger 2.0 has changed, and the concept of a 'resource' no longer exists. Instead, there are tags (with the "tags" property) which can be assigned per operation. The tags is an array of values, and unlike previous versions, each operation can exist under multiple tags if needed. In Swagger-UI, all operations that have no tags defined will end up under the default tag, which is the behavior you've seen. There's an additional tags property at the top-level object that allows you to add descriptions to tags and set their order, but it is not mandatory to include it.

As a final note, I have no idea how the json-schema of Swagger 2.0 ended up in http://json.schemastore.org/swagger-2.0 but it is certainly not up to date. The most up-to-date schema can be found here - http://swagger.io/v2/schema.json - and it is still under development. Keep in mind that the source of truth is the spec (https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md) and not the schema, so in case of conflicts, the spec 'wins'.

Edit:

We just published a guide on referencing. It may help with some use cases - https://github.com/OAI/OpenAPI-Specification/blob/master/guidelines/v2.0/REUSE.md

查看更多
祖国的老花朵
6楼-- · 2019-01-30 03:50

I've written about this in this blog post. You can basically use JSON Refs library to resolve all your little Swagger files into one large one and use it in the tools.

查看更多
劫难
7楼-- · 2019-01-30 03:50

If JSON ref's didn't work for you, it might be useful to write your own concatenator. Well, instead of writing your own you can actually use something that is already out there. Any templating engine will do. In my case Handlebars turned out to be very helpful (because Handlebars actually preserves indentation, which is perfect for Yaml files since they are case sensitive).

Then you can have a build script in Node:

'use strict';

var hbs = require('handlebars');
var fs  = require('fs');

var dir = __dirname + '/your_api_dir';

var files = fs.readdirSync(dir);

files.forEach((fileName) => {
  var raw = fs.readFileSync(dir + '/' + fileName, 'utf8');
  hbs.registerPartial(file, raw);
});

var index = fs.readFileSync(dir + '/index.yaml');

var out = hbs.compile(index.toString());

Read more regarding the issue on my blog.

查看更多
登录 后发表回答