Documenting and exposing an API with Swagger

This section details how to provide and expose metadata about the REST API using Swagger.

Getting ready

We are often required to document APIs for users and customers. When documenting an API, depending on the tools we use, we often get a few extras such as the ability to generate client code from the API metadata or even the generation of integrated test harnesses for the API.

There isn't yet a recognized and universal standard for the format of the API metadata. This lack of standards leads to a quite a few different solutions on the market for the REST documentation.

We have chosen Swagger here because it has the largest and the most active community. It has existed since 2011, and it offers a very nice UI/test harness and great configuration by default.

How to do it...

This section details what can be done and also what we have done in the code base of the checked-out v4.x.x branch.

  1. We have added a Maven dependency for the swagger-springmvc project (version 0.9.5) to cloudstreetmarket-core and cloudstreetmarket-parent:
    <dependency>
      <groupId>com.mangofactory</groupId>
      <artifactId>swagger-springmvc</artifactId>
      <version>${swagger-springmvc.version}</version>
    </dependency> 
  2. The following swagger configuration class has been created:
    @Configuration
    @EnableSwagger //Loads the beans required by the framework
    public class SwaggerConfig {
    
      private SpringSwaggerConfig springSwaggerConfig;
      @Autowired
        public void setSpringSwaggerConfig(SpringSwaggerConfig springSwaggerConfig) {
        this.springSwaggerConfig = springSwaggerConfig;
        }
      @Bean
      public SwaggerSpringMvcPlugin customImplementation(){
          return new SwaggerSpringMvcPlugin( this.springSwaggerConfig)
              .includePatterns(".*")
              .apiInfo(new ApiInfo(
              "Cloudstreet Market / Swagger UI",
              "The Rest API developed with Spring MVC Cookbook [PACKT]",
              "",
              "[email protected]",
              "LGPL",
              "http://www.gnu.org/licenses/gpl-3.0.en.html"
          ));
      }
    }
  3. The following configuration has been added to the dispatch-context.xml:
    <bean class="com.mangofactory.swagger.configuration.SpringSwaggerConfig"/>
    
    <bean class="edu.zc.csm.api.swagger.SwaggerConfig"/>
    <context:property-placeholder location="classpath*:/META-INF/properties/swagger.properties" />
  4. As per the previous configuration, a swagger.properties file has been added at the path src/main/resources/META-INF/properties with the content:
      documentation.services.version=1.0
      documentation.services.basePath=http://localhost:8080/api
  5. Our three controllers have been added a basic documentation. See the following documentation annotations added to IndexController:
    @Api(value = "indices", description = "Financial indices") 
    @RestController
    @RequestMapping(value="/indices", produces={"application/xml", "application/json"})
    public class IndexController extends CloudstreetApiWCI {
    
    @RequestMapping(method=GET)
    @ApiOperation(value = "Get overviews of indices", notes = "Return a page of index-overviews")
    public Page<IndexOverviewDTO> getIndices(
    @ApiIgnore @PageableDefault(size=10, page=0, sort={"dailyLatestValue"}, direction=Direction.DESC) Pageable pageable){
        return 
        marketService.getLastDayIndicesOverview(pageable);
    }
    
    @RequestMapping(value="/{market}", method=GET)
    @ApiOperation(value = "Get overviews of indices filtered by market", notes = "Return a page of index-overviews")
    public Page<IndexOverviewDTO> getIndicesPerMarket(
      @PathVariable MarketCode market,
      @ApiIgnore 
    @PageableDefault(size=10, page=0, sort={"dailyLatestValue"}, direction=Direction.DESC) Pageable pageable){
        return 
        marketService.getLastDayIndicesOverview(market, pageable);
    }
    
    @RequestMapping(value="/{market}/{index}/histo", method=GET)
    @ApiOperation(value = "Get historical-data for one index", notes = "Return a set of historical-data from one index")
    public HistoProductDTO getHistoIndex(
      @PathVariable("market") MarketCode market, 
      @ApiParam(value="Index code: ^OEX") 
      @PathVariable("index") String 
      indexCode,@ApiParam(value="Start date: 2014-01-01") @RequestParam(value="fd",defaultValue="") Date fromDate,
      @ApiParam(value="End date: 2020-12-12") 
      @RequestParam(value="td",defaultValue="") Date toDate,
      @ApiParam(value="Period between snapshots") @RequestParam(value="i",defaultValue="MINUTE_30") QuotesInterval interval){
        return marketService.getHistoIndex(indexCode, market, fromDate, toDate, interval);
      }
    }
  6. We have downloaded the swagger UI project from https://github.com/swagger-api/swagger-ui.This is a collection of static files (JS, CSS, HTML, and pictures). It has been pasted in the webapp directory of our cloudstreetmarket-api project.
  7. Finally, the following mvc namespace configuration has been added to dispatch-context.xml again in order for the Spring MVC to open access to static files in the project:
    <!-- Serve static content-->
    <mvc:default-servlet-handler/>
  8. When we have this configuration, accessing the following URL on the server http://localhost:8080/api/index.html brings up the Swagger UI documentation portal:
    How to do it...

    More than just a REST documentation repository, it is also a handy test harness:

    How to do it...

How it works...

Swagger has its own controller that publishes the metadata of our API. The Swagger UI targets this metadata, parses it, and represents it as a usable interface.

An exposed metadata

On the server side, with the com.mangofactory/swagger-springmvc dependency added to the swagger-springmvc project and with the presented SwaggerConfig class, the library creates a controller on the root path: /api-docs and publishes the entire metadata there for the REST API.

If you visit http://localhost:8080/api/api-docs, you will reach the root of our REST API documentation:

An exposed metadata

This content is the exposed metadata that implements the Swagger specification. The metadata is a navigable structure. Links to other parts of the metadata can be found in the <path> nodes of the XML content.

The Swagger UI

The Swagger UI is only made of static files (CSS, HTML, JavaScript, and so on). The JavaScript logic implements the Swagger specification and recursively parses the entire exposed metadata. It then dynamically builds the API documentation website and test harness that we have presented, digging out every single endpoint and its metadata.

There's more...

In this section, we suggest you to look further into Swagger and its Spring MVC project implementation.

The Swagger.io

Visit the framework's website and its specification: http://swagger.io.

The swagger-springmvc documentation

The swagger-springmvc project is changing as it is becoming part of a bigger project named SpringFox. SpringFox now also supports the second version of the Swagger specification. We recommend you to visit their current reference document:

http://springfox.github.io/springfox/docs/current

They also provide a migration guide to move from the swagger specification 1.2 (that we have implemented here) to the swagger specification 2.0:

https://github.com/springfox/springfox/blob/master/docs/transitioning-to-v2.md

See also

This section guides you toward alternative tools and specification to Swagger:

Different tools, different standards

We have mentioned that there isn't a common standard yet that would clearly legitimize one tool over another. Thus, it is probably good to acknowledge tools other than Swagger because things are moving quite fast in this domain. Here, you can find two great comparison articles:

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset