Magic-api介绍及使用
by @Claudia
简介
magic-api 是一个基于Java的接口快速开发框架,编写接口将通过magic-api提供的UI界面完成(如下图),自动映射为HTTP接口,无需定义Controller、Service、Dao、Mapper、XML等Java对象即可完成常见的HTTP API接口开发。
主要特性
- 基于 magic-script 脚本引擎,动态编译,无需重启,实时发布
- 支持多数据源配置,支持运行时动态添加数据源
- 支持导入Spring中的Bean、Java中的类
- 支持自定义工具类、自定义模块包、自定义类型扩展、自定义函数等
其他特性
- 支持MySQL、MariaDB、Oracle、DB2、PostgreSQL、SQLServer 等支持jdbc规范的数据库
- 支持非关系型数据库Redis、Mongodb
- 支持分页查询以及自定义分页查询
- 支持SQL缓存,以及自定义SQL缓存
- 支持SQL拦截、自定义分页方言、自定义列名转换
- 支持自定义JSON结果、自定义分页结果
- 支持对接口权限配置、拦截器等功能
- 支持Swagger接口文档生成
- 支持Linq式查询,关联、转换更简单
- 支持数据库事务、SQL支持拼接,占位符,判断等语法
- 支持文件上传、下载、输出图片
- 支持脚本历史版本对比与恢复
- 支持脚本代码自动提示、错误提示、参数提示、语法错误提示
- 支持在线调试脚本引擎
基本使用
-
首先导入官网提供的 magic-api.sql 文件,主要用于存储在线web页面编写的接口与脚本数据。
-
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for magic_api_info -- ---------------------------- DROP TABLE IF EXISTS `magic_api_info`; CREATE TABLE `magic_api_info` ( `id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `api_method` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '请求方法', `api_path` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '请求路径', `api_script` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '接口脚本', `api_parameter` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '接口参数', `api_option` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '接口选项', `api_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '接口名称', `api_group_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '分组ID', `api_request_body` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '请求体', `api_request_header` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '请求Header', `api_response_body` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '输出结果', `api_response_header` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '输出Header', `api_description` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '接口描述', `api_create_time` bigint NULL DEFAULT NULL COMMENT '创建时间', `api_update_time` bigint NULL DEFAULT NULL COMMENT '修改时间', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'MagicAPI接口信息' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Table structure for magic_api_info_his -- ---------------------------- DROP TABLE IF EXISTS `magic_api_info_his`; CREATE TABLE `magic_api_info_his` ( `id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'api_id', `api_method` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '请求方法', `api_path` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '请求路径', `api_script` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '接口脚本', `api_parameter` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '接口参数', `api_option` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '接口选项', `api_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '接口名称', `api_group_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '分组ID', `api_request_body` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '请求体', `api_request_header` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '请求Header', `api_response_body` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '输出结果', `api_response_header` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '输出Header', `api_description` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '接口描述', `api_create_time` bigint NULL DEFAULT NULL COMMENT '创建时间', `api_update_time` bigint NULL DEFAULT NULL COMMENT '修改时间' ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'MagicAPI接口历史记录' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Table structure for magic_function -- ---------------------------- DROP TABLE IF EXISTS `magic_function`; CREATE TABLE `magic_function` ( `id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主键', `function_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '函数名称', `function_path` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '函数路径', `function_parameter` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '参数列表', `function_return_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '返回值类型', `function_script` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '脚本', `function_group_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '所属分组', `function_description` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '函数描述', `function_create_time` bigint NULL DEFAULT NULL COMMENT '创建时间', `function_update_time` bigint NULL DEFAULT NULL COMMENT '修改时间', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'MagicAPI 函数表' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Table structure for magic_function_his -- ---------------------------- DROP TABLE IF EXISTS `magic_function_his`; CREATE TABLE `magic_function_his` ( `id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'function_id', `function_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '函数名称', `function_path` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '函数路径', `function_parameter` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '参数列表', `function_return_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '返回值类型', `function_script` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '脚本', `function_group_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '所属分组', `function_description` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '函数描述', `function_create_time` bigint NULL DEFAULT NULL COMMENT '创建时间', `function_update_time` bigint NULL DEFAULT NULL COMMENT '修改时间' ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'MagicAPI 函数历史记录' ROW_FORMAT = DYNAMIC; -- ---------------------------- -- Table structure for magic_group -- ---------------------------- DROP TABLE IF EXISTS `magic_group`; CREATE TABLE `magic_group` ( `id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `group_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '组名', `group_type` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '组类型,1:接口分组,2:函数分组', `group_path` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '分组路径', `parent_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '父级ID', `deleted` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '是否被删除,1:是,0:否', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'MagicAPI分组信息表' ROW_FORMAT = DYNAMIC; SET FOREIGN_KEY_CHECKS = 1;
-
创建 Spring Boot 项目引入 Maven 依赖
<!-- 推荐用最新版 --> <dependency> <groupId>org.ssssssss</groupId> <artifactId>magic-api-spring-boot-starter</artifactId> <version>0.6.1</version> </dependency>
-
修改 application.properties
server.port=9999 #配置web页面入口 magic-api.web=/magic/web #以下配置需跟实际情况修改 spring.datasource.url=jdbc:mysql://localhost/test spring.datasource.username=root spring.datasource.password=123456789 spring.datasource.driver-class-name=com.mysql.jdbc.Driver
-
如上代码是默认数据库magic-api的配置,实际开发中需要实现多数据源配置,因此application.properties修改如下:
server.port=9999 #配置web页面入口 magic-api.web=/magic/web # database db.conn.str=useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai # 默认主数据源 spring.datasource.magic.jdbc-url=jdbc:mysql://localhost:3306/magic-api?${db.conn.str} spring.datasource.magic.username=root spring.datasource.magic.password= spring.datasource.magic.driver-class-name=com.mysql.cj.jdbc.Driver # pm数据源 spring.datasource.pm.jdbc-url=jdbc:mysql://localhost:3306/pm?${db.conn.str} spring.datasource.pm.username=root spring.datasource.pm.password= spring.datasource.pm.driver-class-name=com.mysql.cj.jdbc.Driver
-
建立spring boot 多数据配置文件 DataSourceConfig.java
@Configuration public class DataSourceConfig { @Primary @Bean(name = "magic") @Qualifier("magic") @ConfigurationProperties(prefix = "spring.datasource.magic") public DataSource magicDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "pm") @Qualifier("pm") @ConfigurationProperties(prefix = "spring.datasource.pm") public DataSource pmDataSource() { return DataSourceBuilder.create().build(); } @Bean public MagicDynamicDataSource magicDynamicDataSource() { MagicDynamicDataSource dynamicDataSource = new MagicDynamicDataSource(); dynamicDataSource.setDefault(magicDataSource()); dynamicDataSource.add("pm", pmDataSource()); return dynamicDataSource; } }
-
脚本中使用:
//从pm库中查询 db.pm.select('select * from xxx'); //使用默认magic-api数据源 db.select('select * from xxx');
-
启动项目
-
-
浏览器访问 http://localhost:9999/magic/web 进行在线操作,页面左侧有“接口列表”与“函数列表”:“接口列表”主要负责业务具体逻辑操作;“函数列表”主要封装一些常用的操作,就像数据库中的函数一样,是一个作用,代码里直接使用“函数名(参数1,参数2,…) ”调用即可。
-
以上为Magic-api入门操作。
功能列表:
详细功能列表可见官方文档地址:https://ssssssss.org/
数据库查询
-
当执行SQL需要动态参数时,可以使用
?{condition,expression}
#{expressio}
,${expression}
, 表示,其中#{}
,${}
与Mybatis作用一致,?{condition,expression}
作用是先判断,如果条件成立则拼接后部分SQL内容,与mybatis中的if
标签基本一致。 -
例如,实现从数据库中查询 用户id
u_id
为 1 的材料代码列表,先创建接口分组,其中每创建一个分组必须设置“分组前缀”,即访问的路径前缀: -
然后编写具体接口代码,在“接口信息”一栏设置接口名称,请求路径,请求参数等。
var sql = "select distinct stuff_code from pm_stuff ?{id, where u_id = #{u_id}}"; return db.pm.select(sql);
-
-
以上为开发一个简单接口的基本流程,magic-api具有热更新的特点,无需重启即可测试接口,postman测试接口结果:
-
调用Java封装的类与方法
-
这是Magic-api最显著的一个特点,并且与magic-scipt语法结合可省去框架层级调用的繁琐。
-
例如,实现根据用户Token与零件代码获取唯一零件信息,请求参数为token与code:首先在Java的IDE端封装好从用户token提取u_id的工具类,然后在脚本内调用方法,编辑代码获取数据库信息。
-
-
使用Postman测试接口:
调用Java自定义模块
-
定义用@Component修饰的Java类,并继承MagicModule接口,重写
getModuleName()
方法用于在脚本内直接调用。 -
-
项目重新启动后在脚本内调用及结果:
-
自定义函数
-
magic-api自定义函数是指 定义用@Component修饰的Java类,并设置方法,用@Function修饰。在线脚本编辑时直接调用方法名即可,不需要引入。
-
自定义函数实例:首先定义CustomFunc类,添加@Component注解实例化到 Spring 容器中,然后定义方法添加@Function注解,@Comment注解
-
package wen.magic.demo.func; import java.util.Date; import org.springframework.stereotype.Component; import org.ssssssss.magicapi.config.MagicFunction; import org.ssssssss.script.annotation.Comment; import org.ssssssss.script.annotation.Function; import org.ssssssss.script.functions.DateExtension; @Component public class CustomFunc implements MagicFunction { @Function @Comment("自定义函数:无参有返回值") public static Date customNow() { return new Date(); } @Function @Comment("自定义函数:有参有返回值") public static String dateFormat(@Comment("目标日期") Date target) { return target == null ? null : DateExtension.format(target, "yyyy-MM-dd HH:mm:ss"); } @Function @Comment("自定义函数:多个参数有返回值") public static Object ifNull( @Comment("目标值") Object target, @Comment("为空的值") Object trueValue, @Comment("不为空的值") Object falseValue) { return target == null ? trueValue : falseValue; } }
-
启动项目后在脚本中调用函数名即可
-
-
-
自定义重写接口
- 继承 ApiServiceProvider 内部类,添加 @Component 注解,重写接口:
##### 自定义脚本函数
-
magic-api的在线编辑页面有“接口列表”与“函数列表”,用户可在“函数列表”中定义函数,“接口列表”中引入即可调用,实例如下:
-
首先,自定义函数compare,参数为a和b,实现两个数的比较及操作:
-
-
再建立函数invoker,调用刚刚的操作:
-
-
最后,接口列表页面新建接口,调用函数invoker,执行结果如下:
-
-
以上是接口调用函数,如果接口之间相互调用则需要在 import 的内容之前加入"get:",例如
import '@get:/other/assert' as test;
如下图,“demo2Linq转换”分组中的 call接口 调用“demo3其他测试”分组的 assert接口: -
官方资料
官方gitee地址:https://gitee.com/ssssssss-team/magic-api
官方文档地址:https://ssssssss.org
在线demo演示地址:http://140.143.210.90:9999/magic/web
总结
主要优点:
- 快速开发:无需定义Controller、Service、Dao、Mapper、XML等Java对象,magic-api的出发点就是在于快速开发,熟悉了之后在适当的场景中开发起来远比传统方式要快许多。
- 在线IDE:提供Web页面,在线编写脚本,在线DEBUG,脚本编辑之后无需重启,自动热更新。
- magic-script语法带来的便利性,比如写SQL用文本块(低版本JDK是不支持的)、结果转换用linq/lambda等。
- 其他:代码生成试、分页、Redis、MongoDB、支持各种函数库等。
不足之处:
- magic-script在满足基本开发需求的前提下,仍然缺少脚本格式化代码、SQL提示、接口同步、文档推送、在线管理数据源的功能,但后续会支持在线管理数据源的方案。
- 对于多数据源事务支持的还不够好。
- 面对逻辑复杂的应用场景,magic-api对java封装的工具类与对象仍然有较强依赖。
文章测试demo github地址
更多推荐