GoWind 开源生态GoWind 开源生态
首页
框架
GoWind Admin
GoWind CMS
GoWind IM
GoWind UBA
GoWind IoT
GoWind Toolkit
GoWind Quant
GitHub
首页
框架
GoWind Admin
GoWind CMS
GoWind IM
GoWind UBA
GoWind IoT
GoWind Toolkit
GoWind Quant
GitHub
  • 介绍

    • GoWind CMS 产品介绍
    • GoWind CMS 安装指南
  • 后端文档

    • CMS 后端架构总览
    • CMS 后端模块总览
    • CMS Protobuf API 定义
    • CMS 配置与部署指南
    • 后端扩展机制指南
  • 前端文档

    • CMS 前端架构
    • CMS 前端模块总览
  • 入门教程

    • 新增内容类型全栈实战教程
    • 多端 API 客户端代码生成教程
  • 核心教程

    • 内容多语言翻译实战教程
    • 内容发布工作流实战教程
    • 区块编辑器实战教程
    • Headless API 对接多端实战教程
    • 前台应用开发实战教程
  • 进阶教程

    • 多站点管理实战教程
    • 媒体资源管理实战教程
    • 评论系统实战教程
    • 事件总线架构实战教程
    • Lua 脚本扩展实战教程
  • 高阶教程

    • 权限系统实战教程
    • 双端登录安全实战教程
    • 加密与安全工具实战教程
    • 全文搜索实战教程
    • 任务调度实战教程
    • 实时消息推送实战教程
    • 性能监控实战教程
    • 字典管理系统实战教程
  • 综合教程

    • 全栈集成实战教程
    • 三服务部署实战教程

多端 API 客户端代码生成教程

GoWind CMS 采用 Protobuf First 的开发模式,通过 Buf 工具链自动生成多端 API 客户端代码。本教程讲解如何为管理后台(TypeScript)和前台应用(TypeScript/Dart)生成 API 客户端。

前置条件

  • 已阅读 CMS Protobuf API 定义
  • 了解 Protobuf / Buf 基本概念

一、代码生成架构

1.1 生成流程

1.2 生成的代码用途

输出语言目录用途
Go 代码Goapi/gen/go/后端服务端
TypeScriptTSapi/gen/ts/admin/管理后台前端
TypeScriptTSapi/gen/ts/app/React/Vue 前台
DartDartapi/gen/dart/Flutter 前台
OpenAPIYAMLapi/gen/openapi/API 文档 + 代码生成

二、Buf 配置

2.1 buf.gen.yaml

# buf.gen.yaml - Go 代码生成
version: v1
plugins:
  - plugin: go
    out: api/gen/go
    opt: paths=source_relative

  - plugin: go-grpc
    out: api/gen/go
    opt:
      - paths=source_relative
      - require_unimplemented_servers=false

  - plugin: go-http
    out: api/gen/go
    opt: paths=source_relative

2.2 TypeScript 代码生成

# buf.gen.ts.yaml
version: v1
plugins:
  - plugin: ts
    out: api/gen/ts/admin
    opt:
      - paths=source_relative
      - target=admin
    path: protoc-gen-ts

  - plugin: ts
    out: api/gen/ts/app
    opt:
      - paths=source_relative
      - target=app
    path: protoc-gen-ts

2.3 OpenAPI 生成

# buf.gen.openapi.yaml
version: v1
plugins:
  - plugin: openapiv2
    out: api/gen/openapi
    opt:
      - logtostderr=true
      - simple_operation_ids=true

2.4 Dart 代码生成

# buf.gen.dart.yaml
version: v1
plugins:
  - plugin: dart
    out: api/gen/dart

三、生成命令

3.1 Makefile

# 生成所有代码(Go + TS + Dart + OpenAPI)
gen: api ent wire ts openapi dart

# Go Protobuf 代码
api:
	buf generate

# TypeScript 代码
ts:
	buf generate --template buf.gen.ts.yaml

# OpenAPI 文档
openapi:
	buf generate --template buf.gen.openapi.yaml

# Dart 代码
dart:
	buf generate --template buf.gen.dart.yaml

# Ent ORM 代码
ent:
	go generate ./app/core/service/internal/data/ent

# Wire 依赖注入
wire:
	cd app/core/service/cmd/server && wire
	cd app/admin/service/cmd/server && wire
	cd app/app/service/cmd/server && wire

3.2 执行

cd backend

# 一键生成全部
make gen

# 单独生成 TypeScript
make ts

# 单独生成 OpenAPI
make openapi

四、TypeScript 客户端

4.1 生成的 API 客户端

生成的 TypeScript 代码提供类型安全的 API 调用:

// api/gen/ts/admin/service/v1/PostService.ts(自动生成)
export class PostServiceClient {
  async List(params: PagingRequest): Promise<ListPostResponse> {
    return httpClient.get('/admin/v1/posts', { params });
  }

