This morning, I read this kind tweet by Raumzeitfalle:
@rotnroll666 Just discovered the nice #arc42 based documentation of biking2. Thanks for providing such nice example. Got the hint from @DevBoost that #arc42 might be something helpful. The biking2 example helps a lot!
— 📸 Raumzeitfalle 🛶 (@Raumzeitfalle) December 4, 2018
This refers to arc42 by example. There will be a second edition of this book soon, with new contributions from Gernot and new, Ralf.
My example in this book, biking2 is still up to date. I used this now several times at customers and every time, I also recommended my approach of generating the documentation as part of the build process. You see the live output here.
What makes those special are the following facts:
- The docs are written in Asciidoctor, see: src/docs.
- I’m using the Asciidoctor Maven plugin. That means they are an essential part of the build and aren’t left to die in a Confluence or whatever.
- Even more, I use maven-resources-plugin to copy them into the output dir from which they are put into the final artifact.
While the documentation is strictly structured by the ideas of arc42, here come’s the fun parts:
I’m using jQAssistant to continuously verify my personal quality goals with that project: jQAssistant is a QA tool, which allows the definition and validation of project specific rules on a structural level. It is built upon the graph database Neo4j.
jQAssistant integrates also in your build process. It first analyzes your sources and dependencies and writes every information it can discover through various plugins into an embedded Neo4j instance. That is the scan step. In the following analyze step, it verifies the data agains build-in or custom rules. You write custom rules as Cypher queries. Now the interesting fact: Those concept and rules can be written in Asciidoctor as well. This one, concepts_structure.adoc, declares my concept of a config and support package. Those concepts are executed in Neo4j and add labels to certain nodes. The label is then used in this rule (structure.adoc):
MATCH (a:Main:Artifact) MATCH (a) -[:CONTAINS]-> (p1:Package) -[:DEPENDS_ON]-> (p2:Package) <-[:CONTAINS]- (a) WHERE not p1:Config and not (p1) -[:CONTAINS]-> (p2) and not p2:Support and not p1.fqn = 'ac.simons.biking2.summary' RETURN p1, p2
“Give me all the packages of the main artifact but the config and the summary package that depend on other packages that are not contained in the package itself.” If that query returns an entry, the rule is violated. I use that rule to enforce horizontal, domain specific slices.
Now, the very same, executable rule becomes part of my documentation (see building block view) by just including them. Isn’t that great?
- I also include specific information from my class files in the docs. Asciidoctor allows including dedicated part of all text files. For example, I use package-info.java files like this directly in the docs: “bikes”. I did this to a much bigger extend in this repo, find the linked articles there. I love Asciidoctor.
- Last but not least, I use Spring REST docs in my unit tests. Spring REST docs combines hand-written documentation written with Asciidoctor and auto-generated snippets produced with Spring MVC Test. A simple unit test like this gets instrumented by a call to
documentlike show in this block. This describes expectations about parameters and returned values. If they aren’t there in the request or response, the test fails. So one cannot change the api without adapting documentation. You might have guess: The generated Asciidoctor snippet as included again in the final docs, you find it here.
- I’m using jQAssistant to continuously verify my personal quality goals with that project: jQAssistant is a QA tool, which allows the definition and validation of project specific rules on a structural level. It is built upon the graph database Neo4j.
I started working on the documentation in early 2016, after a great workshop with Peter Hruschka and Gernot Starke. This is now 2 years ago and the tooling just got better and better.
Whether you are writing a monolithic application like my example, micro services or desktop applications. There’s no reason not to document your application.
Here are some more interesting projects, that have similar goals:
- Oliver Drotbohms Moduliths. Oliver strives to create great monoliths by enforcing structure in code through rules and integrates with other tools like jQAssistant as well.
- There is docToolchain, that describes all the tooling needed for creating living docs.
- The Spring REST Docs Open API integration by Mathias
Also, as an added bonus, there’s DocGist, that creates rendered Asciidoctor files for you to share. Thanks Michael for the tip.
“Michael Simons” 😂
Nice Post, great documentation. One tiny suggestion: would it be possible to render some navigation on top/bottom of a document?
Like “prev” “top” “index” “next” ?
That would make the navigation way more easier 🙂
Thanks a lot, Philipp for your kind comment. Means a lot coming from you.
Regarding navigation: Do you mean in the generated docs or in my blog?
Possible something like we do in the Neo4j-OGM docs, right? They are Asciidoctor based as well.
I like the idea, have to poke around a bit.
If you want, you could remove the `maven-resources-plugin to`, since 1.5.5 `asciidoctor-maven-plugin` allows filtering resources.
Just add this to the asciidoctor configuration
Hi. Thanks for the input. Stupid WordPress killed the tags, though. I’d happily merge a PR on the repo itself.
I like this a lot: