next-swagger-doc
    Preparing search index...

    next-swagger-doc

    Welcome to next-swagger-doc 👋

    All Contributors

    Version Downloads/week Prerequisite Documentation License: MIT Twitter: jellydn

    Generate Swagger JSON API from NextJS Api Routes

    If you enjoy working with next-swagger-doc, you will love next-validations: NextJS API Validations, support Zod, Yup, Fastest-Validator, Joi, and more

    • Nextjs >= 9
    • Node >= 18

    This package reads your JSDoc-annotated source code on NextJS API route and generates an OpenAPI (Swagger) specification.

    nextjs + swagger-jsdoc = next-swagger-doc

    yarn add next-swagger-doc
    

    To incorporate next-swagger-doc with your Next.js 13 project, follow these steps. This setup will generate Swagger documentation for your API based on your code and provide a built-in Swagger UI for viewing the documentation.

    Next, create a new file lib/swagger.ts. This file uses the next-swagger-doc library to create a Swagger specification based on the API routes in your Next.js project.

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

    export const getApiDocs = async () => {
    const spec = createSwaggerSpec({
    apiFolder: "app/api", // define api folder under app folder
    definition: {
    openapi: "3.0.0",
    info: {
    title: "Next Swagger API Example",
    version: "1.0",
    },
    components: {
    securitySchemes: {
    BearerAuth: {
    type: "http",
    scheme: "bearer",
    bearerFormat: "JWT",
    },
    },
    },
    security: [],
    },
    });
    return spec;
    };

    Generate a new file named app/api-doc/react-swagger.tsx. In this file, create and export a React component that utilizes the swagger-ui-react library to render the Swagger UI according to the provided specification.

    For demonstration purposes, here is an example using swagger-ui-react

    Feel free to employ any alternative swagger UI library, such as stoplightio/elements. I have added an example using this library in the example folder.

    'use client';

    import SwaggerUI from 'swagger-ui-react';
    import 'swagger-ui-react/swagger-ui.css';

    type Props = {
    spec: Record<string, any>,
    };

    function ReactSwagger({ spec }: Props) {
    return <SwaggerUI spec={spec} />;
    }

    export default ReactSwagger;

    Create a new file app/api-doc/page.tsx. This page imports the Swagger spec and the Swagger UI component to display the Swagger documentation.

    import { getApiDocs } from "@/lib/swagger";
    import ReactSwagger from "./react-swagger";

    export default async function IndexPage() {
    const spec = await getApiDocs();
    return (
    <section className="container">
    <ReactSwagger spec={spec} />
    </section>
    );
    }

    Lastly, add a Swagger comment to your API route in app/api/hello/route.ts. This comment includes metadata about the API endpoint which will be read by next-swagger-doc and included in the Swagger spec.

    /**
    * @swagger
    * /api/hello:
    * get:
    * description: Returns the hello world
    * responses:
    * 200:
    * description: Hello World!
    */
    export async function GET(_request: Request) {
    // Do whatever you want
    return new Response('Hello World!', {
    status: 200,
    });
    }

    Now, navigate to localhost:3000/api-doc (or wherever you host your Next.js application), and you should see the swagger UI.

    https://gyazo.com/6bfa919c4969b000615df6bb9cabcd02.gif

    yarn add next-swagger-doc swagger-ui-react
    
    • Create an live swagger page, e.g: pages/api-doc.tsx
    import { GetStaticProps, InferGetStaticPropsType } from 'next';
    import { createSwaggerSpec } from 'next-swagger-doc';
    import dynamic from 'next/dynamic';
    import 'swagger-ui-react/swagger-ui.css';

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

    function ApiDoc({ spec }: InferGetStaticPropsType<typeof getStaticProps>) {
    return <SwaggerUI spec={spec} />;
    }

    export const getStaticProps: GetStaticProps = async () => {
    const spec: Record<string, any> = createSwaggerSpec({
    apiFolder: 'pages/api' // or 'src/pages/api',
    definition: {
    openapi: '3.0.0',
    info: {
    title: 'Next Swagger API Example',
    version: '1.0',
    },
    },
    });

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

    export default ApiDoc;

    https://gyazo.com/af250bab0d07f931c596ebc8c955ae2e.gif

    • Step 1: Create an api route on nextjs, e.g: pages/api/doc.ts
    import { withSwagger } from "next-swagger-doc";

    const swaggerHandler = withSwagger({
    definition: {
    openapi: "3.0.0",
    info: {
    title: "NextJS Swagger",
    version: "0.1.0",
    },
    },
    apiFolder: "pages/api",
    });
    export default swaggerHandler();
    • Step 2: Add JSdoc to any NextJS API routes, for example: pages/api/hello.ts
    import { NextApiRequest, NextApiResponse } from "next";

    /**
    * @swagger
    * /api/hello:
    * get:
    * description: Returns the hello world
    * responses:
    * 200:
    * description: hello world
    */
    const handler = (_req: NextApiRequest, res: NextApiResponse) => {
    res.status(200).json({
    result: "hello world",
    });
    };

    export default handler;
    • Step 3: Access the Swagger API doc

    https://gyazo.com/0bcf45f0e15778a5cb851b40526324f3.gif

    • Step 1: create a JSON config file as next-swagger-doc.json
    {
    "apiFolder": "pages/api",
    "schemaFolders": ["models"],
    "definition": {
    "openapi": "3.0.0",
    "info": {
    "title": "Next Swagger API Example",
    "version": "1.0"
    }
    }
    }
    • Step 2: run cli for generating swagger file
    yarn next-swagger-doc-cli next-swagger-doc.json
    
    gh repo clone jellydn/next-swagger-doc
    cd examples/next14-app
    pnpm install
    pnm run dev

    Then open http://localhost:3000/api-doc or http://localhost:3000/ on your browser ./example-screenshot.png

    In order to set an eslint rule that checks that all the APIs actually have a swagger JsDoc description we can use the following settings:

    Install the JsDoc eslint plugin:

    yarn add -D eslint-plugin-jsdoc
    

    Create the custom rule in your eslint configuration file:

    {
    //...your configuration
    "overrides": [
    //...your overrides
    {
    // Force the setting of a swagger description on each api endpoint
    "files": ["pages/api/**/*.ts"],
    "plugins": ["jsdoc"],
    "rules": {
    "jsdoc/no-missing-syntax": [
    "error",
    {
    "contexts": [
    {
    "comment": "JsdocBlock:has(JsdocTag[tag=swagger])",
    "context": "any",
    "message": "@swagger documentation is required on each API. Check this out for syntax info: https://github.com/jellydn/next-swagger-doc"
    }
    ]
    }
    ]
    }
    ]
    }

    This project uses pre-commit to enforce code quality. To install pre-commit hooks, run:

    pre-commit install
    

    👤 Huynh Duc Dung

    Stargazers repo roster for @jellydn/next-swagger-doc

    kofi paypal buymeacoffee

    Give a ⭐️ if this project helped you!

    Thanks goes to these wonderful people (emoji key):

    Dung Duc Huynh (Kaka)
    Dung Duc Huynh (Kaka)

    💻 📖
    tmirkovic
    tmirkovic

    📖
    Matthew Holloway
    Matthew Holloway

    💻
    leventemihaly
    leventemihaly

    📖
    PAHRIZAL MA'RUP
    PAHRIZAL MA'RUP

    💻
    Aris
    Aris

    📖
    Valerio Ageno
    Valerio Ageno

    📖
    cachho
    cachho

    💻

    This project follows the all-contributors specification. Contributions of any kind welcome!