I was staring at a support ticket that made me sigh. A developer trying to use our API had spent three hours trying to figure out how to filter a product list. The endpoint was right there, but the documentation was a single, outdated line in a forgotten README file. That moment was a turning point. I realized that for an API to be truly successful, its documentation must be as robust and reliable as the code itself. It shouldn’t be an afterthought; it should be a core feature. This is why I want to show you how to build living, breathing documentation that grows with your application. Let’s build something that answers questions before they’re even asked.
Have you ever tried to use an API where the documentation felt like a ghost town—empty, silent, and slightly unnerving? I have. It’s frustrating. Good documentation is a sign of respect for the developers who will use your work. It’s the bridge between your brilliant code and the world. Today, we’ll construct that bridge using AdonisJS, combining the power of Swagger for external API consumers and TypeDoc for the internal team maintaining the codebase.
We start by setting up our project. The goal is to have two documentation streams generated automatically: one for the public REST API and another for the internal TypeScript code. First, create a new AdonisJS API project.
npm init adonisjs@latest api-docs-project -- --kit=api
cd api-docs-project
Next, we install the tools that will do the heavy lifting. We need Swagger for our REST endpoints and TypeDoc for our TypeScript source code.
npm install @adonisjs/swagger
npm install --save-dev typedoc
Now, let’s configure Swagger. Create a file called config/swagger.ts. This is where we define the look, feel, and information about our API. Think of it as the welcome sign and map for your API city.
import { SwaggerConfig } from '@ioc:Adonis/Addons/Swagger'
export default {
uiEnabled: true,
uiUrl: 'docs',
specEnabled: true,
specUrl: '/swagger.json',
middleware: [],
options: {
definition: {
openapi: '3.0.0',
info: {
title: 'My Production API',
version: '1.0.0',
description: 'The official interface for our services.',
},
servers: [
{ url: 'http://localhost:3333', description: 'Development' },
],
},
apis: ['app/**/*.ts', 'start/routes.ts'],
},
} as SwaggerConfig
With the configuration ready, we need to register the Swagger provider. Open your .adonisrc.json file and add it to the providers array. This tells AdonisJS to load and use our Swagger setup.
{
"providers": [
"./providers/AppProvider",
"@adonisjs/core",
"@adonisjs/swagger"
]
}
The magic happens when we write our controllers. Instead of documenting in a separate file, we write the documentation as comments right above our methods. This keeps the docs and code in sync. Here’s how you might document a simple endpoint to fetch users.
/**
* @swagger
* /api/users:
* get:
* summary: Get a list of users
* description: Returns a paginated list of all registered users.
* responses:
* 200:
* description: A list of users.
*/
public async index({ request, response }: HttpContextContract) {
const users = await User.query().paginate(request.input('page', 1))
return response.ok(users)
}
See how the @swagger comment block defines the endpoint? When you run your application, AdonisJS and the Swagger plugin will read these comments and build the interactive API documentation page automatically. Navigate to http://localhost:3333/docs, and you’ll see a fully interactive UI where you can test every endpoint.
But what about the code itself? The other half of the equation is documenting your TypeScript types, classes, and functions for your fellow developers. This is where TypeDoc comes in. It reads your TypeScript code and generates a clean website of your codebase structure. Create a typedoc.json file in your project root.
{
"entryPoints": ["app"],
"out": "docs/code",
"exclude": ["**/node_modules/**", "**/*.spec.ts", "**/*.test.ts"]
}
Now, document a service class. Good internal documentation explains the “why,” not just the “what.”
/**
* Handles the complex logic for processing and validating financial transactions.
* This service ensures all monetary operations adhere to business rules before
* they are committed to the database.
*/
export default class TransactionService {
/**
* Validates and creates a new transaction record.
* @param payload - The raw transaction data from the API request.
* @throws {ValidationException} If the payload fails business logic checks.
* @returns The newly created and sanitized Transaction model instance.
*/
public async create(payload: CreateTransactionDTO): Promise<Transaction> {
// ... implementation logic
}
}
To generate this internal documentation, you add a script to your package.json.
{
"scripts": {
"docs:code": "typedoc"
}
}
Run npm run docs:code, and TypeDoc will create a docs/code folder with an HTML site detailing all your modules, classes, and methods. This becomes an invaluable reference for onboarding new team members.
How do you ensure this documentation never gets stale? The answer is automation. We integrate documentation generation into our development workflow. For instance, we can set up a Git hook to ensure the Swagger spec is updated before every commit. Or, better yet, we make it part of our Continuous Integration (CI) pipeline. Here’s a simple GitHub Actions workflow that builds and deploys our docs on every push to the main branch.
name: Deploy Documentation
on:
push:
branches: [ main ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
- name: Install Dependencies
run: npm ci
- name: Generate API Docs
run: npm run build
- name: Generate Code Docs
run: npm run docs:code
- name: Deploy to Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs
This workflow does a few key things. It installs dependencies, builds the AdonisJS app (which generates the latest Swagger JSON), runs TypeDoc to generate the code documentation, and then publishes the entire docs folder to GitHub Pages. Now, your documentation is always up-to-date and publicly accessible with every release.
What’s the result of all this work? You end up with a self-documenting system. Your API consumers have a clear, interactive guide at https://your-api.com/docs. Your development team has a detailed code reference at https://your-company.github.io/repo/code. The support tickets about “how do I use this endpoint?” drop dramatically. New developers can understand the codebase in days instead of weeks. The documentation is no longer a chore; it’s a living part of the application that provides real value.
This approach transforms documentation from a static manual into a dynamic asset. It builds trust with your users and efficiency within your team. The initial setup takes a bit of time, but the long-term payoff in saved hours and reduced frustration is immense. Your future self—and every developer who interacts with your code—will thank you.
Did this guide help clarify the path to better API docs? If you found it useful, please share it with a colleague who might be battling outdated documentation. Have you tried a different approach that worked well? I’d love to hear about your experiences in the comments below. Let’s keep building tools that are a joy to use and a pleasure to maintain.
As a best-selling author, I invite you to explore my books on Amazon. Don’t forget to follow me on Medium and show your support. Thank you! Your support means the world!
101 Books
101 Books is an AI-driven publishing company co-founded by author Aarav Joshi. By leveraging advanced AI technology, we keep our publishing costs incredibly low—some books are priced as low as $4—making quality knowledge accessible to everyone.
Check out our book Golang Clean Code available on Amazon.
Stay tuned for updates and exciting news. When shopping for books, search for Aarav Joshi to find more of our titles. Use the provided link to enjoy special discounts!
📘 Checkout my latest ebook for free on my channel!
Be sure to like, share, comment, and subscribe to the channel!
Our Creations
Be sure to check out our creations:
Investor Central | Investor Central Spanish | Investor Central German | Smart Living | Epochs & Echoes | Puzzling Mysteries | Hindutva | Elite Dev | JS Schools
We are on Medium
Tech Koala Insights | Epochs & Echoes World | Investor Central Medium | Puzzling Mysteries Medium | Science & Epochs Medium | Modern Hindutva