在Ts.ED项目中使用Scalar构建API文档指南

在Ts.ED项目中使用Scalar构建API文档指南

【免费下载链接】tsed :triangular_ruler: Ts.ED is a Node.js and TypeScript framework on top of Express to write your application with TypeScript (or ES6). It provides a lot of decorators and guideline to make your code more readable and less error-prone. ⭐️ Star to support our work! 【免费下载链接】tsed 项目地址: https://gitcode.com/gh_mirrors/ts/tsed

前言:为什么选择Scalar作为API文档工具?

在现代Web开发中,API文档的质量直接影响开发效率和协作体验。传统的Swagger UI虽然功能强大,但在用户体验和现代化界面方面存在不足。Scalar作为新一代API文档工具,提供了更优秀的交互体验和更现代化的界面设计。

Ts.ED框架与Scalar的完美结合,让开发者能够通过简单的装饰器语法自动生成高质量的API文档,大大提升了开发效率和文档质量。

环境准备与安装

前置条件

在开始之前,请确保你的项目满足以下要求:

  • Node.js 16.0+ 版本
  • TypeScript 4.5+ 版本
  • 已初始化的Ts.ED项目

安装Scalar依赖

# 使用npm安装
npm install --save @tsed/scalar

# 或使用yarn安装
yarn add @tsed/scalar

基础配置

在Server配置文件中添加Scalar支持:

import "@tsed/platform-express";
import "@tsed/scalar"; // 导入Scalar模块
import { Configuration } from "@tsed/di";

@Configuration({
  scalar: [
    {
      path: "/doc",           // 文档访问路径
      specVersion: "3.0.1",   // OpenAPI规范版本
      showExplorer: true,     // 显示搜索框
      sortPaths: true         // 路径排序
    }
  ]
})
export class Server {}

核心功能详解

1. 模型定义与文档生成

使用Ts.ED的装饰器系统定义数据模型:

import { Description, Example, Property, Title } from "@tsed/schema";

export class CalendarModel {
  @Title("日历ID")
  @Description("日历的唯一标识符")
  @Example("cal_123456789")
  @Property()
  public id: string;

  @Title("日历名称")
  @Description("日历的显示名称")
  @Example("我的工作日历")
  @Property()
  public name: string;

  @Title("创建时间")
  @Description("日历的创建时间戳")
  @Property()
  public createdAt: Date;

  @Title("是否公开")
  @Description("标识日历是否对外公开")
  @Property()
  public isPublic: boolean;
}

2. 控制器端点文档

完整的控制器文档示例:

import { Controller } from "@tsed/di";
import { BodyParams, QueryParams, PathParams } from "@tsed/platform-params";
import { 
  Deprecated, 
  Description, 
  Get, 
  Post, 
  Put, 
  Delete, 
  Returns, 
  Security, 
  Summary 
} from "@tsed/schema";

import { CalendarModel } from "./models/Calendar";

@Controller("/calendars")
@Description("日历管理API")
export class CalendarCtrl {
  
  @Get("/:id")
  @Summary("获取单个日历")
  @Description("根据ID获取特定的日历信息")
  @Returns(200, CalendarModel).Description("成功返回日历数据")
  @Returns(404).Description("日历不存在")
  @Returns(500).Description("服务器内部错误")
  async getCalendar(
    @PathParams("id")
    @Description("日历ID")
    id: string
  ): Promise<CalendarModel> {
    return {} as CalendarModel;
  }

  @Get("/")
  @Summary("获取日历列表")
  @Description("获取所有日历的列表,支持分页和筛选")
  @Returns(200, Array).Of(CalendarModel).Description("日历列表")
  async getCalendars(
    @QueryParams("page")
    @Description("页码")
    page: number = 1,
    
    @QueryParams("limit")
    @Description("每页数量")
    limit: number = 10
  ): Promise<CalendarModel[]> {
    return [];
  }

