# 《WaLiAPI - 本地 LLM API 网关》第1-3节:渠道适配器模式
作者:小傅哥
博客:https://bugstack.cn (opens new window)
沉淀、分享、成长,让自己和他人都能有所收获!😄
大家好,我是技术UP主小傅哥。
上一节我们完成了数据库层。这一节进入 WaLiAPI 最核心的设计——渠道适配器模式。这是整个网关的灵魂:对外暴露统一的 OpenAI 协议,对内对接 N 家不同的 AI 供应商。
# 一、本章诉求
- 理解适配器模式(Adaptor Pattern)在 API 网关中的应用
- 定义
Adaptortrait——所有渠道适配器的统一抽象 - 实现 OpenAI 适配器(透传 + 模型映射)
- 实现 DeepSeek 适配器(OpenAI 兼容协议的复用)
- 实现渠道类型的元数据管理(channel_types)
# 二、为什么要用适配器模式?
# 2.1 问题场景
假设不用适配器模式,我们的代码会变成什么样?
// ❌ 反面教材:if-else 地狱
async fn forward(channel_type: &str, request: &Request) -> Response {
if channel_type == "openai" {
// OpenAI 的请求逻辑
} else if channel_type == "claude" {
// Claude 的请求逻辑:x-api-key 头、anthropic-version、消息格式转换...
} else if channel_type == "gemini" {
// Gemini 的请求逻辑:URL 带 key 参数、contents/parts 格式...
} else if channel_type == "deepseek" {
// ...
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
这样的代码有几个致命问题:
- 违反开闭原则:每加一个供应商就要改核心转发函数
- 职责不单一:一个函数要懂所有供应商的协议细节
- 无法独立测试:想测 Claude 的逻辑必须把整个函数跑起来
# 2.2 适配器模式解法
每家供应商是一个独立的"适配器",实现统一的接口:
┌─────────────────┐
统一 OpenAI 请求 │ Proxy 代理层 │ 统一 OpenAI 响应
──────────→ │ │ ──────────→
│ get_adaptor() │
└────────┬────────┘
│ trait Adaptor
┌──────────┬─────────┼─────────┬──────────┐
↓ ↓ ↓ ↓ ↓
┌─────────┐┌─────────┐┌────────┐┌────────┐┌────────┐
│ OpenAI ││DeepSeek ││ Claude ││ Gemini ││ Custom │
│ Adaptor ││ Adaptor ││Adaptor ││Adaptor ││Adaptor │
└────┬────┘└────┬────┘└───┬────┘└───┬────┘└───┬────┘
↓ ↓ ↓ ↓
api.openai deepseek anthropic google 任意兼容端点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
Proxy 层只依赖 Adaptor trait 这个抽象,不关心具体是哪家供应商。新增供应商 = 新增一个实现 trait 的结构体 + 在工厂函数中注册一行。

