Surely, during the development of the API, difficulties with the documentation appeared more than once: either it does not exist, then it does not display the behavior described in the code.
From the developer's point of view, writing documentation (internal only) takes no less time than writing the code itself. Is that familiar? Then welcome to cat.
Is there a problem?
Our team has been developing the API for a long time, which is the basis of our product, but at that time there were no live users, so no one saw the need to document something for external use. Like all teams, we started with internal documentation - first one method, then another. In our space in Confluence, you can find a dozen other pages where pretty template information is displayed - what kind of API method, what query path it has, what parameters and what we get in the output.
Everything would be fine, but the code is constantly changing and growing, business needs are changing. Along with code changes, APIs can change, which inevitably leads to changes on these pages. Well, if this is one page and only 1 time. And if there are more changes?
We came up with a solution (our own bike), as much as possible, while engaging in the usual activities of the developer, not to think about writing and updating internal documentation.
Some solutions
There are different options for how the code and its specification can be interconnected, but for myself I distinguish two:
- Code first, specification next
- Specification first, code next
I'll start with the second, as with the option that was least suitable for us.
Specification first, code next is about code generation, based on the specification, that is, the code does not exist until you write the specification.
The simplest example is Swagger Codegen.
Our company has teams that use this approach in their product, but in our case it was not very suitable. At the time when we were faced with a need, we had already written a lot of API methods, so for the sake of documentation we did not want to radically change the development processes - first we write drafts, then we code and only then the specification description.
Code first, specification next - everything is simple here, first we write the code, then the specification. But then the question arose - and if we do not want to make unnecessary movements so that the specification is generated?
A number of applications in our company use this approach, but it is not particularly automated - API methods are weighted with all kinds of annotations, based on which the specification was generated. But these same annotations often do not correspond to reality, because the needs and capabilities of the application are growing and changing.
“You are a programmer,” I told myself, and decided to write a small prototype that would allow me not to write all this routine garbage.
Doing the next task and writing the nth functional test, I realized that we already have all the information for the specification.
We have functional tests that contain almost all the information we need:
- What is being called
- What is called (parameters, body, headers, etc.)
- What result is expected (status code, response body)
Why not make your own bike?
Almost everything that we usually write in the specifications we have. The case for small - code this case.
Since our application is in php, reflection came to my aid. Using a little magic of reflection, we collect all the API methods available to us, take data from functional tests, extract data about authorization and its type. From the usual annotations to the methods, we get the description of the method itself. Having mixed all this, seasoning with specific features for the framework used in our solutions, in a couple of weeks we get a solution that practically does not require additional time from the developer.
Generating a specification is only the first step - you need to get documentation from the specification that can be provided by an external developer. One of the requirements for documentation is that it should be presented in several languages, but at the moment, we only generate documentation in English. So far, enough, but it will be necessary to connect the mechanism for receiving transfers to our specification generation scheme.
The problem that was originally we solved. But with this solution there are many risks:
- Price support your own bike
- Extension of necessary functionality
- Update and synchronization of translations
These risks must be borne in mind and, if they start to work, then take action.