SwaggerAs you know, Apicultur is built with API Manager, the Open Source solution by  WSO2 for managing and publishing APIs. This middleware solution offers a complete web application that allows developers to find, discover and subscribe to APIs, and allows publishers to make APIs publicly available adding security and service management.

Adding documentation that is easy to understand and read it’s an important step to API publishing. We decided to add Swagger documentation to the API Manager in Apicultur, as Swagger documentation  allows to test the API and gives clear insight into how the API responds to parameters and options without needing to subscribe first or getting into more detail. It’s a bit of “try this dish first and if you like it, I’ll tell you the recipe”. You can check out  the Swagger docs on Apicultur here.

Swagger allows to generate automatically the necessary files so that the  web client can show the documentation associated to the service (allowed verbs, URLs, parameters, types, descriptions, etc), but requires adding code and additional tagging while coding. However, if later on our web services are published through API Manager, the generated documentation won’t agree with the new enviroment, due to the difference in the endpoints between the original API and the published API. The only solution for this (or the only one we could think of) is only using the Swagger UI and generating the docs for each published API by hand.

Ejemplo de integración de Swagger en Apicultur (Api Manager)

Example of Swagger docs in Apicultur (API Manager)

 

In the following steps you can see how we added the Swagger doc to Apicultur.

Downloading Swagger UI

The Swagger UI can be found here  and it consists of an html, js y css.

Publishing the client in the API Store

We will place the files in the API Store. We access the following location:

<AM_HOME>/repository/deployment/server/jaggeryapps/store/site/themes/fancy/templetes

and we create a new folder called swagger, where we will place the downloaded files.

In our case, we decided to show the Swagger doc in the general info page of the API, in the overview tab. This is the template for this tab:

<AM_HOME>/repository/deployment/server/jaggeryapps/store/site/themes/fancy/templetes/api/overview/templete.jag

Here (where we choose to show the docs) we add the following HTML layers that are the ones Swagger will use to load the docs content.

<div id=”message-bar”>&nbsp;</div><div id=”swagger-ui-container”>

If our API Store works with http and https protocol, we’ll need to create a new variable in template.jag, called “discoveryUrl” where we will keep the value depending on the used protocol:

<%
var discoveryUrl;
if (request.isSecure()){
discoveryUrl = jagg.getMappedUrl("/site/pages/api-docs/"+ api.name + "-" + api.version +"/api-docs.json");
}else{
discoveryUrl = jagg.getMappedUrl("/site/pages/api-doc/"+ api.name + "-" + api.version +"/api-docs.json");
}
%>


We’ll descibe the usefulness of this variable later on.

In order to include all the necessary js and css we’ll access the initializer on the Overview page:

<AM_HOME>/repository/deployment/server/jaggeryapps/store/site/themes/fancy/templetes/api/overview/initializer.jag

In here, we have to add all the necessary js and css:


jagg.addHeaderJS("api/api-info", "api-info1", "templates/swagger/lib/jquery-1.8.0.min.js");
jagg.addHeaderJS("api/api-info", "api-info2", "templates/swagger/lib/jquery.slideto.min.js");
jagg.addHeaderJS("api/api-info", "api-info3", "templates/swagger/lib/jquery.wiggle.min.js");
jagg.addHeaderJS("api/api-info", "api-info4", "templates/swagger/lib/jquery.ba-bbq.min.js");
jagg.addHeaderJS("api/api-info", "api-info5", "templates/swagger/lib/handlebars-1.0.rc.1.js");
jagg.addHeaderJS("api/api-info", "api-info6", "templates/swagger/lib/underscore-min.js");
jagg.addHeaderJS("api/api-info", "api-info7", "templates/swagger/lib/backbone-min.js");
jagg.addHeaderJS("api/api-info", "api-info8", "templates/swagger/lib/swagger.js");
jagg.addHeaderJS("api/api-info", "api-info9", "templates/swagger/swagger-ui.js");
jagg.addHeaderCSS("api/api-info", "api-info10", "templates/swagger/css/screen.css");
jagg.addHeaderCSSCode("api/api-info", "api-info11", ".swagger-ui-wrap {max-width: 960px;margin-left: auto;margin-right: auto;}.icon-btn {cursor: pointer;}#message-bar {min-height: 30px;text-align: center;padding-top: 10px;}.message-success {color: #89BF04;}.message-fail {color: #cc0000;}");

