likes
comments
collection
share

Koa+koa-swagger-decorator实战篇:打造高效优雅的API文档

作者站长头像
站长
· 阅读数 95

前言

好记性不如烂笔头,记录一下koa接入swagger踩得坑

So here's the question(那么问题来了),我们为什么要写接口文档呢?

为什么要写接口文档?

  1. 提供清晰的接口定义:接口文档可以详细描述接口的功能、参数、返回值等,使开发人员清楚了解如何正确调用接口。
  2. 促进团队合作:接口文档可以作为开发人员、产品经理、测试人员等不同角色之间的沟通工具,确保大家对接口的理解一致,减少沟通成本。
  3. 确保开发质量:接口文档可以作为开发人员编写单元测试、集成测试和验收测试的依据,确保开发过程中的质量控制。
  4. 方便接口调试和问题排查:接口文档可以帮助前后端开发人员在调试接口时快速定位问题,加快问题排查和解决的速度。
  5. 支持接口升级和扩展:接口文档可以指导开发人员进行接口的升级和扩展,同时也可以帮助其他开发人员快速了解新接口的使用方式。

所以写好接口文档是一个成熟的程序员必备的技能

安装

pnpm i koa-swagger-decorator@next //notice: 一定要加next,我们要使用最新的版本,2版本,如果不加的话,那么可能就会使用1版本了

有人这里可能要问了,为什么不用koa2-swagger-ui swagger-jsdoc呢,用过的小伙伴应该都知道,那文档真是越写越多,啥都要写,本来我使用swagger来减轻工作量的,结果工作量越来越大,这不和我们的初衷相反么。而有的小伙伴说koa-swagger-decorator的入侵性很强,不适合二次开发?我对此表示疑问。我觉得koa-swagger-decorator写起来方便,也方便修改。我觉得还好呀。

文档地址GitHub - Cody2333/koa-swagger-decorator: using decorator to automatically generate swagger doc for koa-router

大家如果有什么使用问题,也可以提issue,writer也会很快回答的right now

一个完整的配置过程

支持装饰器模式

因为要支持装饰器模式,所以要安装

pnpm install babel-plugin-transform-decorators-legacy

然后配置babelrc

{
  "presets": [["env", { "targets": { "node": "current" } }]],
  "plugins": ["transform-decorators-legacy"]
}

typescript配置

这是必须配置的

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

新建src/routes/index.ts文件

因为koa-swagger-decorator包括routes了,所以所有routes啥的都可以在这里配置,并且不需要引入 koa-router

import { SwaggerRouter } from 'koa-swagger-decorator';
import UserController from '../controller/user';
import { registerExtraComponents } from '../common/swagger-extra';

const router = new SwaggerRouter({
  spec: {
    info: {
      title: 'koa模版',
      version: 'v1.0',
    },
  },
  swaggerHtmlEndpoint: '/swagger-html',
  swaggerJsonEndpoint: '/swagger-json',
});

router.prefix('/api');

registerExtraComponents(router.registry);

// apply swagger docs routes
// 只开发环境运行
if (process.env.NODE_ENV === 'development') {
  router.swagger();
}
// register user defined routes implementation
router.applyRoute(UserController);
// .applyRoute(DemoController); // chained for more then one controller imports

export default router;

notice: 所有的Controller都要applyRoute,否则会不起作用

配置授权

这样我们就可以配合jwt使用了

export const AUTH_KEY = 'authorization';

export function registerExtraComponents(registry: any) {
  registry.registerComponent('securitySchemes', 'authorization', {
    type: 'apiKey',
    name: 'authorization',
    in: 'header',
  });

  registry.registerComponent('schemas', 'ExtraSchemasA', {
    type: 'object',
    properties: {
      id: {
        type: 'string',
      },
    },
  });
}

Koa+koa-swagger-decorator实战篇:打造高效优雅的API文档

notice: input内容的时候一定要加Bearer,不加的话不会生效,谨记

使用

import { routeConfig, z, body, ParsedArgs } from 'koa-swagger-decorator';
// 需要授权的接口要使用
import { AUTH_KEY } from '../../common/swagger-extra';
class UserController {
  @routeConfig({
    path: '/login',
    method: 'post',
    summary: 'user login',
    tags: ['USER'],
  })
  @body(CreateUserReq)
  async login(ctx: Models.Ctx, args: ParsedArgs<LoginType>) {
    const { username, password } = args.body as LoginType;
    const user = await ctx.model.User.findOne({
      where: { user_name: username },
    });
    if (!user) {
      ctx.fail('该用户不存在');
      return;
    }
    if (password !== user.password) {
      ctx.fail('密码错误');
      return;
    }
    const token = jwt.sign(
      {
        username,
      },
      Config.JWT.secret,
      { expiresIn: 60 * 60 }
    );
    ctx.success({ token }, '登录成功');
  }

  @routeConfig({
    // define your API route info using @routeConfig decorator
    method: 'get',
    path: '/users',
    summary: 'get users',
    tags: ['USER'],
    security: [{ [AUTH_KEY]: [] }], // notice: 需要授权的接口要加上security,不需要授权的就不需要写了
  })
  async getUsers(ctx: Models.Ctx) {
    const users = await ctx.model.User.findAll({
      attributes: {
        exclude: ['password'],
      },
    });
    ctx.success(users);
  }

  @routeConfig({
    method: 'post',
    path: '/register',
    summary: 'create user',
    tags: ['USER'],
  })
  @body(CreateUserReq)
  async register(ctx: Models.Ctx, args: ParsedArgs<RegisterType>) {
    const { password, username } = args.body as RegisterType;
    // TODO:增加判断是否有重复用户
    const user = await ctx.model.User.findOne({
      where: { user_name: username },
    });
    if (user) {
      ctx.fail('用户重复');
      return;
    }
    // TODO:密码检测
    // 注册
    await ctx.model.User.create({ password, user_name: username });
    ctx.success('', '注册成功');
  }
}

此时访问/api/swagger-html 就可以了

Koa+koa-swagger-decorator实战篇:打造高效优雅的API文档

配置了security的接口会有一把锁子的标志,需要设置Authorization才行 Koa+koa-swagger-decorator实战篇:打造高效优雅的API文档

总结

大家知道写一个接口文档很麻烦的,是一个重复的工作,有人说,大家接到需求的时候就要写呀,要不怎么前后端分离开发,可是随着接口体系的越来越庞大,所有的接口就需要一个总的文档,并且后续如果需要改接口的话,前端也可以很快进行修改,方便维护。

希望大家能从文章中学到东西,有什么使用问题都可以随时在评论区留言

参考

转载自:https://juejin.cn/post/7302344199445381158
评论
请登录