How to write technical documentation
Quick summary
Use github for documentation. For multiple services, use separate repo. Tie your tech doc to product
Create readme.md in your repo and add there:
- Description
- Usage
- Dependencies
- DB schema
- Contribution
Purpose
Documentation can be of different type, depending on its purpose and end-user (specification document, maintenance sheet, integration document shared with other vendors etc.).This recommendation discusses documentation systems that is needed for web-app as a product for internal engineers.It does not refer to public API documentation, public knowledge center or how-to articles.
Single service (readme.md) structure
These are all optional, pick ones that are relevant to you. "Priority" column here is just to allow sorting of priorities
Heading | Priority | Group | Details |
---|---|---|---|
Description | 1 MUST | Overview | Problem statement and purpose of the service. Screenshot of the UI, if applicable |
Installation | 3 COULD | Overview | How to run locally (installing dependencies, docker, shell scripts, manual actions) |
Usage | 2 SHOULD | Overview | • Where its in UI • URL, feature flags, user settings, payment tier |
Stakeholders | 3 COULD | Overview | Who uses this service directly, who is affected (tribes, clients, third-party developers..), who is the owner |
Roadmap | 3 COULD | Overview | What is the future of this service. How it evolve (roadmap link), will it merge or be deprecated |
TEX video | 4 WISH | Overview | Explain how service works |
Product requirements | 1 MUST | Functionality | How does service affect product experience? |
Use cases / FAQ | 2 SHOULD | Functionality | Stakeholders, actions, multiplicity.Example - describe typical scenarios that developers follow (adding some new code, extending a service etc) |
Business rules / State diagram | 3 COULD | Functionality | • use mermaid-jsThese are typically complex if-else scenarios important to how product behaves |
Page navigation | 3 COULD | Functionality | Useful to show how user can navigate across UI |
Entities & relationships | 3 COULD | Architecture | Concepts and terminology, their one-to-many relationships. This can be seen as more general version of DB schema diagram, but can include entities that are not only in DB, but also in external services, filesystem, caches etc. |
Contribution | 2 SHOULD | Processes | • What needs to be done before PR (linters, codestyle, version bumping, changelog, drafting a release for a library) • How should pull-request review happen (slack notifications) • Who can deploy at what time (if applicable like in barista case) |
Development | 3 COULD | Processes | • How to build (global tools if needed) • How to run in hot reload mode • How to debug in IDE / docker, profile, benchmark • How initial DB is set up. Where are migrations & fixtures |
Testing & Quality | 3 COULD | Processes | • How to run unit tests (how to make snapshots) • How to run functional tests (how they work) • Badges (sonar, codeship, snyk) |
Deployment / Publishing | 3 COULD | Processes | • Deployment links (jenkins) • Monitoring links ◦ Grafana dashboard ◦ Graylog • Prometheus endpoints for monitoring? What metrics are important/tracked? • Deployment diagram. Useful in case of complex server type or non-standard region setup (backoffice, marketplace) • Multi-DC diagram / region specific logic |
Configuration | 2 SHOULD | Architecture | • Do you use custom ENV variables that affect service? What are the default values? • Where its stored (consul, db, package.json) • What fields affect what, important TTLs |
DB schema | 1 MUST | Architecture | • Use mermaid-js, See mermaid js example • Link to schemas / diagram (if service has any DB at all).Lucidchart can automatically generate it based on DQL dump |
Events | 2 SHOULD | Architecture | Generated for external MQ, tracking or analytics engines • See identity as README example • Fastify event schema (typescript) • Links/accounts for sesheta, google analytics, newrelic, fullstory • Schema, fields, type. Link to tests |
Tech stack | 3 COULD | Architecture | List if stack is non-standard. Include versions • Language & extensions • Framework • Third-party product (cms, forum etc.) |
Dependencies | 1 MUST | Architecture | • Use mermaid-js flow chart ◦ you can include html links in service names to reference other repos - see barista example Can include • services ◦ external SaaS services & APIs ◦ CDNs • database servers • message queues • background (cron) jobs should include start time, frequency and name Should include what service depends on (as network requests) - other- Use newrelic service maps to track calls in realtime- Service-manager for service discovery info |
Libraries | 3 COULD | Architecture | Mention third-party dependencies if they are not standard for your stack (package.json, composer.json, Gopkg.toml) Make sure that license allows commercial use |
API | 2 SHOULD | Architecture | (Ordered from easiest to hardest) • Plain list of endpoints & methods that are used ◦ you can use collapsible blocks • Draw a diagram (lucidchart)Useful if service has 3+ endpoints, has non-restful interface.Can highlight what endpoint calls what sub-service / db • export postman collections • Include input payload & response examples (if swagger is not used) • Compose swagger.json manually • Compose swagger.json on the fly based on code annotations • Serve swagger.json via API based on live code & schemas • Exposed public function reference (for libraries) |
Class diagram | 3 COULD | Architecture | • Use mermaid-js • Useful to show deeper waterfall or inheritance structure or highlight specific functionality • Sub-systems. How important custom code works (Caching, DB query builder, Localisation, Event processing, Logging, Email generation & delivery, Search, File handling, Encryption).Typically these are candidates for extraction to a separate library or a service |
Sequence diagrams | 3 COULD | Architecture | Data flow diagram with time directed from top to bottom.Use mermaid-js.Useful logic is complex with multiple involved services, to show response/error code importance |
Project architecture
In progress, structure is not clear yet
Multiple services are usually grouped by their role for the product. Project is a big feature group of web-app or a separate product / stand-alone portal
Diagrams
Diagrams are visually pleasing, but maintaining them is harder. They are also not as searchable, so keep them to minimum
You can use:
- mermaid-js recommended as it is built-in into github, has IDE plugins, thus does not need any image re-upload or re-generation
- lucidcharts (ask internal IT for access)
- draw.io
Or other SaaS service that is editable. Should not need explicit permission. Link is needed in each case. Should not need custom software
In each component/class/queue description put in a name that can be searchable through the code or in consul.
If you use lucidchart, try to include
legend
(
) to explain what certain shapes mean. Typically, prefer using UML 2.0 syntax
Theory
Wow, you reached this section. You must be an aspiring librarian wizard
Documentation role
Documentation is needed to answer most important question - Why (service is needed)?With technical documentation, question often transforms more into How (does it work)?
- explain purpose, reasons, limitations of having this service
- explain what is the role and roadmap of the service in a product
- efficiently share the knowledge of most important parts across tribes
- formalize requirements to have common expectations of what are service limitations
- synchronise terminology that service uses and exposes with other parties
- improve quality by having automated tests acting as living documentation that proves that service works as expected
- act as map, linking to implementation details
Requirements
To answer How (service works), you can list functional requirements.
Architecture is expressed by constraints. To answer Why service was written the way it is, mention non-functional requirements.For the product its often: Performance, Reliability, Security, Usability, Configurability, Availability, ScalabilityFor development its often: Maintainability, Localisation, Compatibility, Reusability, Extensibility, Portability, Interoperability, Accessibility
See https://confluence.atlassian.com/doc/blog/2015/08/how-to-document-product-requirements-in-confluence
Language style
Documentation should be
- Simple. Avoid slang and abbreviations. Provide examples for complex calculations
- Incomplete. Documentation cannot cover everything, that is what code is for. Instead its an overview of significant, high-level things worthy of notice. Think of google maps with its zoom levels and layering.
- Consistent. Content should not contradict itself and use same terminology
- Precise. Things that you should avoid:
- generalizations (all, everywhere, never, any, each)
- vague verbs (optimize, improve, support, handle)
- vague adjectives (easy, simple, seamless)
- vague references (like in product X)
- not countable values (few, several, many, some)
- open-ended statements (etc., where appropriate, sufficient, optionally, including but not limited to)
- recursive and/or double meaning sentenses (see last point)
Keeping documentation in sync
Documentation tends to get out of sync because developers don't use documentation, so they don't update it & rely on code as single source of truth.
Suggested approach is to
- Keep service docs in github
- Have diagrams editable by any developer (without explicit permission request)
- Update docs with every github PR
- include diagrams included in PR description