2026-08-16 12:46:15 +08:00
2026-08-16 12:46:15 +08:00
2026-08-16 12:46:15 +08:00
2026-08-16 12:46:15 +08:00
2026-08-16 12:46:15 +08:00
2026-08-16 12:46:15 +08:00

SimApi for Cangjiesimapi

仓颉版 SimApiASP.NET Core 风格 API 基础框架,移植自 C# 项目 SimApiE:\simcu\simapi-net)。

提供统一响应格式、异常拦截、Token 认证、缓存、工具集、HTTP 客户端等 API 基础能力。


快速开始

package your_app

import soulsoft_web_http.*
import soulsoft_web_routing.*
import soulsoft_web_hosting.*
import soulsoft_extensions_logging.*
import soulsoft_extensions_injection.*
import simapi.extensions.*
import simapi.communications.*

main(args: Array<String>) {
    let builder = WebHost.createBuilder(args)
    builder.services.addRouting()
    builder.services.addLogging()

    // 注册 SimApi 服务(与 addLogging 同样式)
    builder.addSimApi { options =>
        options.enableSimApiAuth = true     // Token 认证(未配 Redis 自动用 InMemory
        options.enableSimApiCache = true    // 缓存
        options.enableSimApiException = true // 全局异常拦截
    }

    let host = builder.build()
    host.useSimApi()

    // 业务接口:返回统一响应格式
    host.mapGet("hello") {
        context =>
            context.response.write(SimApiBaseResponse().toJsonString(dataJson: "\"hello cangjie.\""))
    }

    host.run()
}

统一响应格式

所有接口输出 JSON,HTTP 状态码始终 200,错误信息在 code 字段:

code 含义
200 成功
204 无数据
400 参数错误
401 需要登录
403 无权访问
404 资源不存在
500 服务器错误

异常处理流程

请求 → SimApiExceptionMiddleware(全异常捕获→HTTP 200+JSON)
     → SimApiAuthMiddleware(Token→LoginInfo)
     → 路由 → 业务处理

项目结构

simapi-cj/
├── cjpm.toml                  # 包配置
├── src/
│   ├── communications/        # SimApiBaseResponse, PageResponse, SimApiLoginItem, ApiResult, 请求 DTO
│   ├── configurations/        # SimApiOptions + 各模块 Option(含 ConfigureSimApiXxx 回调)
│   ├── controllers/           # SimApiBaseController, SimApiCommonController, SimApiAuthControllerMVC 写法)
│   ├── exceptions/            # SimApiException
│   ├── extensions/            # SimApiExtensionsaddSimApi / useSimApi + 内置路由)
│   ├── helpers/               # SimApiError, SimApiUtil, SimApiAuth, SimApiCache, SimApiHttpClient
│   ├── interfaces/            # ISimApiAuthChecker
│   ├── logger/                # SimApiLogger, SimApiLoggerProvider(彩色日志)
│   └── middlewares/           # SimApiExceptionMiddleware, SimApiAuthMiddleware, SimApiRequestLogMiddleware

模块说明

1. 错误处理 — SimApiError

import simapi.helpers.*

SimApiError.error(500, "服务器内部错误")          // 直接抛错
SimApiError.errorWhen(amount <= 0, 400, "金额无效") // 条件为 true 时抛错
SimApiError.errorWhenFalse(hasPermission, 403, "无权操作")
SimApiError.errorWhenNone(someOptional, 404, "用户不存在")

2. 认证 — SimApiAuth

import simapi.helpers.*
import simapi.communications.*

let auth = SimApiAuth(redisConfiguration: "")   // 配 Redis 用 Redis,否则 InMemory

let token = auth.login(SimApiLoginItem(id: "user-001"))  // 默认 7 天
let login = auth.getLogin(token)                // 获取登录信息
auth.logout(token)                              // 退出登录
auth.logoutAll("user-001")                      // 退出全部
  • Redis 模式:配置 RedisConfiguration(如 "localhost:6379")时使用,支持多实例共享
  • InMemory 模式:零配置,适合开发/测试;重启后登录态丢失
  • Token 传参Header Token: <value> 或 Query token=<value>

3. 缓存 — SimApiCache

let cache = SimApiCache(redisConfiguration: "")
cache.set("key", "value")
let v = cache.get("key")       // ?String
cache.hasKey("key")            // Bool
cache.remove("key")

Key 自动加前缀 SimApi:Cache:

4. 工具集 — SimApiUtil

SimApiUtil.cstNow            // UTC+8 时间
SimApiUtil.timestampNow      // 秒级时间戳
SimApiUtil.md5("text")       // 32 位十六进制
SimApiUtil.sha1("text")      // 40 位
SimApiUtil.base64Encode("text") / base64Decode("...")
SimApiUtil.checkCell("13800138000")   // 手机号
SimApiUtil.checkEmail("a@b.com")      // 邮箱

5. HTTP 客户端 — SimApiHttpClient

用于调用其他带签名/AES 的 SimApi 服务:

let client = SimApiHttpClient(options: SimApiHttpClientOptions())  // 配置 server/appId/appKey

// 返回泛型 T(对齐 .NET SignQuery<T>/AesQuery<T>/AesSignQuery<T>),T 需实现 ISerialization<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}")

5.1 请求日志 — enableRequestLog

