npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@omer-x/next-openapi-route-handler

v1.3.0

Published

a Next.js plugin to generate OpenAPI documentation from route handlers

Downloads

1,741

Readme

Next OpenAPI Route Handler

npm version npm downloads codecov License: MIT GitHub last commit GitHub issues GitHub stars

Overview

Next OpenAPI Route Handler is an open-source, lightweight, and easy-to-use Next.js plugin designed to build type-safe, self-documented APIs. It leverages TypeScript and Zod to create and validate route handlers, automatically generating OpenAPI documentation from your code. This package aims to simplify the process of building and documenting REST APIs with Next.js, ensuring your API endpoints are well-defined and compliant with OpenAPI specifications.

Key Features:

  • Type-Safe API Endpoints: Ensure your requests and responses are strongly typed with TypeScript.
  • Schema Validation: Use Zod schemas for object validation, automatically converted to JSON schema for OpenAPI.
  • Auto-Generated Documentation: Generate OpenAPI JSON specs from your route handlers.
  • Integration with Next.js: Works seamlessly with Next.js App Directory features.
  • Customizable: Compatible with existing Next.js projects and fully customizable to suit your needs.

Note: This package has a peer dependency on Next OpenAPI JSON Generator for extracting the generated OpenAPI JSON.

Requirements

To use @omer-x/next-openapi-route-handler, you'll need the following dependencies in your Next.js project:

Installation

To install this package, along with its peer dependency, run:

npm install @omer-x/next-openapi-route-handler @omer-x/next-openapi-json-generator

Usage

The defineRoute function is used to define route handlers in a type-safe and self-documenting way. Below is a description of each property of the input parameter:

| Property | Type | Description | | ------------- | ------------------------------------------------------------ | ---------------------------------------------------------------------------------------- | | operationId | string | Unique identifier for the operation. | | method | string | HTTP method for the route (e.g., GET, POST, PUT, PATCH, DELETE). | | summary | string | Short summary of the operation. | | description | string | Detailed description of the operation. | | tags | string[] | Tags for categorizing the operation. | | pathParams | ZodType | (Optional) Zod schema for validating path parameters. | | queryParams | ZodType | (Optional) Zod schema for validating query parameters. | | requestBody | ZodType | Zod schema for the request body (required for POST, PUT, PATCH). | | hasFormData | boolean | Is the request body a FormData | | action | (source: ActionSource) => Promise<Response> | Function handling the request, receiving pathParams, queryParams, and requestBody. | | responses | Record<number, ResponseDefinition> | Object defining possible responses, each with a description and optional content schema. | | handleErrors | (errorType: string, issues?: ZodIssues[]) => Response | (Optional) Custom error handler can be provided to replace the default behavior. See below |

Action Source

| Property | Type | Description | | ------------- | --------------------------- | -------------------------------------------- | | pathParams | ZodType | Parsed parameters from the request URL path. | | queryParams | ZodType | Parsed parameters from the request query. | | body | ZodType | Parsed request body. |

Response Definition

| Property | Type | Description | | ------------- | --------------------------- | ---------------------------------------------- | | description | string | Description of the response. | | content | ZodType | (Optional) Zod schema for the response body. | | isArray | boolean | (Optional) Is the content an array? |

Example

Here's an example of how to use defineRoute to define route handlers:

import defineRoute from "@omer-x/next-openapi-route-handler";
import z from "zod";

export const { GET } = defineRoute({
  operationId: "getUser",
  method: "GET",
  summary: "Get a specific user by ID",
  description: "Retrieve details of a specific user by their ID",
  tags: ["Users"],
  pathParams: z.object({
    id: z.string().describe("ID of the user"),
  }),
  action: async ({ pathParams }) => {
    const results = await db.select().from(users).where(eq(users.id, pathParams.id));
    const user = results.shift();
    if (!user) return new Response(null, { status: 404 });
    return Response.json(user);
  },
  responses: {
    200: { description: "User details retrieved successfully", content: UserDTO },
    404: { description: "User not found" },
  },
  // optional 👇👇👇
  handleErrors: (errorType, issues) => {
    console.log(issues);
    switch (errorType) {
      "PARSE_FORM_DATA":
      "PARSE_REQUEST_BODY":
      "PARSE_SEARCH_PARAMS":
        return new Response(null, { status: 400 });
      "PARSE_PATH_PARAMS":
        return new Response(null, { status: 404 });
      "UNNECESSARY_PATH_PARAMS":
      "UNKNOWN_ERROR":
        return new Response(null, { status: 500 });
    }
  },
});

This will generate an OpenAPI JSON like this:

{
  "openapi": "3.1.0",
  "info": {
    "title": "User Service",
    "version": "1.0.0"
  },
  "paths": {
    "/users": {
      "get": {
        ...
      },
      "post": {
        ...
      }
    },
    "/users/{id}": {
      "get": {
        "operationId": "getUser",
        "summary": "Get a specific user by ID",
        "description": "Retrieve details of a specific user by their ID",
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "description": "ID of the user",
            "schema": {
              "type": "string",
              "description": "ID of the user"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "User details retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserDTO"
                }
              }
            }
          },
          "404": {
            "description": "User not found"
          }
        }
      },
      "patch": {
        ...
      },
      "delete": {
        ...
      }
    }
  },
  "components": {
    "schemas": {
      "UserDTO": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique identifier of the user"
          },
          "name": {
            "type": "string",
            "description": "Display name of the user"
          },
          "email": {
            "type": "string",
            "description": "Email address of the user"
          },
          "password": {
            "type": "string",
            "maxLength": 72,
            "description": "Encrypted password of the user"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Creation date of the user"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Modification date of the user"
          }
        },
        "required": [
          "id",
          "name",
          "email",
          "password",
          "createdAt",
          "updatedAt"
        ],
        "additionalProperties": false,
        "description": "Represents the data of a user in the system."
      },
      "NewUserDTO": {
        ...
      },
      "UserPatchDTO": {
        ...
      }
    }
  }
}

Important: This package cannot extract the OpenAPI JSON by itself. Use Next OpenAPI JSON Generator to extract the generated data as JSON.

An example can be found here

Screenshots

| | | | | |:--------------:|:--------------:|:--------------:|:--------------:| | | | | |

License

This project is licensed under the MIT License. See the LICENSE file for details.