  async Get(id: number, locale?: string): Promise<Post> {
    return httpClient.get(`/admin/v1/posts/${id}`, { params: { locale } });
  }

  async Create(data: CreatePostRequest): Promise<Post> {
    return httpClient.post('/admin/v1/posts', { data });
  }

  async Update(id: number, data: UpdatePostRequest): Promise<Post> {
    return httpClient.put(`/admin/v1/posts/${id}`, { data });
  }

  async Delete(id: number): Promise<void> {
    return httpClient.delete(`/admin/v1/posts/${id}`);
  }
}

4.2 管理后台使用

// frontend/admin/src/api/client.ts
import { PostServiceClient } from '@/api/generated';

export const apiClient = {
  postService: new PostServiceClient(),
  categoryService: new CategoryServiceClient(),
  // ... 其他 Service
};

4.3 Vue Query 封装

// frontend/admin/src/api/composables/post.ts
export function useListPosts(query: Ref<PaginationQuery>) {
  return useQuery({
    queryKey: ['listPosts', query],
    queryFn: () => apiClient.postService.List(query.value.toRawParams()),
  });
}

五、Flutter 客户端生成

5.1 swagger_parser 方式

Flutter 推荐使用 swagger_parser 从 OpenAPI 文档生成 Dart 代码:

# flutter_app/build.yaml
targets:
  $default:
    builders:
      swagger_parser:
        options:
          output_dir: 'lib/core/network/generated'
          input_path: '../../../backend/api/gen/openapi/admin.swagger.json'
          api_base_url: 'http://localhost:6700/app/v1'
          use_path_for_request: true
# 生成 Dart API 客户端
cd frontend/app/flutter_app
dart run build_runner build

5.2 生成的 Retrofit API

// lib/core/network/generated/api/post_api.dart(自动生成)
@RestApi(baseUrl: '/app/v1')
abstract class PostApi {
  factory PostApi(Dio dio, {String? baseUrl}) = _PostApi;

  @GET('/posts')
  Future<ListPostResponse> listPosts({
    @Query('locale') String? locale,
    @Query('page') int? page,
    @Query('pageSize') int? pageSize,
  });

  @GET('/posts/{id}')
  Future<Post> getPost(
    @Path('id') int id, {
    @Query('locale') String? locale,
  });
}

5.3 Repository 封装

// features/post_detail/domain/repository/post_repository.dart
class PostRepositoryImpl implements PostRepository {
  final PostApi _api;

  PostRepositoryImpl(this._api);

  @override
  Future<Post> getPost({required int id, required String locale}) async {
    return await _api.getPost(id, locale: locale);
  }

  @override
  Future<ListPostResponse> getPosts({
    required String locale,
    int page = 1,
    int pageSize = 10,
  }) async {
    return await _api.listPosts(
      locale: locale,
      page: page,
      pageSize: pageSize,
    );
  }
}

六、OpenAPI 文档

6.1 访问 Swagger UI

三个服务都内置了 Swagger 文档:

# Admin API Swagger
http://localhost:6600/docs/

# App API Swagger
http://localhost:6700/docs/

6.2 从 OpenAPI 生成其他语言

# 生成 Python 客户端
openapi-generator-cli generate \
  -i http://localhost:6700/docs/openapi.yaml \
  -g python \
  -o ./clients/python

# 生成 Java 客户端
openapi-generator-cli generate \
  -i http://localhost:6700/docs/openapi.yaml \
  -g java \
  -o ./clients/java

七、开发工作流

7.1 API 变更流程

7.2 新增接口示例

// 1. 修改 proto
// admin/service/v1/i_post.proto
service PostService {
  // ... 已有接口

  // 新增:获取推荐文章
  rpc GetFeatured(GetFeaturedRequest) returns (ListPostResponse) {
    option (google.api.http) = { get: "/admin/v1/posts/featured" };
  }
}

message GetFeaturedRequest {
  optional string locale = 1;
  optional uint32 limit = 2;
}
# 2. 生成代码
make api    # Go 代码
make ts     # TypeScript 代码
make openapi  # OpenAPI 文档

# 3. 实现 Service
# 4. 前端直接使用生成的 API 客户端

八、检查清单

检查项说明
buf 配置buf.gen.yaml / buf.gen.ts.yaml / buf.gen.openapi.yaml
Go 代码生成make api
TS 代码生成make ts
Dart 代码生成swagger_parser
OpenAPI 文档make openapi + Swagger UI
API 客户端前端使用生成的类型安全客户端
开发流程proto → gen → implement

相关文档

  • CMS Protobuf API 定义
  • CMS 后端架构总览
  • Headless API 对接多端实战
  • 前台应用开发实战
Edit this page
Last Updated:: 6/21/26, 8:19 PM
Contributors: Bobo
Prev
新增内容类型全栈实战教程