Skip to content

Add API documentation with Swagger/OpenAPI #934

@jeromehardaway

Description

@jeromehardaway

Description

Document all API endpoints using OpenAPI (Swagger) specification for clear API documentation.

Installation

npm install next-swagger-doc swagger-ui-react

Configuration

Create Swagger Config

Create swagger.ts:

import { createSwaggerSpec } from 'next-swagger-doc';

export const getApiDocs = () => {
  const spec = createSwaggerSpec({
    apiFolder: 'src/pages/api',
    definition: {
      openapi: '3.0.0',
      info: {
        title: 'Vets Who Code API',
        version: '1.0.0',
        description: 'API documentation for Vets Who Code application',
        contact: {
          name: 'Vets Who Code',
          url: 'https://vetswhocode.io',
          email: 'support@vetswhocode.io',
        },
      },
      servers: [
        {
          url: 'http://localhost:3000',
          description: 'Development server',
        },
        {
          url: 'https://vetswhocode.io',
          description: 'Production server',
        },
      ],
      components: {
        securitySchemes: {
          BearerAuth: {
            type: 'http',
            scheme: 'bearer',
            bearerFormat: 'JWT',
          },
        },
      },
    },
  });

  return spec;
};

API Documentation Page

Create src/pages/api-docs.tsx:

import { GetStaticProps } from 'next';
import dynamic from 'next/dynamic';
import 'swagger-ui-react/swagger-ui.css';
import { getApiDocs } from '../swagger';

const SwaggerUI = dynamic(() => import('swagger-ui-react'), { ssr: false });

export default function ApiDoc({ spec }: { spec: any }) {
  return <SwaggerUI spec={spec} />;
}

export const getStaticProps: GetStaticProps = async () => {
  const spec = getApiDocs();

  return {
    props: {
      spec,
    },
  };
};

Document API Routes

Example: Courses API

// src/pages/api/courses/index.ts

/**
 * @swagger
 * /api/courses:
 *   get:
 *     summary: Get all courses
 *     description: Returns a list of all available courses
 *     tags:
 *       - Courses
 *     parameters:
 *       - in: query
 *         name: difficulty
 *         schema:
 *           type: string
 *           enum: [BEGINNER, INTERMEDIATE, ADVANCED]
 *         description: Filter by difficulty level
 *       - in: query
 *         name: published
 *         schema:
 *           type: boolean
 *         description: Filter by published status
 *     responses:
 *       200:
 *         description: Successful response
 *         content:
 *           application/json:
 *             schema:
 *               type: array
 *               items:
 *                 $ref: '#/components/schemas/Course'
 *       500:
 *         description: Server error
 */
export default async function handler(req, res) {
  // Implementation
}

/**
 * @swagger
 * components:
 *   schemas:
 *     Course:
 *       type: object
 *       required:
 *         - id
 *         - title
 *         - slug
 *       properties:
 *         id:
 *           type: string
 *           description: Course ID
 *         title:
 *           type: string
 *           description: Course title
 *         slug:
 *           type: string
 *           description: URL-friendly slug
 *         description:
 *           type: string
 *           description: Course description
 *         difficulty:
 *           type: string
 *           enum: [BEGINNER, INTERMEDIATE, ADVANCED]
 *         estimatedHours:
 *           type: number
 *           description: Estimated completion time in hours
 */

Authentication Endpoint

/**
 * @swagger
 * /api/auth/login:
 *   post:
 *     summary: User login
 *     tags:
 *       - Authentication
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required:
 *               - email
 *               - password
 *             properties:
 *               email:
 *                 type: string
 *                 format: email
 *               password:
 *                 type: string
 *                 format: password
 *     responses:
 *       200:
 *         description: Login successful
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 token:
 *                   type: string
 *                 user:
 *                   $ref: '#/components/schemas/User'
 *       401:
 *         description: Invalid credentials
 *       500:
 *         description: Server error
 */

JSON Response Endpoint

Create src/pages/api/docs.ts:

import { getApiDocs } from '../../swagger';

export default function handler(req, res) {
  const spec = getApiDocs();
  res.status(200).json(spec);
}

Tasks

  • Install swagger dependencies
  • Create swagger configuration
  • Create API documentation page
  • Document authentication endpoints
  • Document course endpoints
  • Document user endpoints
  • Document enrollment endpoints
  • Add schemas for all models
  • Test documentation page: http://localhost:3000/api-docs
  • Link API docs from main site

API Endpoints to Document (Priority)

  1. Authentication (/api/auth/*)
  2. Courses (/api/courses/*)
  3. Users (/api/users/*)
  4. Enrollments (/api/enrollments/*)
  5. Blog posts (/api/posts/*)

Benefits

  • Clear API contract
  • Easy for frontend developers
  • Interactive testing interface
  • Auto-generated client libraries
  • Better API versioning

Learning Outcomes

  • Understanding OpenAPI specification
  • Learning API documentation
  • Practice with Swagger
  • Understanding REST APIs

Estimated Time

3-4 hours

Additional Resources

Priority

Low - Nice to have

Difficulty

Intermediate

Metadata

Metadata

Assignees

Labels

FeaturedocumentationDocumentation improvementsintermediateRequires moderate codebase familiarity; multi-file or design judgment

Type

No type

Projects

Status

Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions