【RuoYi-SpringBoot3-Pro】:Magic API 低代码开发

简介: RuoYi-SpringBoot3-Pro 集成 Magic API,实现低代码快速开发。通过 Web 界面编写脚本,无需编写 Controller、Service 等代码,支持实时生效、数据库操作、多数据源、权限校验与 Redis 缓存,助力高效构建 RESTful 接口,适用于原型开发、报表查询等场景。

【RuoYi-SpringBoot3-Pro】:Magic API 低代码开发

本文详细介绍 RuoYi-SpringBoot3-Pro 框架中集成的 Magic API 低代码开发平台,帮助开发者快速构建 REST API 接口。

一、什么是 Magic API?

Magic API 是一个基于 Java 的接口快速开发框架,通过 Web 界面编写脚本即可完成接口开发,无需定义 Controller、Service、Mapper 等传统分层代码。

1.1 核心优势

特性 说明
可视化开发 通过 Web 界面编写接口,所见即所得
即时生效 接口修改后无需重启,立即生效
脚本语言 基于 Java 语法的脚本语言,学习成本低
数据库操作 内置强大的数据库操作 API
多数据源 支持动态切换多个数据源
参数校验 内置参数校验功能
接口文档 自动生成接口文档
版本控制 支持接口历史记录和回滚

1.2 适用场景

  • 快速原型开发
  • 简单 CRUD 接口
  • 数据查询报表
  • 临时接口需求
  • 低代码平台集成

二、项目集成

2.1 Maven 依赖

RuoYi-SpringBoot3-Pro 已集成 Magic API 2.2.2 版本:

<!-- Magic API 核心依赖 -->
<dependency>
    <groupId>org.ssssssss</groupId>
    <artifactId>magic-api-spring-boot-starter</artifactId>
    <version>2.2.2</version>
</dependency>

<!-- Magic API Redis 插件 -->
<dependency>
    <groupId>org.ssssssss</groupId>
    <artifactId>magic-api-plugin-redis</artifactId>
    <version>2.2.2</version>
</dependency>

2.2 配置文件

application.yml 中配置 Magic API:

# Magic API 配置
# 官方文档:https://www.ssssssss.org/magic-api/pages/config/spring-boot/
magic-api:
  # Web 编辑器访问路径(生产环境建议设为 null 禁用)
  web: /magic/web

  # 编辑器配置文件
  editor-config: classpath:./magic-editor-config.js

  # 接口存储方式
  resource:
    type: database           # 存储类型:database(数据库)/ file(文件)
    tableName: magic_api_file  # 存储表名

  # 接口访问前缀
  prefix: /magic/api

  # 编辑器登录认证
  security:
    username: jyx            # 登录用户名
    password: jyx_692483     # 登录密码

  # 历史记录备份
  backup:
    enable: true             # 是否启用备份
    max-history: -1          # 最大历史记录数(-1 表示不限制)
    table-name: magic_backup_record  # 备份表名

  # 响应结果格式
  response: |- 
    {
   
      code: code,
      msg: message,
      data,
    }

2.3 编辑器主题配置

magic-editor-config.js 文件配置编辑器主题:

var MAGIC_EDITOR_CONFIG = {
   
    theme: 'dark',  // 主题:dark(暗色)/ light(亮色)
}

2.4 安全配置

Magic API 接口默认放行,在 SecurityConfig.java 中配置:

@Bean
public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
   
    httpSecurity
        .authorizeHttpRequests(auth -> auth
            // Magic API 接口放行
            .requestMatchers("/magic/**").permitAll()
            .anyRequest().authenticated()
        );
    return httpSecurity.build();
}

三、访问编辑器

3.1 访问地址

启动项目后,访问 Magic API 编辑器:

http://localhost:8087/magic/web

3.2 登录认证

使用配置文件中设置的账号密码登录:

  • 用户名:jyx
  • 密码:jyx_692483

3.3 编辑器界面

