By: +David Herron; Date: June 15, 2017
Among the Swagger Tools is Swagger UI, an excellent tool for browsing an OpenAPI specification, the methods defined in the specification, the data models used in the specification. Swagger UI even lets you interact with the service from the documentation. It's a most useful take on "documentation", and to large measure is the whole reason for adopting OpenAPI/Swagger.
Unfortunately implementing the springfox-swagger-ui plugin in a Spring Boot Swagger application gives you a Swagger UI implementatation that's nowhere near as nice/capable as the demo app you see at petstore.swagger.io. There is zero documentation on how to implement the improved Swagger UI via the springfox-swagger-ui plugin. Instead, after quite a bit of experimentation, it seems one must turn to the Swagger UI Docker container.
My first thought was perhaps there's a magic @Annotation to configure additional data that will then trigger the
springfox-swagger-ui into showing an improved user interface. After a long bout of reading the documentation which could be found, it seems there's no annotations to exploit. Nor did adding the
springfox-schema plugins make any change.
The Swagger UI project page (
https://github.com/swagger-api/swagger-ui) talks about downloading that repository, and then directly opening
dist/index.html in a web browser. Doing so does bring up a version of the Swagger UI. It includes a text entry box into which you can enter a URL for a JSON file. Unfortunately it doesn't work against the Spring Boot application I've written. It works great against the Petstore demo, however.
Fetch API cannot load http://127.0.0.1/v2/swagger.json. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Uh, okay? CORS, whatever that is. The Swagger UI project page does talk about this, and insists that CORS must be implemented on your server. That means implementing CORS in my Spring Boot service. In theory this guide on implementing Cross Origin Request in Spring contains the necessary guidance. But that didn't help either.
The documentation in both cases left TONS to be desired. Instead of coming straight out and saying what to do ... uh ... anyway, the bottom line is that given my knowledge level on this using Spring UI loaded from a
file:/// URL on my local disk would not work.
Spring UI is also available as a Docker container. It means installing Swagger UI is as simple as:
$ docker pull swaggerapi/swagger-ui $ docker run -p 80:8080 -e "SWAGGER_JSON=/foo/swagger.json" -v /bar:/foo swaggerapi/swagger-ui
Well, it takes a little more than this.
The first thing I needed to do is dump the JSON OpenAPI specification from my service. That's as simple as this:
$ mkdir ~/spec $ cd ~/spec $ curl -f http://localhost:8080/v2/swagger.json >spec.json
On the last line substitute the correct URL to view the API spec. In the
application.properties for the application, I have these lines:
# prefix for all requests server.contextPath=/v2 # location of the swagger json springfox.documentation.swagger.v2.path=/swagger.json
Lacking those property settings, the default seems to be that the JSON appears at
/v2/api-docs. The URL should show up in the messages printed by Spring Boot during its initialization.
The point of the above is to get the specification file into a local file. The next thingg we'll do is a variant of the above Docker command to run Swagger UI so it automatically loads this specification.
$ run --rm -d -p 6080:8080 -e "SWAGGER_JSON=/foo/spec.json" -v `pwd`:/foo swaggerapi/swagger-ui
Look closely and you'll see a few small differences.
--rm so that the container is deleted when it's done, just to clean up after itself.
-d to detach allowing the container to run in the background.
-v options, the specification file is available inside the container, and then loaded by Swagger UI. Earlier commands downloaded the specification file to
-v option mounts the current directory as
/foo inside the container. Then the
-e option tells Swagger UI to look at
/foo/spec.json to load the specification. Which, turns out to be
~/spec/spec.json on the host filesystem.
Once all that's set up, point your browser to
http://HOST-IP:6080 and the full-fledged Swagger UI should be there for your viewing pleasure.