ice-jade
ice-jade 是一个基于 Ruby 标准库的轻量级工具集,零外部依赖。最初定位是 IM Webhook SDK,现已扩展为包含多个独立分支的通用 HTTP 工具包:
- Quantum — IM Webhook 客户端
- Poster — 通用 HTTP POST 客户端
- HttpPoster — 独立模块级 HTTP POST 工具
- Cradle — HTTP 测试服务器
- YAMLServer — YAML 配置驱动的测试服务器实例
安装
gem 'ice-jade'
bundle install
或本地安装:
gem build ice-jade.gemspec
gem install ice-jade-*.gem
分支一:Quantum IM
Quantum 是企业 IM 群机器人的 Webhook 客户端,支持文本、图片、文件、图文消息的发送,以及附件上传。
快速开始
require 'ice_jade'
client = IceJade::Quantum::Client.new('your-webhook-key')
# 发送文本
client.send_text("hello world")
# @所有人
client.send_text("紧急通知", mention_all: true)
# 图文消息
client.send_news("标题", "https://example.com", description: "描述")
# 上传并发送图片
client.upload_and_send_image("/path/to/photo.jpg", height: 1080, width: 1920)
# 上传并发送文件
client.upload_and_send_file("/path/to/report.pdf")
详细文档:documents/im-quantum-api.md
分支二:Poster
IceJade::Poster::Client 是通用 HTTP POST 客户端,面向对象设计,支持 JSON / Form / Multipart,内置超时重试和统一 Response 包装。
快速开始
require 'ice_jade'
poster = IceJade::Poster::Client.new(
base_url: 'https://api.example.com',
headers: { 'Authorization' => 'Bearer token' },
timeout: 30
)
# POST JSON
resp = poster.post_json('/users', { name: 'Alice' })
puts resp.data if resp.success?
# POST Form
resp = poster.post_form('/login', { username: 'admin', password: 'secret' })
# POST Multipart(文件上传)
resp = poster.post_multipart('/upload', { file: '/path/to/image.png' })
# 通用 post(自定义 Content-Type)
resp = poster.post('/hook', '<xml>...</xml>', content_type: 'application/xml')
与 Quantum 的关系
| 分支 | 定位 | 典型场景 |
|---|---|---|
| Quantum | IM Webhook 专用 SDK | 向企业 IM 群机器人发消息 |
| Poster | 通用 HTTP POST 客户端 | 调用任意 REST API、Webhook |
两者共享 IceJade::Response 与 IceJade::Error,响应处理风格一致。
详细文档:documents/poster-api.md
分支三:HttpPoster(独立模块)
HttpPoster 是 lib/http_poster.rb 中定义的纯标准库 HTTP POST 工具,零 gem 依赖。它是独立于 ice-jade gem 的扁平化脚本,适合不想引入任何 gem 的场景。
快速开始
require_relative 'lib/http_poster'
# POST JSON(模块静态方法)
res = HttpPoster.post_json(
'https://api.example.com/users',
{ name: 'Alice' },
{ 'Authorization' => 'Bearer token' },
{ timeout: 30 }
)
puts res # => Hash(解析后的 JSON)
与 Poster 的对比
| 维度 | HttpPoster | IceJade::Poster::Client |
|---|---|---|
| 调用方式 | 模块静态方法 | 先 new 实例化再调用 |
| URL 处理 | 只能传完整 URL | 支持 base_url + 相对路径 |
| 参数风格 | 位置参数 (url,p,h,opts) |
关键字参数 (headers:) |
| 成功返回 | Hash / String | IceJade::Response |
| 错误处理 | 抛 TimeoutError / HttpError |
包装为 Response(不抛异常) |
| 所属体系 | 独立脚本(无依赖) | ice-jade gem 分支 |
| 典型场景 | 快速脚本、教学、零依赖 | 正式项目、与 Quantum 混用 |
详细文档:documents/http-poster-api.md
分支四:Cradle(HTTP 测试服务器)
Cradle 是轻量级 HTTP 测试服务器,基于 Ruby 标准库 socket + thread,零外部依赖。用于本地测试 Poster、Quantum 或其他 HTTP 客户端。
命令行启动
cradle # 默认监听 0.0.0.0:8765
cradle -p 3000 # 监听 0.0.0.0:3000
cradle -h 127.0.0.1 # 仅本地访问
代码启动
require 'ice_jade'
server = IceJade::Cradle::Server.new(port: 8765)
# 注册自定义路由
server.route(:post, '/echo') do |req|
[200, { 'Content-Type' => 'application/json' },
JSON.generate(method: req.method, body: req.parsed_body)]
end
server.start
详细文档:documents/cradle-api.md
分支五:YAMLServer(YAML 配置驱动的测试实例)
YAMLServer 通过载入 YAML 配置文件启动定制化的 HTTP 测试实例,无需写 Ruby 代码注册路由,适合频繁切换测试场景。
命令行启动
cradle-instance config/cradle/poster_test.yml
YAML 配置示例
port: 8765
host: 127.0.0.1
routes:
- method: POST
path: /echo
handler: echo_json
- method: POST
path: /error
handler: static
status: 500
headers:
Content-Type: application/json
body: '{"error":"Internal Server Error"}'
内置 handler:echo_json、echo_form、echo_upload、static、delay。
详细文档:documents/yaml-server-api.md
扩展 Cradle / YAMLServer
Cradle 和 YAMLServer 都可以通过扩展代码添加新功能,变成满足实际需求的 HTTP 服务器:
- Cradle::Server:通过
route(method, path) { |req| ... }注册自定义路由 - YAMLServer:通过
HANDLERS['name'] = lambda { |req, cfg| ... }注册自定义处理器 - 混合模式:YAML 启动基础路由,Ruby 代码追加动态路由
扩展能力包括:自定义响应格式、路径参数、请求头校验、状态计数器、随机延迟、分页模拟、代理转发等。也可以把扩展封装为独立 gem 复用 Cradle 内核。
详细文档:documents/cradle-extension.md
文件结构
lib/
ice_jade.rb # 主入口
http_poster.rb # 独立模块(零依赖)
ice_jade/
version.rb
error.rb
response.rb
client_base.rb
quantum/
client.rb
.rb
poster/
client.rb
cradle/
server.rb # 原生服务器
yaml_server.rb # YAML 配置层
bin/
cradle # 命令行:启动原生服务器
cradle-instance # 命令行:启动 YAML 实例
config/cradle/
poster_test.yml # Poster 测试专用配置
examples/
quantum_usage.rb # Quantum 用法示例
poster_usage.rb # Poster + YAMLServer 联测
comparison_poster.rb # HttpPoster vs Poster 对比
cradle_usage.rb # Cradle 服务器用法
documents/
im-quantum-api.md # Quantum API 文档
poster-api.md # Poster API 文档
http-poster-api.md # HttpPoster 文档
cradle-api.md # Cradle 文档
yaml-server-api.md # YAMLServer 文档
cradle-extension.md # 扩展指南
架构设计
分支关系
ice-jade/
├── Quantum # IM Webhook 客户端
├── Poster # 通用 HTTP POST 客户端
├── HttpPoster # 独立模块(零 gem 依赖)
├── Cradle # HTTP 测试服务器
└── YAMLServer # YAML 配置层(基于 Cradle)
添加新 IM(Quantum 模式)
每个 IM 独占一个命名空间,内部包含自己的 Client 和 Message(如果有)。
lib/ice_jade/
quantum/
client.rb # Quantum::Client < ClientBase
.rb # Quantum::Message
feishu/ # 未来其他IM
client.rb
dingtalk/ # 未来其他IM#2
client.rb
步骤:
- 在
lib/ice_jade/下新建目录 - 实现
client.rb,继承IceJade::ClientBase - 在
lib/ice_jade.rb中require_relative
模板见 README.md 原 Quantum 扩展章节。
统一接口(可选工厂)
def build_im_client(config)
case config[:type]
when 'quantum' then IceJade::Quantum::Client.new(config[:key])
when 'feishu' then IceJade::Feishu::Client.new(config[:webhook_url])
else raise "Unknown IM type: #{config[:type]}"
end
end
依赖
- Ruby >= 2.5
- 仅使用标准库(
net/http、socket、json、uri、yaml等)
限制
- Quantum:文件上传 30MB,消息频率 20条/分钟
- Cradle:不支持 WebSocket、HTTPS、持久连接