Once upon a time, there was a REST service. It wasn’t too big nor too small; one could say — of a reasonable size. However, it was a crucial one, and almost the whole herd of other services was dependent on it. Because of that, its API had to be well documented and publicized so these small, intriguing creatures, called developers, can see it and then use it in their daily work.

As you may guess, the publication wasn’t the most straightforward process since there were specific requirements. However, here is a daredevil who decided to take on this challenge. Of course, many gnomes and critters tried to discourage, even defeat, our brave hero.

Here, you can read the story of a brave developer who picked the gauntlet. Did it end up well? Alternatively, did he fail severely? Have a seat, grab some coffee/tea/yerba and join me for the adventure of taming adversities and finding a way to the destination of our hero.

Circumstances

What’s the mission of our hero?

So, there’s a REST service in the wild. To get familiar with it, people of The Developers’ Kingdom needs some information about it — how to communicate with it: what endpoints are there and what data formats the service accepts and produces.

While the mission looked pretty simple, there is a teeny tiny requirement — the developers established a standard of documenting various services, and our hero has to keep up with it.

The standard reference sounds simple: describe the API using the OpenAPI standard, expose it through the /admin/api-docs endpoint and use Swagger application so the documentation can be easily looked through. However, the application must be available, no matter what, under the /admin/swagger-ui.html path.

The quest

“That’s an easy task!”, said our hero. The service is written in Java, and what’s more, it uses the almighty Spring Framework as its backbone.

“Yay!”, that’s another thought of the daredevil, “Easy peasy since I can use SpringFox magic to complete my task.” Some of you may consider this type of Annotations Magic as a black one. However, our hero didn’t care about it, believing in his strength and experience. As a result of this choice, the service gained a new dependency: springfox-swagger2 library.

Documenting endpoints

The first step in the quest was documenting all the endpoints of the service. How to do it with the smallest effort required? When browsing the elder scroll (a.k.a. documentation) of the SpringFox, our hero has found a useful @EnableSwagger2 spell. After thoughtfully casting it on the application, almost everything needed was documented.

The missing “almost” part was describing endpoints accurately. Our adventurer handled this element of the task by casting @ApiOperation on every endpoint found in the application. The results were just right.

Exposing with a custom path

However, the casted abracadabra ended with the documentation available at /v2/api-docs , while it should be available under /admin/api-docs . That was easy to fix by tweaking (in application.properties ) a single ingredient of the spell’s recipe: assigning the expected path value to springfox.documentation.swagger.v2.path property did the job.

Swagger UI application

Having the endpoints documented, our hero must show them in a format readable by the Developers. One of the prerequisites of the quest was using Swagger UI to present results of the annotation spells.

The next step was quite obvious — adding a new dependency to the project, which is springfox-swagger-ui . It provides the standard layout for the documentation in the form of an HTML file. By default, SpringFox exposes documentation under the swagger-ui.html path and uses the API docs path to feed the page.

While the daredevil was pretty close to finish the quest, he hit the 80/20 rule wall. During 20% of the time, he finished 80% of the task.

Accessing Swagger UI from a custom place

Knowing the arcana of the Spring Framework, the first try was a simple copy-paste kata of springfox-swagger-ui files into reasources/admin folder. As you may guess, it failed badly and calling /admin/swagger-ui.html ended with NotFound status in the form of the “Whitelabel Error Page” error.

“That’s a stupid mistake” — our hero thought — “Let’s try the META-INF folder.” So, he did the same kata, this time using META-INF/resources/admin folder. Unfortunately, it seemed the luck left the daredevil. The recent error looked more seriously:

Not so easy, cowboy!

Entering both locations of the UI file or even the endpoint serving API docs in raw format, didn’t help. The daredevil swore badly on Spring magic. Even Swagger was “the stupidest thing on the world we can imagine, and it has to be screwed up, obviously”.

Our hero had no hope to fix it. Nor didn’t know what to do next. He felt he tried almost everything and every attempt to fix the issue ended with an error.

Fortunately, The Developers’ Kingdom has the Great StackOverflow Library. That’s the place where the daredevil — out of desperation — looked for help and (surprise! surprise!) found the solution.

It appeared to be a variation of the copy-paste kata — this time with a small update on one of the copied files. While the target folder for files was a good one ( META-INF/resources/admin , as in the previous attempt), it required a small change in the swagger-ui-html file. Instead of importing default JavaScript incantations from <script src="../webjars/springfox-swagger-ui/springfox.js?v=2.9.2"></script> , providing a custom version of them solved the issue:

The most crucial change was providing the right address where the documentation in a raw format is publicised. The UI part of the Swagger could now read the data and present it to the Developers waiting for the required information. Our brave developer could finally finish the task.

While everybody was happy and the story turned out a success, the daredevil felt that something went wrong. Something could be done better. What was that?

The happy ending

A “quick” way appeared not so quick; in fact, it took more time than expected. However, in the end, our hero could return to the kingdom and its people to give them what they needed.

The rush

What about the feeling mentioned at the end? I think you can easily spot the issue. The case is solved, however, with yet another copy-paste kata. We can only hope, the “paste” part was done deliberately that our almighty developer knew what he is doing.

Unfortunately, being in rush, we often forget about the consequences of applying thoughtlessly solutions found on the Internet or, particularly, on the StackOverflow pages. It is the case when we always want to solve something “quickly”, and we are interested in providing a fix as soon as possible.

Moving Swagger resources around in a try-and-see-what-happens fashion isn’t the most brilliant idea either. When we want to solve an issue, we must understand it, and all the steps required along the way, correctly. Otherwise, it is hard to achieve a goal effectively.

Deliberate effort

So what are the real things we can do?

At first, look at the sources carefully. Read them, understand, and quite often, this is pretty enough to solve an issue.

If this doesn’t help — READ-THE-DOCS, stupid. Should our daredevil read the Swagger documentation, I’m pretty sure he would have finished the task way earlier than done.

Sometimes even after reading, we feel stuck. Don’t hesitate to ask for help. Let it be asking other developers from the project, your company, or searching hints in the Great StackOverflow Library where countless developers gather the wisdom. HOWEVER! Do not apply the found solution or knowledge blindly to your case! Always understand what you want to achieve and what you are doing at the moment. Deliberate effort always pays off!

Stuck in your head

Also, there are no gnomes or critters: everything is in our heads. It is not that Spring is an awful, magic tool or Swagger is “screwed up”. It is us — developers — using tools and libraries daily, not knowing them into the extent required.

I know, Spring uses a lot of “magic” inside, and it could be challenging to use it sometimes. It is almost impossible to know everything about it. So, this is why docs exist. Looking for details there helps you solve the issue. And did you know you don’t have to rely on the annotations when using Spring?

Thus, no — it is not either a gnome nor critter fault that something does not work. It could be a bug, of course. However, usually understanding of the surroundings is enough to move forward.