API 文档和 Swagger 指南

欢迎使用 Finch API 文档和 Swagger 指南!本指南将引导您完成记录 Finch 应用程序的 API 并集成 Swagger 以实现交互式 API 文档的步骤。无论您是经验丰富的开发人员还是刚刚起步,Finch 都提供了一套强大的工具来简化服务器端 Web 应用程序开发。

定义 API 文档

API 文档涉及 3 个主要部分:

  • 将 Swagger 添加到路由
  • 添加 ApiDoc 路由
  • 为每个路由定义 ApiDoc

Finch 提供了一种使用 ApiDoc 类记录 API 端点的便捷方法。ApiDoc 类允许您为 API 端点定义参数、请求正文和响应结构。以下是使用示例:

API 文档控制器

final apiController = ApiController(
   title: "API Documentation",
   app: app,
);
// 应添加到 FinchApp 路由的路由
// OpenApi json 输出
FinchRoute(
    key: 'root.api.docs',
    path: 'api/docs',
    index: apiController.indexPublic,
),
// Swagger UI
FinchRoute(
    key: 'root.swagger',
    path: 'swagger',
    index: () => apiController.swagger(rq.url('api/docs')),
),

为每个路由定义 ApiDoc

class ApiDocuments {
    static Future<ApiDoc> onePerson() async {
    return ApiDoc(
      post: ApiDoc(
        response: {
          '200': [
            ApiResponse<int>('timestamp_start', def: 0),
            ApiResponse<bool>('success', def: true),
            ApiResponse<Map<String, String>>(
              'data',
              def: PersonCollectionFree.formPerson.fields.map((k, v) {
                return MapEntry(k, v.defaultValue?.call());
              }),
            ),
          ],
          '404': r_404,
        },
        description: "根据 id 更新一个人。",
        parameters: [
          ApiParameter<String>(
            'id',
            isRequired: true,
            paramIn: ParamIn.path,
          ),
          ApiParameter<String>(
            'name',
            isRequired: false,
            paramIn: ParamIn.header,
          ),
          ApiParameter<int>(
            'age',
            isRequired: false,
            paramIn: ParamIn.header,
          ),
          ApiParameter<double>(
            'height',
            isRequired: false,
            paramIn: ParamIn.header,
          ),
          ApiParameter<String>(
            'email',
            isRequired: true,
            paramIn: ParamIn.header,
          ),
          ApiParameter<String>(
            'married',
            isRequired: false,
            paramIn: ParamIn.header,
            def: false,
          ),
        ],
      ),
      get: ApiDoc(
        response: {
          '200': [
            ApiResponse<int>('timestamp_start', def: 0),
            ApiResponse<Map<String, String>>(
              'data',
              def: PersonCollectionFree.formPerson.fields.map((k, v) {
                return MapEntry(k, v.defaultValue?.call());
              }),
            ),
          ],
          '404': r_404,
        },
        description: "根据 id 获取一个人。",
        parameters: [
          ApiParameter<String>('id', isRequired: true, paramIn: ParamIn.path),
        ],
      ),
      delete: ApiDoc(
        response: {
          '200': [
            ApiResponse<int>('timestamp_start', def: 0),
            ApiResponse<bool>('success', def: true),
          ],
          '404': r_404,
        },
        description: "根据 id 删除一个人。",
        parameters: [
          ApiParameter<String>('id', isRequired: true, paramIn: ParamIn.path),
        ],
      ),
    );
  }
}

/// 为路由添加 ApiDoc 示例
FinchRoute(
  key: 'root.person.show',
  path: 'api/person/{id}',
  extraPath: ['example/person/{id}'],
  index: homeController.onePerson,
  methods: Methods.GET_POST,
  apiDoc: ApiDocuments.onePerson,
),