  @Post("/")
  @Summary("创建新日历")
  @Description("创建一个新的日历")
  @Security("calendar_auth", "write:calendar")
  @Returns(201, CalendarModel).Description("成功创建日历")
  @Returns(400).Description("请求参数错误")
  async createCalendar(
    @BodyParams() 
    @Description("日历创建数据")
    calendarData: Partial<CalendarModel>
  ): Promise<CalendarModel> {
    return {} as CalendarModel;
  }

  @Put("/:id")
  @Summary("更新日历")
  @Description("更新指定日历的信息")
  @Security("calendar_auth", "write:calendar")
  @Returns(200, CalendarModel).Description("成功更新日历")
  @Returns(404).Description("日历不存在")
  async updateCalendar(
    @PathParams("id") id: string,
    @BodyParams() updateData: Partial<CalendarModel>
  ): Promise<CalendarModel> {
    return {} as CalendarModel;
  }

  @Delete("/:id")
  @Summary("删除日历")
  @Description("删除指定的日历")
  @Security("calendar_auth", "write:calendar")
  @Returns(204).Description("成功删除日历")
  @Returns(404).Description("日历不存在")
  async deleteCalendar(
    @PathParams("id") id: string
  ): Promise<void> {
    // 删除逻辑
  }
}

3. 高级配置选项

Scalar提供了丰富的配置选项来定制文档行为:

@Configuration({
  scalar: [
    {
      path: "/api-doc",
      specVersion: "3.1.0",
      fileName: "openapi.json",
      showExplorer: true,
      sortPaths: true,
      hidden: false,
      spec: {
        openapi: "3.1.0",
        info: {
          title: "日历管理系统API",
          version: "1.0.0",
          description: "提供完整的日历管理功能",
          contact: {
            name: "技术支持",
            email: "support@example.com"
          }
        },
        servers: [
          {
            url: "https://api.example.com/v1",
            description: "生产环境"
          },
          {
            url: "http://localhost:8000/v1",
            description: "开发环境"
          }
        ]
      },
      options: {
        theme: "purple",
        layout: "modern",
        search: true,
        defaultHttpMethod: "GET"
      }
    }
  ]
})
export class Server {}

安全配置与CSP处理

Helmet安全中间件配置

当使用Helmet时,需要正确配置CSP(Content Security Policy):

import helmet from "helmet";

@Configuration({
  middlewares: [
    helmet({
      contentSecurityPolicy: {
        directives: {
          defaultSrc: [`'self'`],
          styleSrc: [`'self'`, `'unsafe-inline'`],
          imgSrc: [`'self'`, "data:", "validator.scalar.io"],
          scriptSrc: [`'self'`, `https: 'unsafe-inline'`]
        }
      }
    })
  ],
  scalar: [
    {
      path: "/doc",
      specVersion: "3.0.1"
    }
  ]
})
export class Server {}

认证与授权配置

@Configuration({
  scalar: [
    {
      path: "/doc",
      specVersion: "3.0.1",
      options: {
        authentication: {
          preferredSecurityScheme: "bearer",
          securitySchemes: {
            bearer: {
              type: "http",
              scheme: "bearer",
              bearerFormat: "JWT"
            }
          }
        }
      }
    }
  ]
})
export class Server {}

多文档管理

基于装饰器的多文档

@Configuration({
  scalar: [
    {
      path: "/admin-doc",
      doc: "admin",
      spec: {
        info: {
          title: "管理后台API",
          version: "1.0.0"
        }
      }
    },
    {
      path: "/user-doc", 
      doc: "user",
      spec: {
        info: {
          title: "用户端API",
          version: "1.0.0"
        }
      }
    }
  ]
})
export class Server {}

控制器级别的文档分配

import { Docs } from "@tsed/schema";

@Controller("/admin/calendars")
@Docs("admin")
export class AdminCalendarCtrl {
  // 管理端API
}

@Controller("/user/calendars")  
@Docs("user")
export class UserCalendarCtrl {
  // 用户端API
}

最佳实践与技巧

1. 统一的响应格式

import { Property } from "@tsed/schema";

export class ApiResponse<T> {
  @Property()
  success: boolean;

  @Property()
  message: string;

