一个能 💯 替代 springdoc-openapi/Swagger 的 API 生产工具,既不需要修改后端代码,也不需要启动应用
demo:Desktop/ $ oneapi analysis -p ./spring-boot-demo -o . [20:21:48][INFO] Scanning for projects...SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".SLF4J: Defaulting to no-operation (NOP) logger implementationSLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.[20:21:59] version: 1.0.1[20:21:59] cache reflect class[20:22:00] found 2625 jar file from /Users/demo/.m2[20:22:03] cache 581464 class[20:22:03] cache resource[20:22:03] found 7 class from /Users/demo/Desktop/spring-boot-demo[20:22:03] found 1 entry class[20:22:03] ====== analysis entry ======[20:22:03] class: com.xkcoding.swagger.controller.UserController[20:22:03] field count: 0[20:22:03] method: getByUserName[20:22:03] params:[20:22:03] username: String[20:22:03] return: ApiResponse<User>[20:22:03] child type: User[20:22:03] method: get[20:22:03] params:[20:22:03] id: Integer[20:22:03] return: ApiResponse<User>[20:22:03] child type: User[20:22:03] method: delete[20:22:03] params:[20:22:03] id: Integer[20:22:03] return: void[20:22:03] method: post[20:22:03] params:[20:22:03] user: User[20:22:03] return: User[20:22:03] method: multipar[20:22:03] params:[20:22:03] user: List<User>[20:22:03] child type: User[20:22:03] return: List<User>[20:22:03] child type: User[20:22:03] method: array[20:22:03] params:[20:22:03] user: User[][20:22:03] child type: com.xkcoding.swagger.entity.User[20:22:03] return: User[][20:22:03] child type: com.xkcoding.swagger.entity.User[20:22:03] method: put[20:22:03] params:[20:22:03] id: Long[20:22:03] user: User[20:22:03] return: void[20:22:03] method: file[20:22:03] params:[20:22:03] id: Long[20:22:03] file: MultipartFile[20:22:03] return: String[20:22:03] ====== analysis resource ======[20:22:03] class: com.xkcoding.swagger.entity.User[20:22:03] field count: 3[20:22:03] id: Integer[20:22:03] name: String[20:22:03] job: String[20:22:03] class: com.xkcoding.swagger.common.DataType[20:22:03] field count: 0[20:22:03] class: com.xkcoding.swagger.common.ParamType[20:22:03] field count: 0[20:22:03] class: com.xkcoding.swagger.common.ApiResponse[20:22:03] field count: 3[20:22:03] code: Integer[20:22:03] message: String[20:22:03] data: T[20:22:05] exec time: 5 second✅ OneAPI Schema 解析完成(耗时8s): /Users/demo/Desktop/oneapi.jsondemo:Desktop/ $ oneapi service -s ./oneapi.json -r 'import request from "@/utils/request";' -o .✅ Services 文件生成完成: /Users/demo/Desktop/servicesdemo:Desktop/ $ tree services [20:22:45]services├── model│ ├── common│ │ └── apiResponse.ts│ └── entity│ └── user.ts└── userController.ts3 directories, 3 filesdemo:Desktop/ $ cat services/userController.ts [20:22:52]import request from "@/utils/request";import { ApiResponse } from "./model/common/apiResponse";import { User } from "./model/entity/user";/** 条件查询(DONE) */export async function getByUserName(args: {username?: string,}): Promise<ApiResponse<User>> {return request({method: 'GET',url: '/user',params: {username: args.username,},headers: {'Content-Type': 'application/json',},});}/** 主键查询(DONE) */export async function get(args: {id: number,}): Promise<ApiResponse<User>> {return request({method: 'GET',url: `/user/${args.id}`,headers: {'Content-Type': 'application/json',},});}/** 删除用户(DONE) */export async function deleteController(args: {id: number,}): Promise<void> {return request({method: 'POST',url: `/user/${args.id}`,headers: {'Content-Type': 'application/json',},});}/** 添加用户(DONE) */export async function post(args: {user?: User,}): Promise<User> {return request({method: 'POST',url: '/user',data: {user: args.user,},headers: {'Content-Type': 'application/json',},});}/** 添加用户(DONE) */export async function multipar(args: {user?: Array<User>,}): Promise<Array<User>> {return request({method: 'POST',url: '/user/multipar',data: {user: args.user,},headers: {'Content-Type': 'application/json',},});}/** 添加用户(DONE) */export async function array(args: {user?: Array<User>,}): Promise<Array<User>> {return request({method: 'POST',url: '/user/array',data: {user: args.user,},headers: {'Content-Type': 'application/json',},});}/** 修改用户(DONE) */export async function put(args: {id: number,user?: User,}): Promise<void> {return request({method: 'POST',url: `/user/${args.id}`,data: {user: args.user,},headers: {'Content-Type': 'application/json',},});}/** 文件上传(DONE) */export async function file(args: {id: number,file?: any,}): Promise<string> {return request({method: 'POST',url: `/user/${args.id}/file`,data: {file: args.file,},headers: {'Content-Type': 'multipart/form-data',},});}demo:Desktop/ $ oneapi openapi -s ./oneapi.json -o . [20:23:06]✅ openapi.json 转换完成: /Users/demo/Desktop/openapi.jsondemo:Desktop/ $ cat openapi.json [20:23:21]{"openapi": "3.0.0","info": {"title": "","version": "","description": ""},"paths": {"/user": {"post": {"tags": ["UserController"],"operationId": "post","summary": "添加用户(DONE)","description": "添加用户(DONE)","requestBody": {"content": {"application/json": {"schema": {"type": "object","properties": {"user": {"$ref": "#/components/schemas/User"}}}}}},"responses": {"200": {"description": "","content": {"application/json": {"schema": {"$ref": "#/components/schemas/User"}}}}}}},"/user/{id}": {"post": {"tags": ["UserController"],"operationId": "put","summary": "修改用户(DONE)","description": "修改用户(DONE)","parameters": [{"name": "id","in": "path","description": "","required": true,"type": "number"}],"requestBody": {"content": {"application/json": {"schema": {"type": "object","properties": {"user": {"$ref": "#/components/schemas/User"}}}}}},"responses": {"200": {"description": "","content": {"application/json": {"schema": {"$ref": "#/components/schemas/void"}}}}}}},"/user/multipar": {"post": {"tags": ["UserController"],"operationId": "multipar","summary": "添加用户(DONE)","description": "添加用户(DONE)","requestBody": {"content": {"application/json": {"schema": {"type": "object","properties": {"user": {"type": "array","items": {"$ref": "#/components/schemas/User"}}}}}}},"responses": {"200": {"description": "","content": {"application/json": {"schema": {"$ref": "#/components/schemas/Array<User>"}}}}}}},"/user/array": {"post": {"tags": ["UserController"],"operationId": "array","summary": "添加用户(DONE)","description": "添加用户(DONE)","requestBody": {"content": {"application/json": {"schema": {"type": "object","properties": {"user": {"type": "array","items": {"$ref": "#/components/schemas/User"}}}}}}},"responses": {"200": {"description": "","content": {"application/json": {"schema": {"$ref": "#/components/schemas/Array<User>"}}}}}}},"/user/{id}/file": {"post": {"tags": ["UserController"],"operationId": "file","summary": "文件上传(DONE)","description": "文件上传(DONE)","parameters": [{"name": "id","in": "path","description": "","required": true,"type": "number"}],"requestBody": {"content": {"multipart/form-data": {"schema": {"type": "object","properties": {"file": {"type": "object"}}}}}},"responses": {"200": {"description": "","content": {"application/json": {"schema": {"$ref": "#/components/schemas/string"}}}}}}}},"components": {"schemas": {"User": {"type": "object","properties": {"id": {"type": "number"},"name": {"type": "string"},"job": {"type": "string"}}},"ApiResponse<User>": {"type": "object","properties": {"code": {"type": "number"},"message": {"type": "string"},"data": {"$ref": "#/components/schemas/User"}}},"Array<User>": {"type": "array","items": {"$ref": "#/components/schemas/User"}},"ApiResponse": {"type": "object","properties": {"code": {"description": " "通用返回状态","type": "number"},"message": {"description": "通用返回信息","type": "string"},"data": {"description": "通用返回数据","type": "object"}}}}}}
基于 AST 识别项目中符合规范的 API,既不需要修改后端代码,也不需要启动应用
自动识别方法&字段中定义的 JavaDoc 作为 API 文档的描述信息(兼容 Swagger 注解)
与业界其他工具相比,OneAPI 专注于 API 生产,也支持导出 OpenAPI 协议格式数据,方便在其他工具中消费
除 RESTFul API 外,可以通过 Node 来扩展识别企业内部自定义协议,如 RPC、GraphQL 等