Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can one split API documentation in multiple files using Swagger 2.0

Tags:

swagger

According to Swagger 2.0 specs, it might be possible to do this. I am referencing PathObject using $ref which points to another file. We used to be able to do this nicely using Swagger 1.2. But Swagger-UI does not seem to be able to read the referred PathObject in another file.

Is this part of spec too new and is not yet supported? Is there a way to split each "path"'s documentation into another file?

{
    "swagger": "2.0",
    "basePath": "/rest/json",
    "schemes": [
        "http",
        "https"
    ],
    "info": {
        "title": "REST APIs",
        "description": "desc",
        "version": "1.0"
    },
    "paths": {
        "/time": {
            "$ref": "anotherfile.json"
        }
    }
}
like image 641
k2k2e6 Avatar asked Nov 25 '25 15:11

k2k2e6


1 Answers

To support multiple files, your libraries have to support dereferencing the $ref field. But I would not recommend to deliver the swagger file with unresolved references. Our swagger defintion has around 30-40 files. Delivering them via HTTP/1.1 could slow down any reading application.

Since we are building javascript libs, too, we already had a nodejs based build system using gulp. For the node package manager (npm) you can find some libraries supporting dereferencing to build one big swagger file.

Our base file looks like this (shortened):

swagger: '2.0'
info:
  version: 2.0.0
  title: App
  description: Example
basePath: /api/2
paths:
  $ref: "routes.json"
definitions:
  example:
    $ref: "schema/example.json"

The routes.json is generated from our routing file. For this we use a gulp target implementing swagger-jsdoc like this:

var gulp = require('gulp');
var fs   = require('fs');
var gutil = require('gulp-util');
var swaggerJSDoc = require('swagger-jsdoc');

gulp.task('routes-swagger', [], function (done) {
    var options = {
        swaggerDefinition: {
            info: {
                title: 'Routes only, do not use, only for reference',
                version: '1.0.0',
            },
        },
        apis: ['./routing.php'], // Path to the API docs
    };
    var swaggerSpec = swaggerJSDoc(options);
    fs.writeFile('public/doc/routes.json', JSON.stringify(swaggerSpec.paths, null, "\t"), function (error) {
        if (error) {
            gutil.log(gutil.colors.red(error));
        } else {
            gutil.log(gutil.colors.green("Succesfully generated routes include."));
            done();
        }
    });
});

And for generating the swagger file, we use a build task implementing SwaggerParser like this:

var gulp = require('gulp');
var bootprint = require('bootprint');
var bootprintSwagger = require('bootprint-swagger');
var SwaggerParser = require('swagger-parser');
var gutil = require('gulp-util');
var fs   = require('fs');

gulp.task('swagger', ['routes-swagger'], function () {
    SwaggerParser.bundle('public/doc/swagger.yaml', {
        "cache": {
            "fs": false
        }
    })
    .then(function(api) {
        fs.writeFile('public/doc/swagger.json', JSON.stringify(api, null, "\t"), function (error) {
            if (error) {
                gutil.log(gutil.colors.red(error));
            } else {
                gutil.log("Bundled API %s, Version: %s", gutil.colors.magenta(api.info.title), api.info.version);
            }
        });
    })
    .catch(function(err) {
        gutil.log(gutil.colors.red.bold(err));
    });
});

With this implementation we can maintain a rather large swagger specification and we are not restricted to special programming language or framework implementation, since we define the paths in the comments to the real routing definitions. (Note: The gulp tasks are split in multiple files too.)

like image 102
Trendfischer Avatar answered Nov 28 '25 06:11

Trendfischer