Boost API Development: Generate Docs From TRPC Schema
Hey folks! Ever felt lost in the labyrinth of undocumented APIs? It's a common pain, especially when you're a new developer trying to understand what's available, or a frontend developer trying to integrate. Let's talk about how to generate API documentation from tRPC schemas, making life easier for everyone involved.
The Problem: Undocumented APIs
The Struggle is Real
Imagine this: you've got a fantastic API built with tRPC, type-safe and efficient. But, gasp, it's undocumented! This situation leads to a few key problems. New developers struggle to figure out the endpoints, what they do, and how to use them. Frontend developers face integration hurdles, especially if you're planning a web UI. And, any potential third-party integrations become a nightmare. This whole scenario slows down development, onboarding, and collaboration. It's time to fix the problem with good API documentation!
The Current Situation
Thankfully, you're using tRPC, which is a big win. Your endpoints are well-defined in routers. Now, we need to focus on what's missing: public API documentation. That's where the magic begins!
The Solution: Generating API Documentation with tRPC
Embracing tRPC Documentation Options
Let's explore a few solid options for generating API documentation. We'll start with the recommended way and other methods available to the user. You can choose the method depending on your project's needs. We'll show you how to choose the right one for your development to production pipeline.
Option A: tRPC Panel (Recommended Approach)
This is a super cool, interactive API explorer directly generated from your tRPC router. It's like Swagger UI but tailored for tRPC. You can test endpoints live, which is fantastic for debugging and understanding how things work. Here's a quick code snippet to get you started:
import { renderTrpcPanel } from 'trpc-panel'
app.get('/panel', (c) => {
return c.html(
renderTrpcPanel(appRouter, {
url: 'https://your-api-url.com/trpc', // Replace with your API URL
})
)
})
Option B: OpenAPI Generator
For a more REST-style approach, you can generate an OpenAPI 3.0 spec from your tRPC schema. Then, use tools like Swagger UI or Redoc to display the documentation. OpenAPI is great for creating a standardized, REST-like documentation system. Use this if you need a static documentation file.
import { generateOpenApiDocument } from 'trpc-openapi'
const openApiDocument = generateOpenApiDocument(appRouter, {
title: 'Your API Name',
version: '1.0.0',
baseUrl: 'https://your-api-url.com/trpc', // Replace with your API URL
})
Option C: Custom Documentation
This involves writing markdown docs manually. It gives you the most control but requires more maintenance, so think about this option. We don't recommend this one, because it might take more time and you won't be able to show your methods correctly.
Recommendation: A Combined Approach
We recommend using tRPC Panel for your local development and OpenAPI for the production environment. This way, you get the best of both worlds: interactive exploration during development and standard, robust documentation for production.
Dive into tRPC Panel Implementation
Let's get tRPC Panel up and running. It's pretty straightforward, actually.
// apps/api/src/app.ts
import { renderTrpcPanel } from 'trpc-panel'
import { appRouter } from './router'
// Development only
if (process.env.NODE_ENV === 'development') {
app.get('/api-docs', (c) => {
return c.html(
renderTrpcPanel(appRouter, {
url: 'http://localhost:3000/trpc', // Replace with your development API URL
transformer: 'superjson',
})
)
})
}
Access this documentation at http://localhost:3000/api-docs (or your chosen URL). Pretty neat, right? Now, it will be easy to develop.
Enhance Documentation with JSDoc Comments
Supercharge Your Documentation
Want to make your documentation even better? Add JSDoc comments (or use the .meta() method) to your tRPC procedures. Here's how:
export const bookmarkRouter = router({
create: protectedProcedure
.meta({
openapi: {
method: 'POST',
path: '/bookmarks',
tags: ['bookmarks'],
summary: 'Create a new bookmark',
description: 'Creates a bookmark for the authenticated user. Title will be auto-fetched if not provided.',
},
})
.input(createBookmarkInputSchema)
.output(bookmarkSchema)
.mutation(async ({ input, ctx }) => {
// ...
}),
list: protectedProcedure
.meta({
openapi: {
method: 'GET',
path: '/bookmarks',
tags: ['bookmarks'],
summary: 'List user bookmarks',
description: 'Returns paginated list of bookmarks for the authenticated user. Can be filtered by tags.',
},
})
.input(listBookmarksInputSchema)
.output(listBookmarksOutputSchema)
.query(async ({ input, ctx }) => {
// ...
}),
})
This will help the generator to show your methods in a better way, which will facilitate the work of developers. This improves readability and provides context for each procedure, making the documentation more valuable. The generated documentation will be much more helpful for those who use your API.
OpenAPI Generation: Step-by-Step Guide
Generating the OpenAPI Spec
If you're using OpenAPI, you'll need a script to generate the spec. Here's an example:
// scripts/generate-openapi.ts
import { generateOpenApiDocument } from 'trpc-openapi'
import { appRouter } from '../src/router'
import { writeFileSync } from 'fs'
const openApiDocument = generateOpenApiDocument(appRouter, {
title: 'Your API Name',
description: 'A brief description of your API',
version: '1.0.0',
baseUrl: 'https://your-api-url.com', // Replace with your API URL
docsUrl: 'https://github.com/your-repo', // Link to your repo
tags: ['auth', 'bookmarks', 'tags'],
})
writeFileSync(
'openapi.json',
JSON.stringify(openApiDocument, null, 2)
)
console.log('✓ OpenAPI document generated: openapi.json')
Running the Script
Add these scripts to your package.json file:
{
"scripts": {
"docs:generate": "tsx scripts/generate-openapi.ts",
"docs:serve": "npx serve openapi.json" // You'll need to install 'serve'
}
}
Serving the OpenAPI Spec
Now, let's serve the OpenAPI spec using Swagger UI (or Redoc, if you prefer). Create a new endpoint in your API, like this:
// apps/api/src/app.ts
import { serve, setup } from 'swagger-ui-express'
import openApiDocument from './openapi.json'
app.get('/api-docs', serve)
app.get('/api-docs', setup(openApiDocument, {
customSiteTitle: 'Your API Docs',
customCss: '.swagger-ui .topbar { display: none }',
}))
And that's it! Your API documentation is now accessible through /api-docs (or whatever path you set). Now, enjoy your development.
Documentation Sections: What to Include
Essential Sections for API Documentation
Your API documentation should be comprehensive, including these key sections:
- Authentication: How to authenticate (OAuth flow, Bearer tokens, etc.)?
- Endpoints: Details for each CRUD operation (Create, Read, Update, Delete).
- Request/Response Schemas: What data is expected and returned?
- Error Codes: What can go wrong and what the error codes mean?
- Rate Limits: What are the limits?
- Examples: How to make requests and interpret responses.
Implementation Steps: A Quick Guide
The Path to API Documentation
Here's a handy checklist for getting your API documentation up and running:
- Choose your documentation approach: tRPC Panel, OpenAPI, or custom?
- Install the dependencies: See the dependencies section.
- Add the API documentation endpoint: Like
/api-docs. - Add JSDoc/
.meta()to your tRPC procedures: Describe your methods. - Generate the OpenAPI spec: (If you choose OpenAPI).
- Set up Swagger UI or Redoc: For the UI.
- Add authentication documentation: Explain authentication.
- Add examples: Include examples of requests and responses.
- Deploy your docs: Make them available.
- Add a link to the docs in your README: For easy access.
Dependencies: The Tools of the Trade
Essential Packages
Here's a list of the packages you'll need, depending on your chosen approach:
{
"trpc-panel": "^1.3.0", // Option A
"trpc-openapi": "^1.8.0", // Option B
"swagger-ui-express": "^5.0.0", // If using OpenAPI
"redoc": "^2.1.0" // Alternative to Swagger UI
}
Make sure to install these packages in your project to get started.
Access Control: Securing Your Documentation
Who Gets to See the Docs?
Consider these options for access control:
- Development: Open access to
/api-docsis fine. - Production:
- Public: If your API is public, make the docs public.
- Basic auth: Protect your docs with basic authentication.
- Internal: Restrict access using an internal rule (e.g., k8s ingress).
Choose the access control method that suits your API's purpose.
Success Criteria: What to Aim For
Measuring the Success of Your Documentation
Here's how to measure your success:
- API documentation is accessible.
- All endpoints are documented.
- Request/response schemas are displayed.
- Authentication is documented.
- Examples are provided.
- There's a link in your README.
- It's easy to keep up-to-date.
Related Benefits
Beyond Documentation
Generating API documentation has many benefits:
- Improved accessibility: Easier for current and future development.
- Smoother onboarding: Helps new team members quickly understand the API.
- Foundation for a public API: Ready to open up your API to the world!
That's it, guys! We hope this guide helps you boost your API development. Happy documenting!