Swagger UI try It! does not work with Kubernetes ingress

8/14/2018

We have a Java Spring Boot project with Swagger and docker. We deploy it on kubernetes behind an ingress controller.

It works properly in localhost (using postman and swagger-ui try button). Problem comes when we deploy it.

Rest Controller:

@ApiOperation(value = "Operation", 
          notes = "it does something<br />")
@RequestMapping(value="/operation", method=RequestMethod.POST)
@ApiResponses({
    @ApiResponse(code = 200, message = "OK")
})
@ResponseBody public ResponseEntity<String> operation(@RequestBody BodyThing thing) {

    return new ResponseEntity<>("OK", HttpStatus.OK);
} //operation

Now the ingress:

apiVersion: extensions/v1beta1
kind: Ingress

metadata:
  name: myapp-ingress
  namespace: __NAMESPACE__
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /

spec:
  tls:
  - hosts:
    - test.host.com
    secretName: key-pair
  rules:
  - host: test.host.com


http:
  paths:
  - path: /myapp
    backend:
      serviceName: myapp-service
      servicePort: 8080

Then, with the app online deployed on K8S, usign an app like postman we must call: https://test.host.com/myapp/operation in order to call the API. It works OK.

The problem comes if we enter in Swagger UI portal: https://test.host.com/myapp/swagger-ui.html

If we try the API call inside the swagger UI, it tries to call to https://test.host.com/operation and it fails with 404 code.

Swagger-UI makes the Endpoint URL with: host + basepath + operation_path and that is: test.host.com + / + operation

It doesnt aggregate ingress path.

How can we deal with it? Of course is something that only happends if we deploy it with the ingress controller because, we add the /myapp path.

Thanks!

-- mvelazquezm
kubernetes
kubernetes-ingress
spring-boot
swagger
swagger-ui

1 Answer

8/14/2018

The problem is how to get swagger's base path to match to the one that is being used behind the proxy. There is more than one solution as per https://github.com/springfox/springfox/issues/1443

Since you have a specific host, I'd suggest going with the one to change the base path that swagger knows about based upon the host the request goes to. This way you can set it differently for localhost vs in the remote host. You'd need to set a RelativePathProvider for your host in your custom docket section of your Swagger @Configuration class like in https://github.com/springfox/springfox/issues/1443#issuecomment-274540681

-- Ryan Dawson
Source: StackOverflow