Documentation As Code
Documentation as Code
Documentation as Code behandelt Dokumentation wie Software-Code. Lernen Sie Docs zu versionieren, reviewen und automatisiert zu deployen.
Das Konzept
┌─────────────────────────────────────────────────────────────┐ │ DOCUMENTATION AS CODE │ ├─────────────────────────────────────────────────────────────┤ │ │ │ TRADITIONELL DOCS AS CODE │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ Word/Wiki │ │ Markdown/ │ │ │ │ Confluence │ │ AsciiDoc │ │ │ └─────────────┘ └──────┬──────┘ │ │ │ │ │ │ │ │ Git Repository │ │ │ ▼ │ │ │ ┌─────────────┐ │ │ • Keine Versionierung │ PR/MR │ │ │ • Kein Review-Prozess │ Review │ │ │ • Manuelles Update └──────┬──────┘ │ │ • Out of Sync mit Code │ │ │ │ CI/CD Pipeline │ │ ▼ │ │ ┌─────────────┐ │ │ │ Build & │ │ │ │ Deploy │ │ │ └──────┬──────┘ │ │ │ │ │ ▼ │ │ ┌─────────────┐ │ │ │ Website / │ │ │ │ PDF / etc. │ │ │ └─────────────┘ │ │ │ │ VORTEILE: │ │ ✅ Versioniert mit Git │ │ ✅ PR Reviews für Docs │ │ ✅ Automatische Builds │ │ ✅ Docs im gleichen Repo wie Code │ │ ✅ DRY: Code-Beispiele einbinden │ │ │ └─────────────────────────────────────────────────────────────┘
Formate
| Format | Stärken | Gut für |
|---|---|---|
| Markdown | Einfach, weit verbreitet | README, API Docs, einfache Sites |
| AsciiDoc | Mächtiger, PDF-Export | Technische Bücher, komplexe Docs |
| reStructuredText | Python Ökosystem, Sphinx | Python Projekte, API References |
| MDX | Markdown + React Components | Interaktive Dokumentation |
Projekt-Struktur
my-project/ ├── src/ # Quellcode ├── tests/ # Tests ├── docs/ # Dokumentation │ ├── getting-started.md │ ├── installation.md │ ├── api/ │ │ ├── authentication.md │ │ └── endpoints.md │ ├── guides/ │ │ ├── deployment.md │ │ └── configuration.md │ ├── architecture/ │ │ └── decisions/ # ADRs │ │ ├── 001-use-postgresql.md │ │ └── 002-microservices.md │ └── assets/ │ └── images/ ├── README.md # Projekt-Übersicht ├── CONTRIBUTING.md # Contribution Guidelines ├── CHANGELOG.md # Änderungsprotokoll └── docusaurus.config.js # Docs Site Config
Docusaurus Setup
# Docusaurus (React-basiert, von Meta)
# Installation
npx create-docusaurus@latest my-docs classic
# Struktur
my-docs/
├── docs/ # Markdown Dateien
│ ├── intro.md
│ └── tutorial/
├── blog/ # Blog Posts (optional)
├── src/
│ └── pages/ # Custom React Pages
├── static/ # Static Assets
├── docusaurus.config.js # Konfiguration
└── sidebars.js # Navigation
# docusaurus.config.js
module.exports = {
title: 'My Project',
tagline: 'Documentation',
url: 'https://docs.example.com',
baseUrl: '/',
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
sidebarPath: require.resolve('./sidebars.js'),
editUrl: 'https://github.com/my-org/my-project/edit/main/',
},
theme: {
customCss: require.resolve('./src/css/custom.css'),
},
},
],
],
themeConfig: {
navbar: {
title: 'My Project',
items: [
{ to: '/docs/intro', label: 'Docs', position: 'left' },
{ to: '/blog', label: 'Blog', position: 'left' },
{ href: 'https://github.com/my-org/my-project', label: 'GitHub', position: 'right' },
],
},
},
};
# Lokale Entwicklung npm run start # Dev Server auf localhost:3000 # Build npm run build # Generiert static/ Ordner # Deploy npm run deploy # GitHub Pages
MkDocs (Python)
# MkDocs mit Material Theme
# Installation
pip install mkdocs mkdocs-material
# Initialisierung
mkdocs new my-docs
cd my-docs
# mkdocs.yml
site_name: My Project Documentation
site_url: https://docs.example.com
theme:
name: material
palette:
primary: indigo
features:
- navigation.tabs
- navigation.sections
- search.highlight
- content.code.copy
nav:
- Home: index.md
- Getting Started:
- Installation: getting-started/installation.md
- Quick Start: getting-started/quickstart.md
- API Reference:
- Authentication: api/auth.md
- Endpoints: api/endpoints.md
- Guides:
- Deployment: guides/deployment.md
plugins:
- search
- mkdocstrings: # API Docs aus Docstrings
handlers:
python:
paths: [src]
markdown_extensions:
- pymdownx.highlight
- pymdownx.superfences
- admonition
- toc:
permalink: true
# Befehle
mkdocs serve # Dev Server
mkdocs build # Build nach site/
mkdocs gh-deploy # Deploy zu GitHub Pages
API-Dokumentation generieren
# OpenAPI/Swagger aus Code generieren
// PHP: OpenAPI Annotations
/**
* @OA\Get(
* path="/api/users/{id}",
* summary="Get user by ID",
* @OA\Parameter(
* name="id",
* in="path",
* required=true,
* @OA\Schema(type="integer")
* ),
* @OA\Response(
* response=200,
* description="User found",
* @OA\JsonContent(ref="#/components/schemas/User")
* ),
* @OA\Response(response=404, description="Not found")
* )
*/
public function getUser(int $id): JsonResponse
// TypeScript: TypeDoc
// Installation: npm install typedoc
/**
* Represents a user in the system.
*
* @example
* ```typescript
* const user = new User("John", "john@example.com");
* await user.save();
* ```
*/
export class User {
/**
* Creates a new user instance.
* @param name - The user's full name
* @param email - The user's email address
* @throws {ValidationError} If email is invalid
*/
constructor(public name: string, public email: string) {}
/**
* Saves the user to the database.
* @returns The saved user with ID
*/
async save(): Promise<User> { /* ... */ }
}
// typedoc.json
{
"entryPoints": ["src/index.ts"],
"out": "docs/api",
"readme": "README.md"
}
// npx typedoc
Architecture Decision Records (ADRs)
# docs/architecture/decisions/001-use-postgresql.md # 1. Use PostgreSQL as Primary Database ## Status Accepted ## Context We need to choose a database for our new project. Requirements: - ACID transactions - Complex queries with joins - JSON support for flexible data - Good scaling options ## Decision We will use PostgreSQL as our primary database. ## Consequences ### Positive - Mature, battle-tested database - Excellent JSON support (JSONB) - Strong community and tooling - Easy to find developers with experience ### Negative - Requires more ops knowledge than managed NoSQL - Horizontal scaling more complex than MongoDB ### Neutral - Team needs to learn PostgreSQL-specific features
# ADR Template generieren # adr-tools: https://github.com/npryce/adr-tools # Installation brew install adr-tools # Initialisieren adr init docs/architecture/decisions # Neues ADR erstellen adr new Use PostgreSQL for persistence # Status ändern adr supersede 1 "Use MySQL instead"
CI/CD für Docs
# .github/workflows/docs.yml
name: Deploy Docs
on:
push:
branches: [main]
paths:
- 'docs/**'
- 'docusaurus.config.js'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build documentation
run: npm run build
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./build
# Optional: Link-Check
link-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check links
uses: lycheeverse/lychee-action@v1
with:
args: --verbose --no-progress 'docs/**/*.md'
Code-Beispiele einbinden
# Docusaurus: Code aus Dateien importieren
```jsx title="src/components/Button.jsx"
import React from 'react';
export function Button({ label, onClick }) {
return (
<button className="btn" onClick={onClick}>
{label}
</button>
);
}
```
# Mit Highlighting bestimmter Zeilen
```js {3-5}
function example() {
const a = 1;
// Diese Zeilen
// sind
// hervorgehoben
return a;
}
```
# Live Code Editor (MDX)
```jsx live
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</div>
);
}
```
Docs im Monorepo
# Monorepo Struktur mit Docs
monorepo/
├── packages/
│ ├── api/
│ │ ├── src/
│ │ ├── docs/ # API-spezifische Docs
│ │ │ └── endpoints.md
│ │ └── README.md
│ ├── frontend/
│ │ ├── src/
│ │ ├── docs/ # Frontend-spezifische Docs
│ │ │ └── components.md
│ │ └── README.md
│ └── shared/
│ └── README.md
├── docs/ # Übergreifende Docs
│ ├── getting-started.md
│ ├── architecture.md
│ └── deployment.md
├── website/ # Docs Website (Docusaurus)
│ └── docusaurus.config.js
└── README.md
# docusaurus.config.js - Docs aus mehreren Quellen
module.exports = {
plugins: [
[
'@docusaurus/plugin-content-docs',
{
id: 'api',
path: '../packages/api/docs',
routeBasePath: 'api',
},
],
[
'@docusaurus/plugin-content-docs',
{
id: 'frontend',
path: '../packages/frontend/docs',
routeBasePath: 'frontend',
},
],
],
};
💡 Best Practices:
1. Docs im gleichen Repo wie Code halten
2. PRs für Docs genauso reviewen wie Code
3. CI/CD für automatische Builds und Deploys
4. Broken Links automatisch prüfen
5. ADRs für wichtige Architektur-Entscheidungen
2. PRs für Docs genauso reviewen wie Code
3. CI/CD für automatische Builds und Deploys
4. Broken Links automatisch prüfen
5. ADRs für wichtige Architektur-Entscheidungen
Weitere Informationen
- ✨ Clean Code
- 📝 API Design
- 🔄 GitOps