重构: 源码文件蛇形命名, 接口去I头(BindRequestContext/SimApiAuthChecker), 清理C#相关说明, serialization依赖路径改 serialization-cj
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# SimApi for Cangjie(simapi)
|
||||
|
||||
> 仓颉版 SimApi:ASP.NET Core 风格 API 基础框架,移植自 C# 项目 [SimApi](https://github.com/SimcuTeam/simapi-net)(`E:\simcu\simapi-net`)。
|
||||
> 仓颉版 SimApi:ASP.NET Core 风格 API 基础框架,移植自 [SimApi](https://github.com/SimcuTeam/simapi-net)。
|
||||
|
||||
提供**统一响应格式、异常拦截、Token 认证、缓存、工具集、HTTP 客户端、S3 存储、声明式注解**等 API 基础能力。
|
||||
|
||||
@@ -103,7 +103,7 @@ main(args: Array<String>) {
|
||||
simapi-cj/
|
||||
├── cjpm.toml # 包配置
|
||||
├── src/
|
||||
│ ├── SimApiExtensions.cj # 根包入口:SimApiExtensions 静态类(addSimApi / useSimApi + 内置路由 + 响应封装)
|
||||
│ ├── simapi_extensions.cj # 根包入口:SimApiExtensions 静态类(addSimApi / useSimApi + 内置路由 + 响应封装)
|
||||
│ ├── annotations/ # 声明式注解:@SimApiAuth(鉴权)、@OriginResponse(原样响应)、
|
||||
│ │ # @SimApiSign(验签)、@AesBody(AES body 解密)
|
||||
│ ├── authsdk/ # 认证中心 SDK:SimApiAuthClient/Center/Iam + 网关中间件 + DTO
|
||||
@@ -114,7 +114,7 @@ simapi-cj/
|
||||
│ ├── helpers/ # SimApiError, SimApiUtil, SimApiAuth, SimApiCache, SimApiHttpClient,
|
||||
│ │ # SimApiAesUtil(AES-256), SimApiSignChecker(验签), SimApiAesBodyChecker(AES body),
|
||||
│ │ # SimApiStorage(S3/MinIO, 自实现 SigV4), SimApiRequestDelegateFactory, SimApiResultWriter
|
||||
│ ├── interfaces/ # ISimApiAuthChecker, IBindRequestContext, SimApiSignProviderBase, AesBodyProviderBase
|
||||
│ ├── interfaces/ # SimApiAuthChecker, BindRequestContext, SimApiSignProviderBase, AesBodyProviderBase
|
||||
│ ├── logger/ # SimApiLogger, SimApiLoggerProvider(彩色日志)
|
||||
│ ├── macros/ # ReadTomlVersion(编译期读版本号)
|
||||
│ ├── middlewares/ # SimApiExceptionMiddleware, SimApiAuthMiddleware, SimApiRequestLogMiddleware
|
||||
@@ -155,12 +155,12 @@ auth.logoutAll("user-001") // 退出全部
|
||||
- `"localhost:6379"`(基础)
|
||||
- `"localhost:6379,password=xxx"`(带密码)
|
||||
- `"localhost:6379,password=xxx,db=2"`(带密码 + DB 索引)
|
||||
- **InMemory 模式**:零配置,适合开发/测试;登录态带过期时间(对齐 C# 过期语义),重启后丢失
|
||||
- **InMemory 模式**:零配置,适合开发/测试;登录态带过期时间,重启后丢失
|
||||
- **Token 传参**:Header `Token: <value>` 或 Query `token=<value>`
|
||||
|
||||
### 2.1 声明式鉴权 — @SimApiAuth(对齐 C# [SimApiAuth])
|
||||
### 2.1 声明式鉴权 — @SimApiAuth
|
||||
|
||||
标注在控制器**方法或类**上,请求派发时自动执行鉴权(未登录 401 → 类型不匹配 403 → 遍历执行 `ISimApiAuthChecker`):
|
||||
标注在控制器**方法或类**上,请求派发时自动执行鉴权(未登录 401 → 类型不匹配 403 → 遍历执行 `SimApiAuthChecker`):
|
||||
|
||||
```cangjie
|
||||
import simcu::simapi.annotations.{SimApiAuth}
|
||||
@@ -174,11 +174,11 @@ public class MyController <: SimApiBaseController {
|
||||
}
|
||||
```
|
||||
|
||||
> 说明:仓颉注解参数须为编译期常量,`@SimApiAuth` 支持单个类型参数(`@SimApiAuth["admin"]`)或逗号分隔多类型(`@SimApiAuth["admin,user"]`,对齐 C# `type.Split(",")`);空参数表示任意已登录用户。
|
||||
> 说明:仓颉注解参数须为编译期常量,`@SimApiAuth` 支持单个类型参数(`@SimApiAuth["admin"]`)或逗号分隔多类型(`@SimApiAuth["admin,user"]`);空参数表示任意已登录用户。
|
||||
|
||||
### 2.2 原样响应 — @OriginResponse
|
||||
|
||||
标注后跳过统一响应封装,接口返回什么就输出什么(对齐 C# `[OriginResponse]`):
|
||||
标注后跳过统一响应封装,接口返回什么就输出什么:
|
||||
|
||||
```cangjie
|
||||
import simcu::simapi.annotations.{OriginResponse}
|
||||
@@ -190,7 +190,7 @@ public func raw(): String {
|
||||
}
|
||||
```
|
||||
|
||||
### 2.3 声明式验签 — @SimApiSign(对齐 C# [SimApiSign])
|
||||
### 2.3 声明式验签 — @SimApiSign
|
||||
|
||||
标注在控制器**方法或类**上,请求派发时自动验签(appId 提取 → 密钥获取 → timestamp 过期校验 → nonce 去重 → MD5 比对):
|
||||
|
||||
@@ -210,9 +210,9 @@ public class MySignProvider <: SimApiSignProviderBase {
|
||||
public func signedAction(): String { "ok" }
|
||||
```
|
||||
|
||||
`SimApiSignProviderBase` 可配置:`appIdName` / `timestampName` / `nonceName` / `signName` / `queryExpires` / `duplicateRequestProtection` / `signFields`(与 C# 一致)。也可手动调用 `SimApiSignChecker.verify(context, provider, cache)`。
|
||||
`SimApiSignProviderBase` 可配置:`appIdName` / `timestampName` / `nonceName` / `signName` / `queryExpires` / `duplicateRequestProtection` / `signFields`。也可手动调用 `SimApiSignChecker.verify(context, provider, cache)`。
|
||||
|
||||
### 2.4 声明式 AES body — @AesBody(对齐 C# [AesBody])
|
||||
### 2.4 声明式 AES body — @AesBody
|
||||
|
||||
标注在**参数**上,请求派发时自动解密 `{"data":"密文"}` body 并反序列化为参数类型:
|
||||
|
||||
@@ -252,14 +252,14 @@ Key 自动加前缀 `SimApi:Cache:`。
|
||||
```cangjie
|
||||
SimApiUtil.cstNow // UTC+8 时间
|
||||
SimApiUtil.timestampNow // 秒级时间戳
|
||||
SimApiUtil.newGuid() // UUID v4(对齐 C# Guid.NewGuid())
|
||||
SimApiUtil.newGuid() // UUID v4
|
||||
SimApiUtil.md5("text") // 32 位十六进制
|
||||
SimApiUtil.sha1("text") // 40 位
|
||||
SimApiUtil.base64Encode("text") / base64Decode("...")
|
||||
SimApiUtil.base64Encode(obj) // 对象 → JSON → Base64(对齐 C# Base64Encode(object))
|
||||
SimApiUtil.base64Encode(obj) // 对象 → JSON → Base64
|
||||
SimApiUtil.json(obj) // 对象 → JSON 字符串(simcu::serialization 反射)
|
||||
SimApiUtil.escapeJson(s) // JSON 字符串转义
|
||||
SimApiUtil.fromJson<T>(json) // JSON → T(对齐 C# FromJson<T>,任意类免约束)
|
||||
SimApiUtil.fromJson<T>(json) // JSON → T(任意类免约束)
|
||||
SimApiUtil.base64DecodeTo<T>(str) // Base64 → JSON → T
|
||||
SimApiUtil.checkCell("13800138000") // 手机号
|
||||
SimApiUtil.checkEmail("a@b.com") // 邮箱
|
||||
@@ -267,9 +267,9 @@ SimApiUtil.checkEmail("a@b.com") // 邮箱
|
||||
|
||||
> JSON 序列化/反序列化统一走 **simcu::serialization**(`JsonSerializer.Serialize` / `Deserialize<T>`),任意类免标注、免接口约束。
|
||||
|
||||
### 4.1 AES 加解密 — SimApiAesUtil(对齐 C# SimApiAesUtil)
|
||||
### 4.1 AES 加解密 — SimApiAesUtil
|
||||
|
||||
纯仓颉实现 AES-256-CBC + PKCS7(S-box/密钥扩展/轮函数),与 .NET 双向互操作已验证:
|
||||
纯仓颉实现 AES-256-CBC + PKCS7(S-box/密钥扩展/轮函数),加解密结果跨语言互通已验证:
|
||||
|
||||
```cangjie
|
||||
let encrypted = SimApiAesUtil.encrypt("明文", "key字符串") // Base64(随机IV + 密文)
|
||||
@@ -279,7 +279,7 @@ let plain = SimApiAesUtil.decrypt(encrypted, "key字符串")
|
||||
- 密钥:`SHA256(key 字符串)` → 32 字节;IV 每次随机 16 字节前置;输出 `Base64(IV + 密文)`
|
||||
- 供 `SimApiHttpClient.aesQuery<T>` / `aesSignQuery<T>` 使用
|
||||
|
||||
### 4.2 实体基类 — SimApiBaseModel(对齐 C# SimApiBaseModel)
|
||||
### 4.2 实体基类 — SimApiBaseModel
|
||||
|
||||
```cangjie
|
||||
import simcu::simapi.models.*
|
||||
@@ -301,19 +301,19 @@ user.updateTime() // 刷新 _updatedAt
|
||||
```cangjie
|
||||
let client = SimApiHttpClient(options: SimApiHttpClientOptions()) // 配置 server/appId/appKey
|
||||
|
||||
// 返回泛型 T(对齐 .NET SignQuery<T>/AesQuery<T>/AesSignQuery<T>),T 任意类免约束
|
||||
// 返回泛型 T(SignQuery<T>/AesQuery<T>/AesSignQuery<T>),T 任意类免约束
|
||||
let resp1 = client.signQuery<SimApiLoginItem>("/api/hello", body: "{\"a\":1}")
|
||||
let resp2 = client.aesQuery<SimApiLoginItem>("/api/data", body: "{\"a\":1}")
|
||||
let resp3 = client.aesSignQuery<SimApiLoginItem>("/api/data", body: "{\"a\":1}")
|
||||
```
|
||||
|
||||
签名参数名可配置(`signName / timestampName / nonceName / appIdName / signFields`,对齐 C# 的 virtual 属性)。AES 请求体用 `SimApiOneFieldRequest<String>` 序列化为 `{"data":"密文"}`(对齐 C#)。
|
||||
签名参数名可配置(`signName / timestampName / nonceName / appIdName / signFields`)。AES 请求体用 `SimApiOneFieldRequest<String>` 序列化为 `{"data":"密文"}`。
|
||||
|
||||
### 5.1 请求日志 — enableRequestLog
|
||||
|
||||
记录每次请求的方法、URL、请求头、请求体、响应状态码、耗时与异常(对齐 C#):
|
||||
记录每次请求的方法、URL、请求头、请求体、响应状态码、耗时与异常:
|
||||
- 请求体按 **JSON 字段级截断**(仅对超长字符串字段截断,保留结构;非 JSON 整串截断)
|
||||
- 下游异常**捕获记录后重抛**(对齐 C# ExceptionDispatchInfo)
|
||||
- 下游异常**捕获记录后重抛**
|
||||
|
||||
```cangjie
|
||||
SimApiExtensions.addSimApi(builder) { options =>
|
||||
@@ -336,7 +336,7 @@ SimApiExtensions.addSimApi(builder) { options =>
|
||||
|
||||
### 5.2 日志格式 — SimApiLogger
|
||||
|
||||
`enableLogger`(默认 `true`)时自动使用 `SimApiLoggerProvider`,输出格式对齐 C# 原版:
|
||||
`enableLogger`(默认 `true`)时自动使用 `SimApiLoggerProvider`,输出格式与原版一致:
|
||||
|
||||
```
|
||||
[ 分类 ][ 时间:毫秒 ][ 级别 ]
|
||||
@@ -345,7 +345,7 @@ SimApiExtensions.addSimApi(builder) { options =>
|
||||
|
||||
按级别着色:Debug 深紫 / Info 深青 / Warn 黄 / Error 红 / Fatal 深红。
|
||||
|
||||
### 5.3 存储 — SimApiStorage(S3/MinIO,对齐 C# SimApiStorage)
|
||||
### 5.3 存储 — SimApiStorage(S3/MinIO)
|
||||
|
||||
`enableSimApiStorage = true` 时注册 `SimApiStorage`(Scoped,内部自实现 AWS Signature V4,基于 stdx.net.http,无需 Minio SDK):
|
||||
|
||||
@@ -371,7 +371,7 @@ SimApiExtensions.addSimApi(builder) { options =>
|
||||
| `fullUrl(path)` / `getUrl(path)` | 补全访问 URL(`~/` 前缀依赖请求上下文) |
|
||||
| `getPath(url)` | 从 URL 还原相对路径(去掉 Endpoint/Bucket 或 ServeUrl 前缀) |
|
||||
|
||||
> 说明:桶不存在时自动创建(对齐 C# BucketExists + MakeBucket,静态守卫只执行一次);
|
||||
> 说明:桶不存在时自动创建(静态守卫只执行一次);
|
||||
> 预签名与上传使用 AWS SigV4(HMAC-SHA256 基于 stdx SHA256 自实现),已用 AWS 官方测试向量验证签名正确。
|
||||
|
||||
### 6. 内置路由(UseSimApi 自动注册)
|
||||
@@ -392,21 +392,21 @@ options.configureSimApiRoute { route =>
|
||||
}
|
||||
```
|
||||
|
||||
### 7. 认证后处理 Hook — ISimApiAuthChecker
|
||||
### 7. 认证后处理 Hook — SimApiAuthChecker
|
||||
|
||||
实现后每次认证成功都会调用(配合 `@SimApiAuth` 注解或手动 `requireLogin`):
|
||||
|
||||
```cangjie
|
||||
import simcu::simapi.interfaces.*
|
||||
|
||||
class MyAuthChecker <: ISimApiAuthChecker {
|
||||
class MyAuthChecker <: SimApiAuthChecker {
|
||||
public func run(loginItem: SimApiLoginItem, token: String): Unit {
|
||||
// 认证成功后执行
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 8. 认证中心 SDK — AuthSDK(对齐 C# AuthSDK)
|
||||
### 8. 认证中心 SDK — AuthSDK
|
||||
|
||||
`enableSimApiAuthGate = true` 时注册 `SimApiAuthClient` / `SimApiAuthCenter` / `SimApiAuthIam` 单例并挂载网关透传中间件:
|
||||
|
||||
@@ -457,7 +457,7 @@ SimApiExtensions.addSimApi(builder) { options =>
|
||||
options.enableCors = true // 全量 CORS
|
||||
options.enableLogger = true // 控制台日志
|
||||
|
||||
// .NET 风格子模块配置回调(对齐 C# ConfigureSimApiXxx)
|
||||
// 子模块配置回调(ConfigureSimApiXxx)
|
||||
options.configureSimApiRoute { route =>
|
||||
route.userInfoRoute = Some("/user/info") // 内置路由自定义路径
|
||||
route.logoutRoute = Some("/auth/logout")
|
||||
@@ -483,7 +483,7 @@ SimApiExtensions.addSimApi(builder) { options =>
|
||||
|
||||
## 内置控制器(MVC 写法)
|
||||
|
||||
simapi 提供 Spire MVC 控制器(继承 `SimApiBaseController`),`addSimApi` 自动注册内置控制器 + 自动扫描调用者包中的控制器(对齐 C# `Assembly.GetTypes()` 扫描):
|
||||
simapi 提供 Spire MVC 控制器(继承 `SimApiBaseController`),`addSimApi` 自动注册内置控制器 + 自动扫描调用者包中的控制器:
|
||||
|
||||
| 控制器 | 路由 | 说明 |
|
||||
|--------|------|------|
|
||||
@@ -514,7 +514,7 @@ public class MyController <: SimApiBaseController {
|
||||
|
||||
## 未实现模块(选项占位)
|
||||
|
||||
以下 C# 原包功能因仓颉生态暂无对应库(Hangfire/MQTT/Swashbuckle),**选项保留但未实现**:
|
||||
以下原包功能因仓颉生态暂无对应库(Hangfire/MQTT/Swashbuckle),**选项保留但未实现**:
|
||||
|
||||
| 选项 | 原功能 | 状态 |
|
||||
|------|--------|------|
|
||||
@@ -522,7 +522,7 @@ public class MyController <: SimApiBaseController {
|
||||
| `enableSynapse` | MQTT 通信 | ❌ 未实现 |
|
||||
| `enableJob` | Hangfire 任务调度 | ❌ 未实现 |
|
||||
|
||||
> ✅ 已实现(曾为占位):`enableSimApiStorage`(S3/MinIO,自实现 AWS SigV4)、`enableSimApiAuthGate`(AuthSDK 认证中心)、`SimApiAesUtil`(纯仓颉 AES-256-CBC,与 .NET 双向互操作)、`ISimApiAuthChecker`、`@SimApiSign` / `@AesBody` 声明式注解、内置路由自定义路径。
|
||||
> ✅ 已实现(曾为占位):`enableSimApiStorage`(S3/MinIO,自实现 AWS SigV4)、`enableSimApiAuthGate`(AuthSDK 认证中心)、`SimApiAesUtil`(纯仓颉 AES-256-CBC)、`SimApiAuthChecker`、`@SimApiSign` / `@AesBody` 声明式注解、内置路由自定义路径。
|
||||
|
||||
---
|
||||
|
||||
@@ -530,7 +530,7 @@ public class MyController <: SimApiBaseController {
|
||||
|
||||
| 依赖 | 用途 |
|
||||
|------|------|
|
||||
| `soulsoft_web_http / routing / hosting` | Web 框架(ASP.NET Core 仓颉移植版) |
|
||||
| `soulsoft_web_http / routing / hosting` | Web 框架 |
|
||||
| `soulsoft_extensions_logging` 系列 | 日志 |
|
||||
| `soulsoft_extensions_injection` | 依赖注入 |
|
||||
| `soulsoft_extensions_configuration` | 配置 |
|
||||
|
||||
Reference in New Issue
Block a user