┌─────────────────────────────────────────────────────────────┐
│  Magic API Editor                                    [用户] │
├─────────────┬───────────────────────────────────────────────┤
│             │                                               │
│  接口列表    │              脚本编辑区                        │
│             │                                               │
│  📁 分组1    │  // 编写接口脚本                              │
│    └─ 接口1  │  var list = db.select("""                    │
│    └─ 接口2  │      SELECT * FROM sys_user                  │
│  📁 分组2    │  """)                                        │
│    └─ 接口3  │  return list                                 │
│             │                                               │
├─────────────┼───────────────────────────────────────────────┤
│  接口配置    │              执行结果                          │
│  请求方式    │  [                                            │
│  请求路径    │    {"userId": 1, "userName": "admin"},       │
│  请求参数    │    {"userId": 2, "userName": "test"}         │
│             │  ]                                            │
└─────────────┴───────────────────────────────────────────────┘

四、接口开发

4.1 创建第一个接口

  1. 点击左侧「+」创建分组
  2. 在分组下创建接口
  3. 配置请求方式和路径
  4. 编写脚本代码
  5. 点击「执行」测试
  6. 点击「保存」发布

4.2 基础语法

Magic API 使用类 Java 语法的脚本语言:

// 变量定义
var name = "张三"
var age = 18

// 条件判断
if (age >= 18) {
   
    return "成年人"
} else {
   
    return "未成年人"
}

// 循环
var list = [1, 2, 3, 4, 5]
for (item in list) {
   
    print(item)
}

// 函数定义
var add = (a, b) => a + b
return add(1, 2)

4.3 获取请求参数

// 获取 Query 参数:/api/user?name=张三&age=18
var name = name        // 直接使用参数名
var age = age

// 获取 Path 参数:/api/user/{id}
var userId = path.id

// 获取 Body 参数(JSON)
var user = body
var userName = body.userName

// 获取 Header
var token = header.Authorization

// 获取完整请求对象
var request = request

4.4 数据库操作

Magic API 内置强大的数据库操作 API:

// 查询列表
var list = db.select("""
    SELECT * FROM sys_user WHERE status = '0'
""")

// 查询单条
var user = db.selectOne("""
    SELECT * FROM sys_user WHERE user_id = #{
   userId}
""")

// 带参数查询
var users = db.select("""
    SELECT * FROM sys_user 
    WHERE dept_id = #{
   deptId} 
    AND user_name LIKE CONCAT('%', #{
   keyword}, '%')
""")

// 分页查询
var page = db.page("""
    SELECT * FROM sys_user WHERE status = '0'
""")

// 插入数据
var result = db.insert("""
    INSERT INTO sys_user (user_name, nick_name, email) 
    VALUES (#{
   userName}, #{
   nickName}, #{
   email})
""")

// 更新数据
var result = db.update("""
    UPDATE sys_user SET nick_name = #{
   nickName} WHERE user_id = #{
   userId}
""")

// 删除数据
var result = db.delete("""
    DELETE FROM sys_user WHERE user_id = #{
   userId}
""")

4.5 链式查询

// 使用链式 API 构建查询
var list = db.table('sys_user')
    .where()
    .eq('status', '0')
    .like('user_name', keyword)
    .orderBy('create_time desc')
    .page(pageNum, pageSize)
    .select()

// 插入
db.table('sys_user').insert({
   
    userName: '张三',
    nickName: '小张',
    email: 'zhangsan@example.com'
})

// 更新
db.table('sys_user')
    .where()
    .eq('user_id', 1)
    .update({
   
        nickName: '新昵称'
    })

// 删除
db.table('sys_user')
    .where()
    .eq('user_id', 1)
    .delete()

4.6 多数据源

// 切换数据源
var list = db.slave.select("""
    SELECT * FROM other_table
""")

// 或使用 datasource 指定
var list = db.datasource('slave').select("""
    SELECT * FROM other_table
""")

五、接口鉴权

5.1 鉴权拦截器

RuoYi-SpringBoot3-Pro 实现了 Magic API 的请求拦截器,支持登录验证和权限校验:

@Component
public class MagicApiRequestInterceptor implements RequestInterceptor {
   

