Git Product home page Git Product logo

koa-swagger-decorator's Introduction

koa-swagger-decorator

defined your api with simple decorators and generate api docs automatically

Important

this docs is written for V2 and it's currently under development. refer to V1 Docs for V1 version

V2 version has undergone complete refactoring, introducing break change and new APIs to provide more type-safe functionality.

  1. Installation

  2. Introduction

  3. Usage

    1. Quick Example
    2. Runnable Example
    3. Typescript Configuration
    4. Integrate with Koa
    5. Define query/path params
    6. Define body/responses params
    7. Using router.prefix
    8. Using Middlewares
  4. TODO List

Installation

npm i koa-swagger-decorator@next

Introduction

Developing your type-safe API using simple decorators and zod schema with auto-generated OpenAPI docs based on OpenAPI V3.

Usage

Quick Example

// define your api handler with @routeConfig decorator and it will generate OpenAPI Docs automatically
class UserController {
  @routeConfig({ // define your API route info using @routeConfig decorator
    method: "post",
    path: "/users",
    summary: "create a user",
    tags: ["USER"],
    operationId: "CreateUser",
  })
  @body(z.object({uid: z.string(), name: z.string(), age: z.number().min(18).optional()}))
  async CreateUser(ctx: Context, args) {
    // body params will be validated using zodSchema.parse(ctx.request.body)
    // and assigned the parsed value to args.
    console.log(args, args.body.uid, args.body.name);
    ctx.body = { message: "create", id: "123" } as ICreateUserRes;
  }
}

Runnable Example

you can refer to example dir for details.

git clone https://github.com/Cody2333/koa-swagger-decorator.git
cd koa-swagger-decorator
npm i
npm run dev

// open http://localhost:3000/api/swagger-html to execute api
// open example dir for detail codes.

Typescript Configuration

typescript is required. Please make sure compilerOptions is set correctly in tsconfig.json

// tsconfig.json
{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "esModuleInterop": true,
  }
}

Integrate with Koa

following below steps to integrate your koa application with koa-swagger-decorator

  1. Define your Request/Response with Zod Schema
// file -> ./schema/user.ts
import { z } from 'koa-swagger-decorator'
// define req/res schema
const CreateUserReq = z.object({
  uid: z.string().nonempty(),
  name: z.string().nullable().optional(),
  age: z.number().min(18).nullable(),
  operator: z.string().nonempty().optional(),
});

const CreateUserRes = z.object({
  id: z.string().nullable(),
  message: z.string().nullable(),
});

// export req/res typings
export type ICreateUserRes = z.infer<typeof CreateUserRes>;
export type ICreateUserReq = z.infer<typeof CreateUserReq>;
  1. Write your API Handler with decorator and zod schema
// file -> ./controller/user.ts
import { Context } from "koa";
import { body, responses, routeConfig } from "../../lib/decorator";
import {
  CreateUserReq,
  CreateUserRes,
} from "../schemas/user";
import { ParsedArgs, z } from "../../lib";

class UserController {
 
  @routeConfig({ // define your API route info using @routeConfig decorator
    method: "post",
    path: "/users",
    summary: "create a user",
    tags: ["USER"],
    operationId: "CreateUser",
  })
  @body(CreateUserReq)
  @responses(CreateUserRes)
  async CreateUser(ctx: Context, args: ParsedArgs<ICreateUserReq>) {
    // args is injected with values = CreateUserReq.parse(ctx.request.body)
    console.log(args, args.body.uid, args.body.name);
    ctx.body = { message: "create", id: "123" } as ICreateUserRes;
  }

}

export { UserController };
  1. Init SwaggerRouter Instance
// file -> ./routes/index.ts
import { SwaggerRouter } from 'koa-swagger-decorator'
import { UserController } from './controller/user'

const router = new SwaggerRouter({
  spec: {
    info: {
      title: "Example API Server",
      version: "v1.0",
    },
  },
  swaggerHtmlEndpoint: '/swagger-html',
  swaggerJsonEndpoint: '/swagger-json',
});

// apply swagger docs routes
router.swagger();

// register user defined routes implementation
router
  .applyRoute(UserController)
  // .applyRoute(DemoController); // chained for more then one controller imports

export {router}
  1. Init Koa Application
// file -> ./main.ts
import {router} from './routes/index'
const app = new Koa();
app
  .use(cors())
  .use(bodyParser())
  .use(router.routes())
  .use(router.allowedMethods());

export default app.listen(config.port, () => {
  console.log(`App is listening on ${config.port}.`);
});

// running ts-node ./main.ts and that's all

Define query/path params

@routeConfig({
  method: "get",
  path: "/user/{uid}",
  summary: "get user by id",
  description: "detailed user",
  tags: ["USER"],
  operationId: "GetUserById",
  request: {
    params: z.object({
      uid: z.string().nonempty(), // path params, don't forget to add {uid} in [path] field.
    }),
    query: z.object({
      count: z.coerce.number().default(10), // using z.coerce to convert query string into number & validate
      limit: z.coerce.number().default(0),
    })
  },
})

Define body/responses params

define params by adding @body/@responses decorators to your handler

  @routeConfig({
    path: "/users/update",
    method: "put",
    tags: ["USER"],
    operationId: "UpdateUser",
  })
  @body([ZodSchema])
  @responses([ZodSchema])

Using router.prefix

const router = new SwaggerRouter({});

router.prefix("/api");

by calling router.prefix, your swagger docs routes & biz routes will automatically add prefix "/api". Open http://localhost:3000/api/swagger-html to get swagger docs.

Using Middlewares

using @middlewares decorator for your handler method

  @middlewares([
    async (ctx, next) => {
      const x = ctx._swagger_decorator_meta as ItemMeta; // get swagger decorator meta info through ctx
      console.log("biz mid", x.routeConfig);
      await next();
    },
  ])

TODO List

  • support request validation
  • support response validation
  • support middleware decorator
  • support adding exist components to spec
  • support generate openapi docs without starting app
  • add unit test
  • support form-data request
  • support define non-200 responses
  • support class decorators

koa-swagger-decorator's People

Contributors

cody2333 avatar sedationh avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.