Thursday, September 18, 2014

Action Report: poc-swagger-springmvc

Upgrading swagger-springmvc from version 0.65 to 0.8.8 is not a smooth upgrade in eGospel project. So, I decided to create separated Proof of Concept (POC) to make sure if we removed some complexity in the project, the investigation will be lot easier. My (stupid) first mistake is, I forgot to add
<bean class="com.mangofactory.swagger.configuration.SpringSwaggerConfig" />
in my springmvc-context.xml. After 1-2 hour, I figured out what happen, but till now still lamented for 2 hours wasted because of my stupidity. Moral of the story is, don't do any coding, when you are tired and sleepy, just rest!

Then I add (and replaced) the latest swagger-ui from "https://github.com/wordnik/swagger-ui" dist folder, and add their index.html as my "welcome-file" in web.xml
The controller I built is very simple HelloController, with one function returning Hello object and another function returning String. I also add HelloControllerTestIT for integration test, and setup all maven-plugin as in my eGospel project. And testing phase is success.

But problem now happen when I deploy my poc in application server (in my case, Tomcat) and browse it in browser. Yes, the swagger-ui can list down the controllers (which the swagger is working), but when I "Tryit out!" I got http 404; not found error. It's strange since the integration test can find the service.

I do more readings (by browsing), and guess it caused by relative path in the URL. I read several sources:
https://github.com/wordnik/swagger-ui/issues/114
https://github.com/wordnik/swagger-ui/issues/355
https://github.com/wordnik/swagger-ui/issues/337
http://stackoverflow.com/questions/14262660/rest-api-swagger-java-jersey-wrong-listing-path-and-additional-apis

Although not directly helping me, in my problem, I know what I need to do. Change my basepath into absolute path!
Since I don't want to make my hand dirty by writing my own CustomizeSwaggerConfiguration, what I need to do is to extend SpringSwaggerConfig into my new class. here comes SpringSwaggerConfig. 
package com.dariawan.poc.config;

import com.mangofactory.swagger.configuration.SpringSwaggerConfig;
import com.mangofactory.swagger.models.configuration.SwaggerModelsConfiguration;
import com.mangofactory.swagger.paths.AbsoluteSwaggerPathProvider;
import com.mangofactory.swagger.paths.SwaggerPathProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
 *
 * @author Desson Ariawan <teodesson@yahoo.com>
 */
@Configuration
//@ComponentScan(basePackages = {"com.mangofactory.swagger.controllers"})
@Import(SwaggerModelsConfiguration.class)
public class MySpringSwaggerConfig extends SpringSwaggerConfig {

    @Bean
    @Override
    public SwaggerPathProvider defaultSwaggerPathProvider() {
        return new AbsoluteSwaggerPathProvider();
    }
}

Yes, what I do is only overriding  defaultSwaggerPathProvider() function. Replace bean in springmvc-context.xml, now using MySpringSwaggerConfig.
<bean class="com.dariawan.poc.config.MySpringSwaggerConfig" />

And voila! Integration Test now passed, and swagger-ui also showing what I'm expecting.



You can check complete project in https://github.com/teodesson/poc-swagger-springmvc
Now I need to sleep.

Update: add pictures, and later on: added spring-security into the project, no functional impact, swagger and spring-mvc works as expected

No comments:

Post a Comment