    @Override
    public Object preHandle(ApiInfo info, MagicScriptContext context, 
            MagicHttpServletRequest request, MagicHttpServletResponse response) {
   

        // 获取接口配置的选项
        boolean needLogin = StringUtils.equals("true", info.getOptionValue(Options.REQUIRE_LOGIN));
        String role = info.getOptionValue(Options.ROLE);
        String permission = info.getOptionValue(Options.PERMISSION);

        // 需要角色或权限时,自动要求登录
        if (StringUtils.isNotBlank(role) || StringUtils.isNotBlank(permission)) {
   
            needLogin = true;
        }

        // 登录校验
        if (needLogin) {
   
            try {
   
                SecurityUtils.getLoginUser();
            } catch (Exception e) {
   
                return new JsonBean<>(401, "用户未登录");
            }
        }

        // 角色校验
        if (StringUtils.isNotBlank(role)) {
   
            if (!SecurityUtils.hasRole(role)) {
   
                return new JsonBean<>(403, "用户权限不足");
            }
        }

        // 权限校验
        if (StringUtils.isNotBlank(permission)) {
   
            if (!SecurityUtils.hasPermi(permission)) {
   
                return new JsonBean<>(403, "用户权限不足");
            }
        }

        return null;  // 返回 null 表示放行
    }
}

5.2 配置接口权限

在 Magic API 编辑器中,为接口配置权限选项:

选项 说明 示例值
require_login 是否需要登录 true / false
role 需要的角色 admin
permission 需要的权限 system:user:list

配置方式:

  1. 在编辑器中选择接口
  2. 点击「选项」标签
  3. 添加对应的选项配置

5.3 获取当前用户

在脚本中获取当前登录用户信息:

import com.ruoyi.common.utils.SecurityUtils

// 获取当前用户 ID
var userId = SecurityUtils.getUserId()

// 获取当前用户名
var username = SecurityUtils.getUsername()

// 获取当前用户信息
var loginUser = SecurityUtils.getLoginUser()
var user = loginUser.getUser()

六、Redis 缓存

6.1 基础操作

Magic API 集成了 Redis 插件,可直接使用:

// 设置缓存
redis.set('key', 'value')

// 设置缓存(带过期时间,单位秒)
redis.set('key', 'value', 3600)

// 获取缓存
var value = redis.get('key')

// 删除缓存
redis.del('key')

// 判断是否存在
var exists = redis.exists('key')

// 设置过期时间
redis.expire('key', 3600)

6.2 接口缓存示例

// 先从缓存获取
var cacheKey = 'user:list:' + deptId
var list = redis.get(cacheKey)

if (list == null) {
   
    // 缓存不存在,查询数据库
    list = db.select("""
        SELECT * FROM sys_user WHERE dept_id = #{
   deptId}
    """)
    // 存入缓存,1小时过期
    redis.set(cacheKey, list, 3600)
}

return list

6.3 Hash 操作

// 设置 Hash 字段
redis.hset('user:1', 'name', '张三')
redis.hset('user:1', 'age', 18)

// 获取 Hash 字段
var name = redis.hget('user:1', 'name')

// 获取所有字段
var user = redis.hgetAll('user:1')

// 删除 Hash 字段
redis.hdel('user:1', 'name')

七、高级特性

7.1 事务支持

import db

// 开启事务
db.transaction(() => {
   
    db.update("""
        UPDATE account SET balance = balance - 100 WHERE user_id = 1
    """)
    db.update("""
        UPDATE account SET balance = balance + 100 WHERE user_id = 2
    """)
})

7.2 异步执行

import async

// 异步执行
async.run(() => {
   
    // 耗时操作
    db.insert("""
        INSERT INTO log (content) VALUES ('异步日志')
    """)
})

return "请求已接收"

7.3 HTTP 请求

import http

// GET 请求
var result = http.get('https://api.example.com/users')

// POST 请求
var result = http.post('https://api.example.com/users', {
   
    body: {
   
        name: '张三',
        age: 18
    }
})

// 带 Header 的请求
var result = http.get('https://api.example.com/users', {
   
    headers: {
   
        'Authorization': 'Bearer token'
    }
})

7.4 参数校验

import assert

// 非空校验
assert.notNull(userId, '用户ID不能为空')
assert.notBlank(userName, '用户名不能为空')

// 条件校验
assert.isTrue(age >= 18, '年龄必须大于等于18')

// 正则校验
assert.regx(email, '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$', '邮箱格式不正确')

7.5 日志输出

import log

log.info('这是一条信息日志')
log.warn('这是一条警告日志')
log.error('这是一条错误日志')
log.debug('这是一条调试日志')

八、实战示例

8.1 用户列表接口

/**
 * 接口路径:GET /magic/api/user/list
 * 请求参数:pageNum, pageSize, userName, status
 */

