「清洁 API 架构」六部曲·Part 1:分层全景 + Ruby 实战,告别“Fat Controller”!
文章目录
我们开始了一个关于如何构建 Web API 的六部分系列,旨在介绍多年来各种语言和框架提出或使用的多种架构模式。其中,Clean 架构是线上讨论最为广泛的架构之一。它通过将项目划分为多个层次来实现关注点分离,每一层都遵循单一职责原则。这种设计不仅让每个类专注于处理流程的一部分,还能更轻松地进行单元测试。
Clean 架构适用于多个领域。在另一个博客系列中,我们曾探讨如何将 Clean 架构应用于移动应用程序。而今天,我们将重点讨论如何将 Clean 架构应用于 API 端点,这种方法被我们称为 清洁 API 架构。
💡 想让指标可衡量、团队节奏更透明?「开发任务管理系统 KPI」提示词可帮你基于 AI 超级提示词,快速制定与业务成果对齐的 KPI,兼顾用户参与度与业务成果!
一、清洁 API 架构的层次划分 🏗️
| 层级 | 职责 | Ruby 示例对象 |
|---|---|---|
| Frameworks & Drivers | 路由、HTTP、DB、外部服务 | Rails Controller、Sidekiq Job |
| Interface Adapters | 类型化 Request、Presenter、Socket Relay | Request 类、JSONPresenter |
| Application Logic | 编排、权限、事务边界 | Service、Command |
| Entity Logic | 领域模型、业务规则 | Repository、Adapter、Entity |
🛠️ 写完 Service 别忘了跑「代码优化」提示词,一键诊断慢查询与重复请求,让接口响应提速 30 %!
二、控制器(Controller)—— 编排而非业务 🎛️
1. 只做三件事
- 提取并验证 HTTP 参数 →
Request对象 - 身份认证 & 授权
- 调用 Application Service,返回
Result
2. 依赖清单
- Validator → 语法校验
- Presenter → 输出格式化
- Socket Relay → WebSocket 推送
- Request → 类型化参数封装
# app/controllers/favorites_controller.rb
class FavoritesController < ApplicationController
def create
request = CreateFavoriteRequest.new(params)
result = AddToFavoriteService.call(request, current_user)
present(result) # JSONPresenter
end
end
三、Application Logic —— 用例层 💼
① 读流程(GET)
- Service → 校验语义、权限 → Repo/Adapter 取数据 → 返回
Result
② 写流程(POST/PUT/DELETE)
- Service → 校验 → 写入 DB → 推送副作用(Job、WebSocket)
# app/services/add_to_favorite_service.rb
class AddToFavoriteService
include Dry::Monads[:result]
def self.call(request, user)
return Failure(:invalid_target) unless request.valid?
favorite = FavoriteRepo.first_or_create(user.id, request.target_id)
Success(favorite)
end
end
四、Entity Logic —— 可复用的基础设施 🔌
| 组件 | 说明 | 示例 |
|---|---|---|
| Repository | 聚合根持久化 | FavoriteRepo |
| Adapter | 外部 API 访问 | S3Adapter、ElastiCacheAdapter |
| Entity | 领域对象/聚合根 | Favorite |
📖 想给同事一份秒懂的接口文档?「代码文档生成器」可自动生成标准化字段描述、请求/响应示例与错误码,让协作零阻力!
五、双重验证机制 ✅
- 语法验证 —— Request 层(类型、必填、格式)
- 语义验证 —— Service 层(业务规则、权限、状态)
class CreateFavoriteRequest
include ActiveModel::Model
attr_accessor :target_id, :creator_id
validates :target_id, presence: true, numericality: true
end
六、测试策略 🧪
- 单元测试 → Service、Repository 用内存 SQLite
- 集成测试 → Controller 用
instance_doubleMock 外部适配器 - 契约测试 → 确保 Request/Response JSON Schema 不变
RSpec.describe AddToFavoriteService do
it "creates favorite when valid" do
result = described_class.call(valid_request, user)
expect(result).to be_success
end
end
七、Ruby 代码分层全景图 🗺️
# Frameworks & Drivers 层
post '/favorite' do
request = CreateFavoriteRequest.new(params)
result = AddToFavoriteService.call(request, current_user)
present(result)
end
# Application 层
class AddToFavoriteService
def self.call(request, user)
return Failure(:invalid) unless request.valid?
favorite = FavoriteRepo.first_or_create(user.id, request.target_id)
Success(favorite)
end
end
# Entity 层
module FavoriteRepo
def self.first_or_create(user_id, target_id)
Favorite.where(user_id: user_id, target_id: target_id).first_or_create!
end
end
八、常见疑问 ❓
Q1. 层太多会不会过度工程?
→ 单体 MVP 可先保持 3 层(Controller-Service-Repo),用户量>10w 再细化。
Q2. 性能会不会下降?
→ 层间调用都是内存对象,无网络开销;瓶颈多在 DB 和外部 API。
Q3. 必须 Ruby 吗?
→ 分层思想语言无关;Python/FastAPI、Java/Spring Boot、Go 均可映射。
九、结语 🎯
清洁 API 架构带来的好处:
- ✅ 关注点分离 —— 易定位 bug、易单元测试
- ✅ 可扩展 —— 新增用例只需加 Service/Repository
- ✅ 可维护 —— 每层单一职责,新人一周上手
先用「代码生成」快速产出 Service 模板与 Repository 接口,再用 KPI 面板持续监控每层耗时、测试覆盖率与线上错误率,你的 API 将更快、更稳地迎接高并发挑战!🚀
原文链接: https://medium.com/perry-street-software-engineering/clean-api-architecture-2b57074084d5
热门API
- 1. AI文本生成
- 2. AI图片生成_文生图
- 3. AI图片生成_图生图
- 4. AI图像编辑
- 5. AI视频生成_文生视频
- 6. AI视频生成_图生视频
- 7. AI语音合成_文生语音
- 8. AI文本生成(中国)
最新文章
- 2025大学生暑假兼职新风口:从送外卖到做AI副业,你还在靠体力赚零花钱吗?
- 如何获取Microsoft API Key 密钥实现bing搜索分步指南
- Google Pay UPI 注册与集成指南
- 香港支付宝可以绑定大陆银行卡吗?详解使用方法与步骤
- New API架构:探索现代软件开发的新趋势
- 什么是 Wandb
- 在 Golang 中实现 JWT 令牌认证
- 如何使用 Google News API 获取实时新闻数据
- API文档:深入指南与前沿免费工具 – Apidog
- 交叉熵的Numpy实现:从理论到实践
- Google DeepMind发布 Genie 3与Shopify:2小时上线电商3D样板间实战
- Gemini Deep Research 技术实战:利用 Gemini Advanced API 构建自动化的深度研究 Agent