一款接口快速开发框架
mhr18 2024-12-24 12:24 22 浏览 0 评论
在日常开发过程中我们总是需要写很多的CRUD接口,乏味且无聊。太多重复性的工作,会降低我们的工作热情!现在有这么一款框架,可以快速的帮助你编写这些接口,甚至包括一些复杂的逻辑处理,那么它就是magic-api。
magic-api 是一个基于Java的接口快速开发框架,编写接口将通过magic-api提供的UI界面完成,自动映射为HTTP接口,无需定义Controller、Service、Dao、Mapper、XML、VO等Java对象即可完成常见的HTTP API接口开发
【已有上千家中小型公司使用,上万名开发者用于接口配置开发。上百名开发者参与提交了功能建议,接近20多名贡献者参与。已被gitee长期推荐。从首个版本开始不断优化升级,目前版本稳定,开发者交流群活跃。】
开源地址:https://gitee.com/ssssssss-team/magic-api
特性
- 支持MySQL、MariaDB、Oracle、DB2、PostgreSQL、SQLServer 等支持jdbc规范的数据库
- 支持非关系型数据库Redis、Mongodb
- 支持集群部署、接口自动同步。
- 支持分页查询以及自定义分页查询
- 支持多数据源配置,支持在线配置数据源
- 支持SQL缓存,以及自定义SQL缓存
- 支持自定义JSON结果、自定义分页结果
- 支持对接口权限配置、拦截器等功能
- 支持运行时动态修改数据源
- 支持Swagger接口文档生成
- 基于magic-script脚本引擎,动态编译,无需重启,实时发布
- 支持Linq式查询,关联、转换更简单
- 支持数据库事务、SQL支持拼接,占位符,判断等语法
- 支持文件上传、下载、输出图片
- 支持脚本历史版本对比与恢复
- 支持脚本代码自动提示、参数提示、悬浮提示、错误提示
- 支持导入Spring中的Bean、Java中的类
- 支持在线调试
- 支持自定义工具类、自定义模块包、自定义类型扩展、自定义方言、自定义列名转换等自定义操作
快速开始
首先我们新建一个springboot工程,这里就不过多赘述,接下来引入magic-api依赖
<!-- 以spring-boot-starter的方式引用 -->
<dependency>
<groupId>org.ssssssss</groupId>
<artifactId>magic-api-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
修改application.properties
magic-api:
web: /magic/web # UI请求的界面以及UI服务地址
resource: #配置存储方式
type: database # 配置存储在数据库中
tableName: magic_api_file_v2 # 数据库中的表名
#datasource: magic #指定数据源(单数据源时无需配置,多数据源时默认使用主数据源,如果存在其他数据源中需要指定。)
prefix: /magic-api # key前缀
readonly: false # 是否是只读模式
prefix: / # 接口前缀,可以不配置
auto-import-module: db # 自动导入的模块
auto-import-package: java.lang.*,java.util.* #自动导包
allow-override: false #禁止覆盖应用接口
sql-column-case: camel #启用驼峰命名转换
editor-config: classpath:./magic-editor.js #编辑器配置
support-cross-domain: true # 跨域支持,默认开启
#secret-key: 123456789 # 远程推送时的秘钥,未配置则不开启推送
#push-path: /_magic-api-sync #远程推送的路径,默认为/_magic-api-sync
show-sql: true #配置打印SQL
compile-cache-size: 500 #配置编译缓存容量
persistence-response-body: true #是否持久化保存ResponseBody
date-pattern: # 配置请求参数支持的日期格式
- yyyy-MM-dd
- yyyy-MM-dd HH:mm:ss
- yyyyMMddHHmmss
- yyyyMMdd
response: |- #配置JSON格式,格式为magic-script中的表达式
{
state: code == 1 ? 'success' : 'fail',
msg: message,
data,
timestamp,
requestTime,
executeTime,
}
response-code:
success: 1 #执行成功的code值
invalid: 0 #参数验证未通过的code值
exception: -1 #执行出现异常的code值
banner: true # 打印banner
thread-pool-executor-size: 8 # async语句的线程池大小
throw-exception: false #执行出错时是否抛出异常
backup: #备份相关配置
enable: true #是否启用
max-history: -1 #备份保留天数,-1为永久保留
#datasource: magic #指定数据源(单数据源时无需配置,多数据源时默认使用主数据源,如果存在其他数据源中需要指定。)
table-name: magic_backup_record_v2 #使用数据库存储备份时的表名
crud: # CRUD相关配置
logic-delete-column: deleted #逻辑删除列
logic-delete-value: 1 #逻辑删除值
cache: # 缓存相关配置
capacity: 10000 #缓存容量
ttl: -1 # 永不过期
enable: true # 启用缓存
page:
size: pageSize # 页大小的参数名称
page: page # 页码的参数名称
default-page: 1 # 未传页码时的默认首页
default-size: 10 # 未传页大小时的默认页大小
security: # 安全配置
username: admin # 登录用的用户名
password: 123456 # 登录用的密码
swagger:
version: 1.0
description: MagicAPI 接口信息
title: MagicAPI Swagger Docs
name: MagicAPI 接口
location: /v2/api-docs/magic-api/swagger2.json
debug:
timeout: 60 # 断点超时时间,默认60s
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.1.197:3306/magic-api-test?allowMultiQueries=true&useUnicode=true&characterEncoding=utf-8&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai
username: root
password: 123
从上面的配置文件我们可以看出magic-api支持配置存储方式数据库/磁盘,可以更好的迁移与备份;支持开始是否跨域,无需我们另外手写跨域配置;支持请求参数配置日期格式;支持配置统一的返回格式;支持在线编辑页面的登录管理;支持缓存配置;支持自定义插件引入;
启动项目
********************************************当前服务相关地址********************************************
服务启动成功,magic-api已内置启动! Access URLs:
接口本地地址: http://localhost:9999/
接口外部地址: http://192.168.57.1:9999/
接口配置平台: http://192.168.57.1:9999/magic/web/index.html
可通过配置关闭输出: magic-api.show-url=false
********************************************当前服务相关地址********************************************
项目启动成功我们可以看到输出的接口根目录与在线编辑的web地址
登录
访问http://localhost:9999/magic/web或者http://192.168.57.1:9999/magic/web/index.html进行操作
由于我们开启了登录验证,所以需要我们登录一下才能进入管理页面。magic-api也提供了登录方法的拦截器让我们自定义校验,通过这个拦截器我们可以实现和数据库的账号密码接入,实现员工一人一账号,下面是拦截器代码
#配置用户名密码
默认情况下是不配置用户名密码的。
如果需要可以通过以下配置开启用户名密码验证登录。
magic-api:
security:
username: admin # 登录用的用户名
password: 123456 # 登录用的密码
#多用户登录
如果需要配置多用户登录,则需要使用自定义鉴权的方式。
/**
* 自定义用户名密码登录
*/
@Component //注入到Spring容器中
public class CustomAuthorizationInterceptor implements AuthorizationInterceptor {
/**
* 配置是否需要登录
*/
@Override
public boolean requireLogin() {
return true;
}
/**
* 根据Token获取User
*/
@Override
public MagicUser getUserByToken(String token) throws MagicLoginException {
if (判断token是否有效) {
return magicUser; // 从token中获取MagicUser对象
}
throw new MagicLoginException("token无效");
}
@Override
public MagicUser login(String username, String password) throws MagicLoginException {
// 根据实际情况进行修改,如查询数据库。。
if("admin".equals(username) && "admin".equals(password)){
// 登录成功后 构造MagicUser对象。
return new MagicUser("1","admin","tokenvalue......");
}
throw new MagicLoginException("用户名或密码不正确");
}
}
管理页面
接下来我们输入配置的账号密码登录,进入管理页面
界面简介
整体说明
接口信息
RequestBody
ResponseBody
DEBUG
创建接口
1. 创建分组
点击创建分组按钮后,输入分组信息,点击创建。
2. 新建接口
右键分组,点击新建接口。
在编辑器输入内容后,填写接口名称和及其路径。
var sql = """
select * from test_data
"""
return db.select(sql)
ctrl+s保存后,即可访问接口。
3.访问接口
> curl http://localhost:9999/test/test
{
"code": 1,
"message": "success",
"data": [
{
"id": 1,
"name": "magicApi"
},
{
"id": 2,
"name": "xiaoDong"
}
],
"timestamp": 1638192442535,
"executeTime": 9
}
? 也可以通过web界面执行。
通过以上几个步骤,我们就实现了一个简单的查询功能。省去了Controller、Service、Dao、Mapper、XML、VO等模板代码的工作量。
脚本语法
#关键字
关键字 | 含义 |
var | 定义变量 |
if | 条件语句的引导词 |
else | 用在条件语句中,表明当条件不成立时的分支 |
for | for循环语句 |
in | 与for配合使用 |
while | while循环语句 |
continue | 执行下一次循环 |
break | 跳出循环 |
return | 终止当前过程的执行并正常退出到上一个执行过程中 |
exit | 终止当前脚本,并退出返回,如exit 200,'执行成功',[1,2,3]; v0.5.0中新增 |
assert | 断言 v1.3.4中新增 |
instanceof | 判断一个对象是否为一个类的实例 v2.0.0中新增 |
try | 用于捕获可能发生异常的代码块 |
catch | 与try关键字配合使用,当发生异常时执行 |
finally | 与try关键字配合使用,finally块无论发生异常都会执行 |
import | 导入Java类或导入已定义好的模块 |
as | 与 import 关键字配合使用,用作将导入的 Java类或模块 命名为一个本地变量名 |
new | 创建对象 |
true | 基础类型之一,表示 Boolean 的:真值 |
false | 基础类型之一,表示 Boolean 的:假值 |
null | 基础类型之一,表示 NULL 值 |
async | 异步调用 |
#运算符
数学运算 | 比较运算 | 逻辑运算 | 位运算 | ||||
+ | 加法 | < | 小于 | && | 并且 | &、&= | 与 |
- | 减法 | <= | 小于等于 | || | 或者 | |、|= | 或 |
* | 乘法 | > | 大于 | ^、^= | 异或 | ||
/ | 除法 | >= | 大于等于 | ~、~= | 取反 | ||
% | 取模 | == | 等于 | <<、<<= | 左移 | ||
++ | 自增 | != | 不等于 | >>、>>= | 右移 | ||
-- | 自减 | === | 等于 | >>>、>>>= | 无符号右移 | ||
!== | 不等于 |
#类型
类型 | 写法 |
byte | 123b、123B |
short | 123s、123S |
int | 123 |
long | 123l、123L |
float | 123f、123F |
double | 123d、123D |
BigDecimal | 123m、123M |
boolean | true、false |
string | 'hello' |
string | "hello" |
string | """多行文本块,主要用于编写SQL""" |
Pattern | /\d+/g,/pattern/gimuy 用于定义正则 |
lambda | ()=>expr、(param1,param2....)=>{...} |
list | [1,2,3,4,5] |
map | {key : value,key1 : value} |
{[key] : "value"} [key]表示动态从变量中获取key值
#一元运算符
您可以通过一元运算-符将数字取反,例如-234。要取反布尔表达式,可以使用!运算符,例如!true。 自增/自减 i++ 、 ++i、i--、--i
#算术运算符
支持常见的算术运算符,例如1 + 2 * 3 / 4 % 2,同样也支持+=、-=、*=、/=、%=
#比较运算符
23 < 34,23 <= 34,23 > 34,23 >= 34,true != false,23 == 34
比较运算符结果为boolean类型
#逻辑运算符
除了一元运算!符,您还可以使用&&和||。就像Java中一样,运算符也是一种短路运算符。如果&&左边计算为false,则不会计算右边。如果||左侧为true,则不会计算右边 在0.4.6+版本中增强了&& || 不再强制两边必须是布尔类型。作用与JS一样
#三元运算符
三元运算符是if语句的简写形式,其工作方式类似于Java中,例如true ? "yes" : "no" 在0.4.3+版本中,增强了if 和三元运算符,不再强制值必须是布尔类型,可以写if(xxx)的形式当xxx为以下情况时为fasle、其它情况为true
- null
- 空集合
- 空Map
- 空数组
- 数值==0
- 非空字符串
- false
#类型转换
可使用::type(defaultValue) 的方式进行类型转换,如
var a = "123"::int; // 123
var b = "abc"::int(111); // 111
var c = "2020-01-01"::date('yyyy-MM-dd'); // 转换为date
#可选链操作符
可选链操作符(?.)允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?.操作符的功能类似于.链式操作符,不同之处在于,在引用为空 的情况下不会引起错误,该表达式短路返回值是 null。
当尝试访问可能不存在的对象属性时,可选链操作符将会使表达式更短、更简明。在探索一个对象的内容时,如果不能确定哪些属性必定存在,可选链操作符也是很有帮助的。
obj?.prop
obj?.method(args)
示例:
var a = null;
var b = a?.name; // b = null;
var c = a?.getName(); // c = null;
#扩展运算符
扩展运算符,又叫展开语法(Spread syntax), 是用于将list或map在语法层面展开;
语法:
lambda 调用
var sum = (a,b,c) => a + b + c;
System.out.println(sum(...[1,2,3]))
/*
结果:6
*/
list 展开
var arr = [3,4,5];
System.out.println([1,2,...arr,6,7])
/*
结果:[1, 2, 3, 4, 5, 6, 7]
*/
list 展开到 map 中
var arr = [3,4,5];
System.out.println({key1:1,...arr})
/*
结果:{key1=1, 0=3, 1=4, 2=5}
虽然这些key看起来像数值,但其实是String类型的key,如果把它们转为JSON看起来是这样的:
{"key1":1, "0":3, "1":4, "2":5}
*/
map 展开
var map = {key2:2}
System.out.println({key1:1,...map,key3:3})
/*
结果:{key1=1, key2=2, key3=3}
*/
#for循环
当前for循环只支持两种,循环集合或Map
#循环集合
import 'java.lang.System' as System;
var list = [1,2,3];
for(index,item in list){ //如果不需要index,也可以写成for(item in list)
System.out.println(index + ":" + item);
}
/*
结果:
0:1
1:2
2:3
*/
#循环指定次数
var sum = 0;
for(value in range(0,100)){ //包括0包括100
sum = sum + value; //不支持+= -= *= /= ++ -- 这种运算
}
return sum;
/*
结果:5050
*/
#while循环
var count = 100;
var sum = 0;
while(count){
sum = sum + count;
count = count - 1;
}
return sum; // 5050
#循环map
import 'java.lang.System' as System;
var map = {
key1 : 123,
key2 : 456
};
for(key,value in map){ //如果不需要key,也可以写成for(value in map)
System.out.println(key + ":" + value);
}
/*
结果:
key1:123
key2:456
*/
#Import导入
#导入Java类
import 'java.lang.System' as System;//导入静态类并赋值给system作为变量
import 'javax.sql.DataSource' as ds;//从spring中获取DataSource并将值赋值给ds作为变量
import 'org.apache.commons.lang3.StringUtils' as string;//导入静态类并赋值给ds作为变量
import 'java.text.*' //此写法跟Java一致,在1.3.4中新增
System.out.println('调用System打印');//调用静态方法
System.out.println(ds);
System.out.println(string.isBlank('')); //调用静态方法
System.out.println(new SimpleDateFormat('yyyy-MM-dd').format(new Date())); // 2020-01-01
#new创建对象
#创建对象
import 'java.util.Date' as Date;//创建之前先导包,不支持.*的操作
return new Date();
#导入已定义的模块
import log; //导入log模块,并定义一个与模块名相同的变量名
//import log as logger; //导入log模块,并赋值给变量 logger
log.info('Hello {}','Magic API!')
#异步调用
#异步调用方法
var val = async db.select('.....'); // 异步调用,返回Future类型
return val.get(); //调用Future的get方法
#异步调用lambda
var list = [];
for(index in range(1,10)){
list.add(async (index)=>db.selectInt('select #{index}'));
}
return list.map(item=>item.get()); // 循环获取结果
#exit
语法格式为 exit expr[,expr][,expr][,expr][,expr][,expr][,expr]....
在magic-api中只取前三个值,分别对应code、message、data
如:exit 400,'参数填写有误'
#assert
语法格式为 assert expr : expr[,expr][,expr][,expr][,expr][,expr][,expr].... 如:assert a == 1 : 400, 'a的值应为1' 相当于
if(a != 1){
exit 400, 'a的值应为1'
}
#类型转换
通过::进行类型转换,如xxx::int、xxx::double等, 当前支持转换类型有int、double、long、byte、short、float、date
var a = "1";
return {
v1: a::int,
v2: a::int(0), //转换失败时,值为0
v3: "2020-01-01"::date('yyyy-MM-dd') //转为Date
}
? ::sql支持将数据转换为对应的sql类型, 比如:
img::sql('blob')
? 可传入的参数请参考java.sql.Types中定义的常量,不区分大小写。
#嵌入其它脚本语言
var name = "hello";
var test = ```javascript
name + ' ~ world'
```;
return test();
文档/演示
- 文档地址:https://ssssssss.org
- 在线演示:https://magic-api.ssssssss.org
最后
本文仅仅演示magic-api的一些简单功能,如果大家感兴趣的话可以自行到官方网站去学习!或者你有更好的开发框架或意见也可在评论区留言。
- 上一篇:批处理相关技术在支付业务系统中的应用
- 下一篇:上海公司大数据面试题(面经)
相关推荐
- MySQL数据库中,数据量越来越大,有什么具体的优化方案么?
-
个人的观点,这种大表的优化,不一定上来就要分库分表,因为表一旦被拆分,开发、运维的复杂度会直线上升,而大多数公司和开发人员是欠缺这种能力的。所以MySQL中几百万甚至小几千万的表,先考虑做单表的优化。...
- Redis的Bitmap(位图):签到打卡、用户在线状态,用它一目了然
-
你是不是每天打开APP,第一时间就是去“签到打卡”?或者在社交软件里,看到你的朋友头像旁边亮着“在线”的绿灯?这些看似简单的功能背后,都隐藏着一个有趣而高效的数据结构。如果让你来设计一个签到系统:用户...
- 想知道有多少人看了你的文章?Redis HyperLogLog几KB就搞定!
-
作为一名内容创作者,你每天最期待的,除了文章阅读量蹭蹭上涨,是不是还特别想知道,到底有多少个“独立用户”阅读了你的文章?这个数字,我们通常称为“UV”(UniqueVisitors),它比总阅读量更...
- Redis的“HyperLogLog”:统计网站日活用户,省内存又高效的神器
-
你可能从未听过这个拗口的名字——“HyperLogLog”,它听起来就像是某个高深莫测的数学公式。但请相信我,理解它的核心思想并不难,而且一旦你掌握了它,你会发现它在处理大数据统计问题时,简直就是“救...
- 阿里云国际站:为什么我的云服务器运行缓慢?
-
本文由【云老大】TG@yunlaoda360撰写一、网络性能瓶颈带宽不足现象:上传/下载速度慢,远程连接卡顿。排查:通过阿里云控制台查看网络流量峰值是否接近带宽上限34。解决:升级带宽(如从1M提...
- Java 近期新闻:Jakarta EE 11和Spring AI更新、WildFly 36.0 Beta、Infinispan
-
作者|MichaelRedlich译者|明知山策划|丁晓昀OpenJDKJEP503(移除32位x86移植版本)已从“ProposedtoTarget”状态进入到“T...
- 腾讯云国际站:怎样设置自动伸缩应对流量高峰?
-
云计算平台服务以阿里云为例:开通服务与创建伸缩组:登录阿里云控制台,找到弹性伸缩服务并开通。创建伸缩组时,选择地域与可用区,定义伸缩组内最小/最大实例数,绑定已有VPC虚拟交换机。实例模板需...
- 【案例分享】如何利用京东云建设高可用业务架构
-
本文以2022年一个实际项目为基础,来演示在京东云上构建高可用业务的整个过程。公有云及私有云客户可通过使用京东云的弹性IAAS、PAAS服务,创建高可用、高弹性、高可扩展、高安全的云上业务环境,提升业...
- Spring Security在前后端分离项目中的使用
-
1文章导读SpringSecurity是Spring家族中的一个安全管理框架,可以和SpringBoot项目很方便的集成。SpringSecurity框架的两大核心功能:认证和授权认证:...
- Redis与Java集成的最佳实践
-
Redis与Java集成的最佳实践在当今互联网飞速发展的时代,缓存技术的重要性毋庸置疑。Redis作为一款高性能的分布式缓存数据库,与Java语言的结合更是如虎添翼。今天,我们就来聊聊Redis与Ja...
- Redis在Java项目中的应用与数据持久化
-
Redis在Java项目中的应用与数据持久化Redis简介:为什么我们需要它?在Java项目中,Redis就像一位不知疲倦的快跑选手,总能在关键时刻挺身而出。作为一个内存数据库,它在处理高并发请求时表...
- Redis 集群最大节点个数是多少?
-
Redis集群最大节点个数取决于Redis的哈希槽数量,因为每个节点可以负责多个哈希槽。在Redis3.0之前,Redis集群最多支持16384个哈希槽,因此最大节点数为16384个。但是在Redi...
- Java开发岗面试宝典:分布式相关问答详解
-
今天千锋广州Java小编就给大家分享一些就业面试宝典之分布式相关问题,一起来看看吧!1.Redis和Memcache的区别?1、存储方式Memecache把数据全部存在内存之中,断电后会挂掉,数据不...
- 当Redis内存不足时,除了加内存,还有哪些曲线救国的办法?
-
作为“速度之王”的Redis,其高性能的秘密武器之一就是将数据存储在内存中。然而,内存资源是有限且昂贵的。当你的Redis实例开始告警“内存不足”,或者写入请求被阻塞时,最直接的解决方案似乎就是“加内...
- 商品详情页那么多信息,Redis的“哈希”如何优雅存储?
-
你每天网购时,无论是打开淘宝、京东还是拼多多,看到的商品详情页都琳琅满目:商品名称、价格、库存、图片、描述、评价数量、销量。这些信息加起来,多的惊人。那么问题来了:这些海量的商品信息,程序是去哪里取出...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- MySQL数据库中,数据量越来越大,有什么具体的优化方案么?
- Redis的Bitmap(位图):签到打卡、用户在线状态,用它一目了然
- 想知道有多少人看了你的文章?Redis HyperLogLog几KB就搞定!
- Redis的“HyperLogLog”:统计网站日活用户,省内存又高效的神器
- 阿里云国际站:为什么我的云服务器运行缓慢?
- Java 近期新闻:Jakarta EE 11和Spring AI更新、WildFly 36.0 Beta、Infinispan
- 腾讯云国际站:怎样设置自动伸缩应对流量高峰?
- 【案例分享】如何利用京东云建设高可用业务架构
- Spring Security在前后端分离项目中的使用
- Redis与Java集成的最佳实践
- 标签列表
-
- oracle位图索引 (63)
- oracle批量插入数据 (62)
- oracle事务隔离级别 (53)
- oracle 空为0 (50)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)