// 参数处理
var pageNum = pageNum ?: 1
var pageSize = pageSize ?: 10

// 构建查询
var query = db.table('sys_user')
    .where()
    .eq('del_flag', '0')

// 动态条件
if (userName) {
   
    query.like('user_name', userName)
}
if (status) {
   
    query.eq('status', status)
}

// 分页查询
var page = query.orderBy('create_time desc')
    .page(pageNum, pageSize)
    .select()

return page

8.2 用户详情接口

/**
 * 接口路径:GET /magic/api/user/{id}
 * 路径参数:id
 */

import assert

// 参数校验
assert.notNull(path.id, '用户ID不能为空')

// 查询用户
var user = db.selectOne("""
    SELECT u.*, d.dept_name 
    FROM sys_user u
    LEFT JOIN sys_dept d ON u.dept_id = d.dept_id
    WHERE u.user_id = #{
   path.id} AND u.del_flag = '0'
""")

if (user == null) {
   
    return {
   
        code: 404,
        msg: '用户不存在'
    }
}

return user

8.3 新增用户接口

/**
 * 接口路径:POST /magic/api/user
 * 请求体:userName, nickName, email, phonenumber, deptId
 */

import assert
import com.ruoyi.common.utils.SecurityUtils

// 参数校验
assert.notBlank(body.userName, '用户名不能为空')
assert.notBlank(body.nickName, '昵称不能为空')

// 检查用户名是否存在
var exists = db.selectOne("""
    SELECT 1 FROM sys_user WHERE user_name = #{
   body.userName} AND del_flag = '0'
""")
if (exists) {
   
    return {
   
        code: 500,
        msg: '用户名已存在'
    }
}

// 插入用户
var result = db.insert("""
    INSERT INTO sys_user (user_name, nick_name, email, phonenumber, dept_id, 
        password, create_by, create_time)
    VALUES (#{
   body.userName}, #{
   body.nickName}, #{
   body.email}, #{
   body.phonenumber}, 
        #{
   body.deptId}, #{
   SecurityUtils.encryptPassword('123456')}, 
        #{
   SecurityUtils.getUsername()}, NOW())
""")

return {
   
    code: 200,
    msg: '新增成功'
}

8.4 统计报表接口

/**
 * 接口路径:GET /magic/api/report/user-stats
 * 请求参数:startDate, endDate
 */

// 用户统计
var stats = db.selectOne("""
    SELECT 
        COUNT(*) as totalCount,
        SUM(CASE WHEN status = '0' THEN 1 ELSE 0 END) as activeCount,
        SUM(CASE WHEN status = '1' THEN 1 ELSE 0 END) as disabledCount
    FROM sys_user 
    WHERE del_flag = '0'
""")

// 部门分布
var deptStats = db.select("""
    SELECT d.dept_name, COUNT(u.user_id) as userCount
    FROM sys_dept d
    LEFT JOIN sys_user u ON d.dept_id = u.dept_id AND u.del_flag = '0'
    WHERE d.del_flag = '0'
    GROUP BY d.dept_id, d.dept_name
    ORDER BY userCount DESC
    LIMIT 10
""")

// 注册趋势
var trend = db.select("""
    SELECT DATE(create_time) as date, COUNT(*) as count
    FROM sys_user
    WHERE del_flag = '0'
    AND create_time BETWEEN #{
   startDate} AND #{
   endDate}
    GROUP BY DATE(create_time)
    ORDER BY date
""")

return {
   
    stats: stats,
    deptStats: deptStats,
    trend: trend
}

九、生产环境配置

9.1 禁用编辑器

生产环境建议禁用 Web 编辑器:

magic-api:
  web: null  # 设为 null 禁用编辑器

9.2 修改默认密码

magic-api:
  security:
    username: your_username
    password: your_strong_password

9.3 接口访问控制

通过 Spring Security 控制 Magic API 接口访问:

.requestMatchers("/magic/api/**").authenticated()  // 需要登录
.requestMatchers("/magic/web/**").hasRole("ADMIN") // 仅管理员

十、常见问题

10.1 接口不生效

  • 检查是否点击「保存」按钮
  • 检查接口路径是否正确
  • 查看控制台是否有错误日志

10.2 数据库连接失败

  • 检查数据源配置是否正确
  • 确认数据库服务是否启动
  • 查看连接池配置

