Showing posts with label Swagger. Show all posts
Showing posts with label Swagger. Show all posts

Friday, September 16, 2016

Use Swagger UI for showing interactive API documentation

Following Swagger post I showed how to configure Swagger with Spring project. In this blog I will demonstrate using Swagger UI for showing interactive documentation.

Swagger UI is part of the Swagger project and it allows you to generate, visualize and consume API. It is package which basically consist of html, css and javascript, and parses the json output generated from application code scanning. This scanning and configuration was explained in following post.


Swagger UI Setup can be downloaded from "here".


Copy the files to a Dynamic Web project in eclipse and paste the content from "dist" folder to WebContent as shown below.





Here I am using tomcat server to host this UI application. By doing so it will be easy to share the API application with other user. It shows following UI. 


Please note that by default swagger will load the petstore Api details. I will cover customizing them in next point. 




Swagger UI presents very nice interactive tool, using which users can read the documentation, can see the exposed API, detailed input and output parameter, also they can test the API real time. This tool present by parsing the json output which was generated while scanning the API project. 


Above UI shows all the available API exposed in petstore application, method type supported and some basic details at top level. 

You can see entire API details after expanding the service  by clicking on the link. 
Below "/store/inventory" API has been expanded and you can see description of this API, what is response code returned when successful, at the last of the section you can see "Try it Out!" button, using which you can test the API. 

Response from the API will be shown in the same section below the button.

 


By default Swagger UI shows details pet store API, now if you want your custom build API to be listed, then few changes needs to be done in the above setup. Below I am going to explain the steps which needs to be done to customize the output.

  • Ensure that application is completed with the swagger setup and json output is accessible when you access following url, "http://localhost:9081/SpringSwaggerDemo/v2/api-docs", this is the url for the sample api application  which i created, you need to change it as per your setup, but last part of URL remain same i.e. "/v2/api-docs".
  • To load api documentation in the Swagger UI enter the above url in test field provided in top header section and press on "Explore" button.
  • Application will parse json and it will display the content in below section. This temporary loads you custom API details.
  • This url change will not be persisted in the UI code if you refresh the page it will be lost, so to persist the url change you need to modify the script code as shown below.
  • Locate index.html file, open with editor do following changes. modify the url value to you API url as shown below. After this change launch the UI again, you will see by default application loads the API details.
  var url = window.location.search.match(/url=([^&]+)/);
  if (url && url.length > 1) {
     url = decodeURIComponent(url[1]);
  } else {
      //url = "http://petstore.swagger.io/v2/swagger.json"; // change this value to your API json url. 
      url="http://localhost:9081/SpringSwaggerDemo/v2/api-docs";
  }
  • Check below UI where it shows the custom API details.



  • Next I will explain some more customization's related to language and UI.
  • Different Language support.
    • Swagger support showing UI menu in different languages. To enable this change index.html file needs to be modified and you need to add following script files. These files comes with the package which you downloaded. Locate "lang" folder inside the project, you will find different language files which by default comes with package. If you need to enable French language, so following code needs to be added in the index.html file. 
  <script src="lang/translator.js" type="text/javascript"></script>
  <script src="lang/fr.js" type="text/javascript"></script>
    • By default basic menu and other controls of Swagger UI will be converted to french language. Incase you have any other language for which file is not present then you need to create that file and place it inside this folder and include it in the html file.
  • UI Customization
    • Swagger UI can be customized and configured as per the organization and individual needs and requirements.
    • Entire source code is provided, so any modification can be easily done. Generally following are the section in UI which needs to be modified like Header, Logo, Color theme, etc.
    • To change the logo change the images inside "img" folder.
    • To apply new css, modify the css or override by putting new css file which extends the style provided by swagger.
    • To modify parsing logic and other logic modify js file inside lib folder.
    • Below is one sample changes to UI I have done. You can see the difference between above UI and the modified UI.


I hope this will be helpful post for people looking to use swagger as API documentation tool using Swagger UI. This post will help you kick starting the process.


Share your feedback.



Monday, September 12, 2016

Swagger API doc for Spring Based Webservices

When any API is created one of the major challenge is to create documentation, also once documentation is created then updating it over the period of time for any changes which are done in API.

In this blog I will be demonstrating how to create API documentation for REST webservices using Swagger tool.

Swagger is very mature API doc creation tools. It provides interactive documentation with very good ecosystem like Swagger UI, Swagger Editor.
Swagger is intelligent enough to scan through the code automatically and it generates am output which are easily readable by human and even system.

In this blog i will be showing swagger integration with Spring based rest webservices(bottom up).

Prerequisite for this blog is that you have Spring API project created and working.
  • To start first download following jar files and add them in your project.
  1. aopalliance-1.0.jar
  2. aspectjrt-1.8.6.jar
  3. aspectjweaver-1.8.6.jar
  4. classmate-1.2.0.jar
  5. guava-18.0.jar
  6. mapstruct-1.0.0.CR1.jar
  7. spring-hateoas-0.18.0.RELEASE.jar
  8. spring-plugin-core-1.2.0.RELEASE.jar
  9. spring-plugin-metadata-1.2.0.RELEASE.jar
  10. springfox-core-2.2.2.jar
  11. springfox-schema-2.2.2.jar
  12. springfox-spi-2.2.2.jar
  13. springfox-spring-web-2.2.2.jar
  14. springfox-swagger-common-2.2.2.jar
  15. springfox-swagger2-2.2.2.jar
  16. swagger-annotations-1.5.3.jar
  17. swagger-models-1.5.3.jar
  • Next will be to add Swagger Config java file, this is the file which is responsible for loading swagger config, specifying the url which needs to be scanned, basic API details.