In addition, we have to add a js made by hand. This js file must include the function that will be executed once the site is loaded and that will render the html code in order to show a nice-looking documentation.

<script type=”text/javascript”>

        $(function () {
            window.swaggerUi = new SwaggerUi({
                discoveryUrl:”<%=discoveryUrl%>”,
                dom_id:”swagger-ui-container”,
                supportHeaderParams: true,
                supportedSubmitMethods: [‘get’, ‘post’, ‘put’],
                onComplete: function(swaggerApi, swaggerUi){
                 if(console) {
                        console.log(“Loaded SwaggerUI”)
                        console.log(swaggerApi);
                        console.log(swaggerUi);
                    }
                },
                onFailure: function(data) {
                 if(console) {
                        console.log(“Unable to Load SwaggerUI”);
                        console.log(data);
                    }
                },
                docExpansion: “none”
            });
            window.swaggerUi.load();
        });
    </script>

We’ll explain now the values and attributes that have been modified in relation to the value that Swagger had by default:

  • supportHeaderParams: we changed the value to true so that Swagger could sent our application token from API Manager and therefore test the response of the API.
  • discoveryUrl: it carries the URL of the JSON file that contains the docs info that will be shown by the Swagger client.
  • headers: Here we add our application token if we want that users can not only see the documentation but also test the API by themselves.

Generating the docs for each API

In order to have and display the doc for every API without having to modify the internal code of the API Store, it suffices to follow the next steps:

Creating a directory to keep the docs

In the folder

<AM_HOME>/repository/deployment/server/jaggeryapps/store/site/pages

we’ll create two new folders called “api-docs”  and “api-doc”, where we’ll keep the files for each API depending of the protocol we are using (http, https). The content of these folders will be the same, although there are two minor details that must be taken into account and that we will explain later on.

Creating a directory for each API

For every API we want to document, we’ll create a subfolder called “NameAPI-Version” in the “api-docs” directory. For instance, if I have and API in the API Store called “BasicOperations” and its version is 1.0, he folder to be created is “BasicOperations-1.0”.

Inside of this folder we’ll place the necessary files:

  • api-docs.json: It’s the main file and contains links to the to the files of the different URLs.
  • archivoapi: It contains the doc for all the methods allowed by the URL, parameters, type, descriptions, etc.

For our “BasicOperation” API we would have the following api-docs.json:

{
"apiVersion":"1.0",
"swaggerVersion":"1.1",
"basePath":"https://mistoreapimanager:9443/site/pages/",
"apis":[
{
"path":"/api-docs/BasicOperations-1.0/add",
"description":"This methods add to number together"
},
{
"path":"/api-docs/BasicOperations-1.0/substract",
"description":"Substract one number from another"
}
]
}

In this example, we have two different URLs for the API, and therefore we’ll have two files in order to describe each of them (one for “add” and another for “substract”). We show how the “add” file would look like (the “substract” file would look alike with the necessary modifications).

For further info concerning these files please check API Declaration, Resource Listing, Parameters y Data Types .

File “add”:


{
"apiVersion":"1.0",
"swaggerVersion":"1.1",
"basePath":"https://mistoreapimanager:9443",
"resourcePath":"basicoperations/1.0/add",
"apis":[
{
"path":"basicoperations/1.0/add/{parameter1}/{parameter2}",
"description":"Adding operation",
"operations":[
{
"httpMethod":"GET",
"summary":"It adds to numbers",
"notes":"This API returns the result of adding the two parameters",
"responseClass":"Result",
"nickname":"getAdd",
"parameters":[
{
"name":"parameter1",
"description":"First number to be added",
"paramType":"path",
"required":true,
"allowMultiple":false,
"dataType":"long"
},
{
"name":"parameter2",
"description":"Second number to be added",
"paramType":"path",
"required":true,
"allowMultiple":false,
"dataType":"long"
}
],
"errorResponses":[
{
"code":401,
"reason":"Unauthorized"
}
]
}
]
}
],
"models":{
"Result":{
"id":"Result",
"properties":{
"result":{
"type":"long"
}
}
}
}
}

Creating the copy of each API for the other protocol

Once the doc for our API is done, we can copy the entire folder into the “api-doc” directory and change the content of the files inside, changing the protocols  in the URLs (and the port, if appropriate) from https to http. It will also be necessary to change the path from “/api-docs/”  to  “/api-doc/”.

Share →