10.3 权限校验失败

  • 确认接口配置了正确的权限选项
  • 检查请求是否携带有效的 Token
  • 验证用户是否拥有对应权限

十一、总结

RuoYi-SpringBoot3-Pro 集成的 Magic API 具有以下特点:

  • 开箱即用:预配置完善,启动即可使用
  • 可视化开发:Web 界面编写接口,所见即所得
  • 即时生效:无需重启,修改立即生效
  • 数据库持久化:接口存储在数据库,支持版本控制
  • 权限集成:与 RuoYi 权限体系无缝集成
  • Redis 支持:内置 Redis 插件,轻松实现缓存

Magic API 适合快速开发简单接口,与传统 Controller 开发方式互补,可根据实际需求灵活选择。


目录
相关文章
|
3月前
|
存储 消息中间件 Kafka
Confluent 首席架构师万字剖析 Apache Fluss(一):核心概念
Apache Fluss是由阿里巴巴与Ververica合作开发的Flink表存储引擎,旨在提供低延迟、高效率的实时数据存储与变更日志支持。其采用TabletServer与CoordinatorServer架构,结合RocksDB和列式存储,实现主键表与日志表的统一管理,并通过客户端抽象整合湖仓历史数据,弥补Paimon在实时场景下的性能短板。
585 22
Confluent 首席架构师万字剖析 Apache Fluss(一):核心概念
|
4天前
|
安全 Java Maven
【RuoYi-SpringBoot3-Pro】:ClassFinal 代码加密
本文介绍RuoYi-SpringBoot3-Pro如何集成ClassFinal实现Java代码加密,保护核心业务逻辑。通过Maven插件对class文件与配置文件进行AES加密,防止反编译泄露,支持选择性加密、密码验证与机器码绑定,适用于商业交付、私有化部署等场景,保障知识产权安全。
84 5
|
1天前
|
机器学习/深度学习 人工智能 自然语言处理
构建AI智能体:九十一、大模型三大适应技术详解:有监督微调、提示学习与语境学习
大模型应用并非高不可攀,有监督微调、提示学习与语境学习提供了低门槛落地路径。提示学习通过指令引导模型,零成本快速试用;语境学习借助示例让模型“即学即用”;有监督微调则通过数据训练打造专业模型,实现性能突破。三者层层递进,助力高效构建AI应用。
64 14
|
5月前
|
存储 分布式计算 Apache
湖仓一体:小米集团基于 Apache Doris + Apache Paimon 实现 6 倍性能飞跃
小米通过将 Apache Doris(数据库)与 Apache Paimon(数据湖)深度融合,不仅解决了数据湖分析的性能瓶颈,更实现了 “1+1>2” 的协同效应。在这些实践下,小米在湖仓数据分析场景下获得了可观的业务收益。
1018 9
湖仓一体:小米集团基于 Apache Doris + Apache Paimon 实现 6 倍性能飞跃
|
5月前
|
Java 测试技术 API
2025 年 Java 开发者必知的最新技术实操指南全览
本指南涵盖Java 21+核心实操,详解虚拟线程、Spring Boot 3.3+GraalVM、Jakarta EE 10+MicroProfile 6微服务开发,并提供现代Java开发最佳实践,助力开发者高效构建高性能应用。
841 4
|
11月前
|
前端开发 JavaScript Java
Java打包jar运行时分离lib和jar
在`pom.xml`的`build`节点中,设置`packaging`为`jar`,并配置插件分离依赖库到`lib`目录和资源文件到`resources`目录。这样可以在运行时通过`-Dloader.path=lib,resources`加载外部依赖和资源文件,便于独立升级依赖库和修改资源文件,而无需重新打包程序。具体插件包括`maven-dependency-plugin`、`maven-resources-plugin`和`spring-boot-maven-plugin`等。
675 1
|
存储 缓存 Linux
Linux VFS机制详解
Linux VFS机制详解
1283 1
|
SQL 自然语言处理 数据库
XiYan-SQL:一种多生成器集成的Text-to-SQL框架
XiYan-SQL 是一种创新的多生成器集成Text-to-SQL框架,通过M-Schema增强模型对数据库结构的理解,结合ICL与SFT方法提升SQL生成质量和多样性,经实验证明在多个数据集上表现优异,特别是在Spider和SQL-Eval上取得了领先成绩。
2335 7