Here is the sample code.
package com.swagger.apidoc;

import static com.google.common.base.Predicates.or;
import static springfox.documentation.builders.PathSelectors.regex;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.google.common.base.Predicate;

import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfig {
 @Bean
 public Docket api() {
  return new Docket(DocumentationType.SWAGGER_2).select()
    .apis(RequestHandlerSelectors.any())
    .paths(paths())
    .build()
    .apiInfo(getApiInfo());
 }
 private ApiInfo getApiInfo() {
  ApiInfo apiInfo = new ApiInfo("Swagger Demo API details",
    "These are API is demonstration of Swagger integration with spring","1.0", "TOS", 
           "abcd@test.com","@Swagger Demo", "http://java-treat.blogspot.com");
  return apiInfo;
 }
 private Predicate paths() {
  Predicate filter  = or(regex("/api.*")); // apiurl which starts with /api will be scanned by swagger.
  return filter;
 }
}

  • Above code will scan through following controller class present in the project.
package com.swagger.controller;

import java.io.IOException;

import org.apache.http.client.ClientProtocolException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.swagger.bean.Response;
import com.swagger.exception.CustomTwitterException;
import com.swagger.service.PostService;

import oauth.signpost.exception.OAuthCommunicationException;
import oauth.signpost.exception.OAuthExpectationFailedException;
import oauth.signpost.exception.OAuthMessageSignerException;

@RequestMapping(value="/api")
@Controller
public class ApiController {

 private static final Logger LOGGER = LoggerFactory.getLogger(ApiController.class);

 @Autowired
 PostService demoService;

 @RequestMapping(value = "/demo/{clientId}", method = RequestMethod.GET)
 public @ResponseBody
 ResponseEntity demoMethod(@PathVariable String clientId) throws OAuthMessageSignerException,
   OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException, IOException,
   CustomTwitterException {
  LOGGER.debug("START: ----- demoMethod [GET] method");
  ResponseEntity entity = null;
  Response resp = null;
  if (!StringUtils.isEmpty(clientId)) {
   resp = demoService.postMessageSelf(clientId);
   entity = new ResponseEntity(resp, resp.getStatus());
  } else {
   resp = new Response();
   resp.setCode("ERR404");
   resp.setMessage("System Error occurred: Invalid parameter passed, correct 
                                         the input parameter and retry");
   resp.setDeveloperMessage("System Error occurred: Invalid parameter passed, 
                                         correct the input parameter and retry");
   resp.setStatus(HttpStatus.UNAUTHORIZED);
   resp.setProcessedCount("0");
   resp.setReceivedCount("0");
   entity = new ResponseEntity(resp, resp.getStatus());
   LOGGER.debug(
   "postMessage method: Invalid parameter is passed during posting message operation,
                         throwing back error to caller {} ",
    entity.toString());
  }
  LOGGER.debug("END: ----- demoMethod [GET] method");
  return entity;
 }
 @RequestMapping(value = "/test", method = RequestMethod.GET)
 public ModelAndView demoMethod1(@PathVariable String clientId) {
  ModelAndView mdv=new ModelAndView();
  mdv.setViewName("ppTesting");
  return mdv;
 }
}
  • I have custom response class, sample for same is given below.

package com.swagger.bean;

import java.io.Serializable;

import javax.xml.bind.annotation.XmlRootElement;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@XmlRootElement
@JsonIgnoreProperties(value={"throwable"})
public class Response implements Serializable{
 String message;
 String code;
 String receivedCount;
 String processedCount;
 public Response(){
  this.code = null;
  this.message = null;
  this.receivedCount=null;
  this.processedCount=null;
 }
 public String getMessage() {
  return message;
 }
 public void setMessage(String message) {
  this.message = message;
 }
 public String getCode() {
  return code;
 }
 public void setCode(String code) {
  this.code = code;
 }
 public String getReceivedCount() {
  return receivedCount;
 }
 public void setReceivedCount(String receivedCount) {
  this.receivedCount = receivedCount;
 }
 public String getProcessedCount() {
  return processedCount;
 }
 public void setProcessedCount(String processedCount) {
  this.processedCount = processedCount;
 }
}
  • Once above step has been completed, next start the server. Swagger API will scan the packages and it will generate the necessary json documentation. 
  • This json documentation can be parsed and documentation can be generated. In next blog i will show how to use Swagger provided UI, which does the parsing of the json output and displays in nice look and feel UI.
  • To access the generated json file, access following url, and you should see something as shown below.
  • URL: http://<hostname>:<port>/SpringSwaggerDemo/v2/api-docs
  • For my demo context root of the application was "SpringSwaggerDemo", 
  • Below is the sample json output file.

In future blogs I will show different annotations which are available which can be used for more customized documentation and also configure Swagger with Jersey based api projects, using and configuring Swagger UI.

Components of Big Data - Hadoop System

In this blog i will explain important components which are part of Hadoop System. I will give very brief overview of these components. Be...