You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多模型需独立创建/获取/列表API,是否需定义单/列表消息?

关于gRPC接口中批量/列表消息的设计建议

嘿,这个问题我太有共鸣了——当初刚上手gRPC设计接口时,也纠结过要不要为每个模型单独定义列表类的消息。先给你明确核心规则,再聊两种方案的利弊:

首先划重点:gRPC的硬性要求

gRPC的RPC方法不允许直接把repeated类型作为请求或返回值,必须用单个message来包装。也就是说你不能这么写:

// ❌ 错误写法:参数/返回值不能直接是repeated类型
rpc CreateStudents(repeated Student) returns (google.protobuf.Empty);
rpc GetAllStudents() returns (repeated Student);

所以你必须用一个message来封装重复的实体,接下来就是选哪种封装方式的问题。

方案1:为每个模型定义专用的列表/批量请求消息(推荐)

也就是你提到的定义StudentList,同时批量创建也建议定义CreateStudentsRequest,示例如下:

syntax = "proto3";

import "google/protobuf/empty.proto";

message Student {
  string name = 1;
  int32 age = 2;
}

// 批量创建学生的请求消息
message CreateStudentsRequest {
  repeated Student students = 1;
  // 后续可以灵活添加批量操作的配置,比如
  bool skip_duplicate_check = 2;
}

// 获取学生列表的响应消息
message StudentListResponse {
  repeated Student students = 1;
  // 后续扩展分页、统计字段非常方便
  int64 total_count = 2;
  int32 current_page = 3;
  int32 page_size = 4;
}

service StudentService {
  rpc CreateStudent(Student) returns (google.protobuf.Empty);
  rpc CreateStudents(CreateStudentsRequest) returns (google.protobuf.Empty);
  rpc GetAllStudents(google.protobuf.Empty) returns (StudentListResponse);
  // 如果需要分页查询,可以再加一个带参数的请求
  rpc GetStudentsByPage(GetStudentsByPageRequest) returns (StudentListResponse);
}

message GetStudentsByPageRequest {
  int32 page_num = 1;
  int32 page_size = 2;
}

这种方案的优势非常明显:

  • 扩展性拉满:后续要加分页参数、总数统计、操作开关这类元数据,直接在对应的message里加字段就行,完全不用修改RPC方法的签名,兼容老版本客户端。
  • 语义清晰:从方法名和消息名就能一眼看懂接口的作用,团队协作时沟通成本低。
  • 规范统一:所有模型的批量/列表接口都遵循相同的结构,维护起来非常省心。

方案2:用通用包装消息(不推荐)

有些人为了省事儿,会尝试定义一个通用的列表消息,比如用google.protobuf.Any来包装任意类型:

import "google/protobuf/any.proto";

message GenericListResponse {
  repeated google.protobuf.Any items = 1;
  int64 total_count = 2;
}

// 批量创建的通用请求
message GenericBatchCreateRequest {
  repeated google.protobuf.Any items = 1;
}

但这种方案的问题很多:

  • 类型不安全:客户端和服务端都需要手动做类型转换,很容易出现类型不匹配的错误,排查起来麻烦。
  • 可读性极差:其他开发者看接口时,根本不知道返回的列表里是什么类型的实体,必须去查文档或者代码。
  • 扩展性受限:如果某个模型的列表需要特殊字段,通用消息没法满足,最后还是得回到方案1。

总结一下

如果你的项目是长期维护的,强烈推荐方案1——为每个模型定义专用的批量请求和列表响应消息。虽然一开始多写几行代码,但后续的扩展性和可维护性会给你省超多麻烦。

内容的提问来源于stack exchange,提问作者TheDude

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:15:07