{"id":27874591,"url":"https://github.com/jinzcdev/oneapi-backend","last_synced_at":"2025-05-05T01:36:33.052Z","repository":{"id":184654319,"uuid":"671950851","full_name":"jinzcdev/oneapi-backend","owner":"jinzcdev","description":"一个 API 开放平台，实现接口在线管理、调用","archived":false,"fork":false,"pushed_at":"2025-04-29T07:55:05.000Z","size":1070,"stargazers_count":18,"open_issues_count":0,"forks_count":6,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-29T08:42:05.881Z","etag":null,"topics":["gataway","openapi","springboot"],"latest_commit_sha":null,"homepage":"https://oneapi.charjin.top","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jinzcdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-07-28T14:22:08.000Z","updated_at":"2025-04-29T08:03:21.000Z","dependencies_parsed_at":"2024-10-28T03:51:58.602Z","dependency_job_id":"d5c681f0-da53-4878-a848-7326b6629d5c","html_url":"https://github.com/jinzcdev/oneapi-backend","commit_stats":null,"previous_names":["jinzcdev/oneapi-backend"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinzcdev%2Foneapi-backend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinzcdev%2Foneapi-backend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinzcdev%2Foneapi-backend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinzcdev%2Foneapi-backend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jinzcdev","download_url":"https://codeload.github.com/jinzcdev/oneapi-backend/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252424607,"owners_count":21745782,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gataway","openapi","springboot"],"created_at":"2025-05-05T01:36:32.519Z","updated_at":"2025-05-05T01:36:33.044Z","avatar_url":"https://github.com/jinzcdev.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OneAPI 开放平台\n\n\u003e [!TIP]\n\u003e \n\u003e **因资源有限，该项目已下线**\n\u003e \n\u003e ~~该项目目前已经上线：\u003chttps://oneapi.charjin.top\u003e，对应的前端项目地址在[此处](https://github.com/jinzcdev/oneapi-frontend)~~\n\u003e\n\u003e ~~管理员/普通用户：admin/user 密码：12345678~~\n\n\u003cp align=\"center\"\u003e\n  \u003cimg style=\"width: 95%;\" src=\"https://raw.githubusercontent.com/jinzcdev/oneapi-backend/main/docs/imgs/oneapi.png\" alt=\"OneAPI\"\u003e\n\u003c/p\u003e\n\n该平台包含以下模块：\n\n1. 后台管理系统\n2. 客户端 SDK\n3. 公共类库\n4. API 网关模块\n5. 后台接口库\n\n## 后端管理系统\n\n后端管理系统主要为前端提供接口，实现如下功能：\n\n普通用户：\n\n1. OneAPI 用户登录/注册（注册后会自动分配 API 密钥）\n2. 查看已有接口及用户调用情况\n\n管理员：\n\n1. 接口管理：创建接口、修改接口元数据、发布/下线接口\n2. 接口充值：为用户充值接口调用次数\n3. 接口统计：使用 Ant Design 图表库展示接口调用统计\n\n## 客户端 SDK\n\n客户端 SDK 提供给开发者使用，其中封装了 API 签名认证算法以简化开发者调用 API 的流程。\n\nSDK 模块的设计花费了较长的时间，因为必须保证 **可扩展性**，即增加不同的接口时避免对原有代码的改动，因此必须对功能做抽象。\n\n### 设计思想\n\n客户端的整体流程：开发者创建请求对象，使用客户端发起 HTTP 请求至后端网关。\n\n为了提高代码的**可复用性**与**可扩展性**，客户端采用面向抽象的设计模式，将客户端请求的各个环节进行抽象，形成了以下几个封装类：\n\n1. `AbstractModel`：模型类，封装了请求参数的基本信息，通过 Gson 注解在请求的后处理中将**请求/响应参数转换为 JSON 格式**\n   。实现类包含如下两种：\n   - `Request`：请求对象，封装了请求的基本信息。\n   - `Response`：响应对象，封装了响应的基本信息。\n2. `HttpProfile`：HTTP 配置类，封装了 HTTP 请求的基本信息，如请求方法、请求地址、请求协议、请求超时时间等。\n3. `ClientProfile`：客户端配置类，封装了 HttpProfile、签名方法等。\n4. `AbstractClient`：客户端抽象类，封装了 ClientProfile、密钥对象、HTTP 请求方法。实现类：\n   - `OneApiClient`：OneAPI 客户端实现类，封装自定义接口的请求方法。\n\n注：在后台管理系统中，前端页面需为用户提供**在线调用**功能。为了在后端实现对 API 的动态调用，使用了**反射**\n动态创建请求对象以在后端使用 SDK。\n\n## API 网关模块\n\n网关模块需实现的核心功能在于 **抽离出对接口鉴权、请求染色的统一控制等**，该模块在后端接口中可以使用 AOP 实现，但是当有多个后端接口服务时 AOP 就可剥离出来，使用更通用的模块去替代，因此这里使用了 API 网关实现。具体业务功能如下：\n\n1. API 路由：只处理 `/api/**` 的接口地址\n2. 使用请求头部信息实现鉴权：通过时间戳避免请求重放，对用户参数重新计算签名验证签名正确性\n3. 统一接口调用的响应格式：为了提供“健壮”的服务，即使后端程序出错也要**保证返回给调用者有效的信息（错误码、错误原因等）**\n\n改进点：这里的**请求头部验证**可以使用 Gateway 中 **Predicate** 实现，应该使用声明式设计让实现更简洁。\n\n## 后台接口\n\n后台接口，目前仅仅实现了两个随机头像的接口（使用了第三方），该项目目前的核心在于实现 API 平台本身，而不是提供消费级别的接口调用平台。因此可以考虑后期继续扩展。\n\n问题思考：在设计 SDK 模块时，参考了腾讯云的 SDK 设计，发现他们在调用后端接口时候并不是以 RESTful 的标准形式，而是**统一发送到一个域名地址**，并在头部添加请求的后端功能（用 Action 命名）。我认为他们的请求中间应该会经过相应的 API 网关，但通过 Action 参数，如果有效的将其与实际的后端调用地址或方法做映射，此处还可再构思。\n\n## 项目部署\n\n使用 Nginx 反向代理，不对外开放端口。（请求路径应该更业务化一些，可改进）\n\n| 模块         | 端口 | 路径 | 是否对外开放 |\n| ------------ | ---- | ---- | ------------ |\n| 后台管理系统 | 8101 | /api | 否           |\n| API 网关模块 | 8090 | /api | 否           |\n| 后台接口库   | 7089 | /api | 否           |\n\n运行 Docker 命令：\n\n```shell\ndocker run -d --name one-api -p 8101:8101 -m 2G one-api:1.0.0\n```\n\n在部署项目时，发现购买的学生云服务器内存过小，因此使用了 FRP 的内网穿透将服务部署在实验室的服务器上，通过端口映射的形式开发出去。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjinzcdev%2Foneapi-backend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjinzcdev%2Foneapi-backend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjinzcdev%2Foneapi-backend/lists"}