记录每次请求的方法、URL、请求头、请求体、响应状态码与耗时:

builder.addSimApi { options =>
    options.enableRequestLog = true
    options.simApiRequestLogOptions.showFullHeader = true   // 打印完整 Header(默认只打 Token/Query-Id
    options.simApiRequestLogOptions.requestStringLogLength = 200  // 请求体截断长度(0 不截断)
}

输出示例:

[GET] /hello
*( RequestHeaders [Full] ) =>
{"host":"127.0.0.1:5000",...}
*( RequestBody ) =>

*( Response [200] ) => 1.756400ms

5.2 日志格式 — SimApiLogger

enableLogger(默认 true)时自动使用 SimApiLoggerProvider(替换 soulsoft 默认控制台格式),输出格式对齐 C# 原版:

[ 分类 ][ 时间:毫秒 ][ 级别 ]
消息内容

按级别着色:

级别 颜色
Debug 深紫(DarkMagenta
Info 深青(DarkCyan
Warn 黄(Yellow
Error 红(Red
Fatal 深红(DarkRed 粗体近似)
其他 白(White

6. 内置路由(UseSimApi 自动注册)

路由 方法 条件 说明
/versions GET/POST 始终 返回 SimApi/App 版本
/user/info POST enableSimApiAuth 需登录,返回 LoginInfo
/auth/logout POST enableSimApiAuth 退出登录
/exception/{code} GET 始终 错误反馈

7. 认证后处理 Hook — ISimApiAuthChecker

import simapi.interfaces.*

class MyAuthChecker <: ISimApiAuthChecker {
    public func run(loginItem: SimApiLoginItem, token: String): Unit {
        // 认证成功后执行
    }
}

SimApiOptions 完整配置

builder.addSimApi { options =>
    options.redisConfiguration = "localhost:6379"  // Redis(可选)

    // 功能开关
    options.enableSimApiAuth       = false   // Token 认证
    options.enableSimApiCache      = true    // 缓存
    options.enableSimApiException  = true    // 全局异常拦截
    options.enableSimApiResponseFilter = true // 响应统一封装
    options.enableSimApiHttpClient = false   // HTTP 客户端
    options.enableRequestLog       = false   // 请求日志中间件
    options.enableCors             = true    // 全量 CORS
    options.enableLogger           = true    // 控制台日志

    // .NET 风格子模块配置回调(对齐 C# ConfigureSimApiXxx
    options.configureSimApiRoute { route =>
        route.userInfoRoute = Some("user/info")
        route.logoutRoute = Some("auth/logout")
    }
    options.configureSimApiRequestLog { opt =>
        opt.showFullResponse = true
        opt.showFullHeader = false
        opt.requestStringLogLength = 50
    }
    options.configureSimApiHttpClient { http =>
        http.appId = "your-app-id"
        http.appKey = "your-app-key"
        http.server = "https://api.example.com"
    }
}

内置控制器(MVC 写法)

simapi 提供 Spire MVC 控制器(继承 SimApiBaseController),宿主通过 addControllers + 手动 AssemblyPart 注册(当前 cjc 无法自动扫描包子包):

控制器 路由 说明
SimApiCommonController /exception/{code}/webconfig/user/info 通用内置路由
SimApiAuthController /auth/logout 退出登录
SimApiBaseController 基类:loginInfo / loginToken / requireLogin()
import simapi.controllers.*

// 控制器写法:继承 SimApiBaseController,注解路由 + DI 注入
public class MyController <: SimApiBaseController {
    private let _auth: SimApiAuth
    public init(auth: SimApiAuth) { this._auth = auth }

    @HttpPost["my/route"]
    public func myAction(@FromBody request: MyRequest): ApiResult {
        requireLogin()
        ApiResult.ok()
    }
}

// 宿主注册
let mvc = builder.services.addControllers()
mvc.addApplicationPart(AssemblyPart("simapi.controllers", [
    TypeInfo.of<SimApiCommonController>(),
    TypeInfo.of<SimApiAuthController>(),
]))

未实现模块(选项占位)

以下 C# 原包功能因仓颉生态暂无对应库,选项保留但未实现

选项 原功能 状态
enableSimApiDoc Swagger 文档 未实现
enableSimApiStorage S3/MinIO 存储 未实现
enableSynapse MQTT 通信 未实现
enableJob Hangfire 任务调度 未实现
enableSimApiAuthGate Auth Center 网关鉴权 未实现
SimApiAesUtil AES-256-CBC ⚠️ 仓颉 std 无 AES,暂用 Base64 占位

依赖

依赖 用途
soulsoft_web_http / routing / hosting Web 框架(ASP.NET Core 仓颉移植版)
soulsoft_extensions_logging 系列 日志
soulsoft_extensions_injection 依赖注入
soulsoft_extensions_configuration 配置
soulsoft_serialization JSON 序列化
redispkg.cangjie-lang.cn Redis 客户端(认证/缓存 Redis 模式)
stdxCANGJIE_STDX_PATH 标准扩展库(md5/sha1/base64/http

构建前需设置 CANGJIE_STDX_PATH 指向本地 stdx 的 static/stdx 目录。


许可证

MIT

S
Description
仓颉版 SimApi:ASP.NET Core 风格 API 基础框架,移植自 C# 项目
Readme
76 KiB
Languages
Cangjie 100%