  @Property()
  data?: T;

  @Property()
  timestamp: Date = new Date();

  constructor(success: boolean, message: string, data?: T) {
    this.success = success;
    this.message = message;
    this.data = data;
  }
}

// 在控制器中使用
@Returns(200, ApiResponse).Of(CalendarModel)
async getCalendar(): Promise<ApiResponse<CalendarModel>> {
  return new ApiResponse(true, "操作成功", calendarData);
}

2. 错误处理与文档

export class ErrorResponse {
  @Property()
  statusCode: number;

  @Property()
  message: string;

  @Property()
  error: string;

  @Property()
  timestamp: Date;
}

// 在控制器中定义错误响应
@Returns(400, ErrorResponse).Description("参数验证失败")
@Returns(401, ErrorResponse).Description("未授权访问")
@Returns(403, ErrorResponse).Description("权限不足")
@Returns(404, ErrorResponse).Description("资源不存在")
@Returns(500, ErrorResponse).Description("服务器内部错误")

3. 枚举类型文档

import { Enum } from "@tsed/schema";

export enum CalendarStatus {
  ACTIVE = "active",
  INACTIVE = "inactive",
  ARCHIVED = "archived"
}

export class CalendarModel {
  @Property()
  @Enum(CalendarStatus)
  @Description("日历状态: active-活跃, inactive-未激活, archived-已归档")
  status: CalendarStatus;
}

常见问题解决方案

问题1:CSP策略冲突

症状:Scalar界面无法正常加载样式和脚本 解决方案:正确配置Helmet的CSP策略

helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: [`'self'`],
      styleSrc: [`'self'`, `'unsafe-inline'`],
      imgSrc: [`'self'`, "data:", "validator.scalar.io"],
      scriptSrc: [`'self'`, `https: 'unsafe-inline'`]
    }
  }
})

问题2:文档不更新

症状:代码修改后文档没有实时更新 解决方案:确保开发模式下启用热重载

# 使用Ts.ED的开发模式
npm run start:dev

问题3:类型定义不显示

症状:复杂类型在文档中显示为object 解决方案:使用@Returns明确指定返回类型

@Returns(200, ApiResponse).Of(CalendarModel).Description("成功响应")

性能优化建议

1. 生产环境配置

const isProduction = process.env.NODE_ENV === "production";

@Configuration({
  scalar: isProduction ? [
    {
      path: "/doc",
      specVersion: "3.0.1",
      showExplorer: false, // 生产环境关闭搜索框
      options: {
        theme: "default",
        layout: "classic"
      }
    }
  ] : [
    {
      path: "/doc",
      specVersion: "3.0.1",
      showExplorer: true,
      options: {
        theme: "purple",
        layout: "modern"
      }
    }
  ]
})
export class Server {}

2. CDN优化

@Configuration({
  scalar: [
    {
      path: "/doc",
      specVersion: "3.0.1",
      cdn: "https://cdn.jsdelivr.net/npm/@scalar/api-reference@latest"
    }
  ]
})
export class Server {}

总结

通过本指南,你应该已经掌握了在Ts.ED项目中集成和使用Scalar API文档工具的全部技能。Scalar不仅提供了美观的界面,更重要的是它与Ts.ED框架的无缝集成,让API文档的维护变得简单高效。

记住良好的API文档是项目成功的关键因素之一,它不仅能提升开发效率,还能改善团队协作体验。现在就开始为你的Ts.ED项目配置Scalar,享受现代化API文档带来的便利吧!

下一步建议

  1. 为现有API添加完整的文档注释
  2. 配置多环境文档策略
  3. 集成自动化文档生成到CI/CD流程
  4. 定期审查和更新API文档

【免费下载链接】tsed :triangular_ruler: Ts.ED is a Node.js and TypeScript framework on top of Express to write your application with TypeScript (or ES6). It provides a lot of decorators and guideline to make your code more readable and less error-prone. ⭐️ Star to support our work! 【免费下载链接】tsed 项目地址: https://gitcode.com/gh_mirrors/ts/tsed

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值