【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 开发方式互补,可根据实际需求灵活选择。


目录
相关文章
|
5天前
|
存储 JavaScript 前端开发
JavaScript基础
本节讲解JavaScript基础核心知识:涵盖值类型与引用类型区别、typeof检测类型及局限性、===与==差异及应用场景、内置函数与对象、原型链五规则、属性查找机制、instanceof原理,以及this指向和箭头函数中this的绑定时机。重点突出类型判断、原型继承与this机制,助力深入理解JS面向对象机制。(238字)
|
3天前
|
云安全 人工智能 安全
阿里云2026云上安全健康体检正式开启
新年启程,来为云上环境做一次“深度体检”
1566 6
|
5天前
|
安全 数据可视化 网络安全
安全无小事|阿里云先知众测,为企业筑牢防线
专为企业打造的漏洞信息收集平台
1322 2
|
5天前
|
缓存 算法 关系型数据库
深入浅出分布式 ID 生成方案:从原理到业界主流实现
本文深入探讨分布式ID的生成原理与主流解决方案,解析百度UidGenerator、滴滴TinyID及美团Leaf的核心设计,涵盖Snowflake算法、号段模式与双Buffer优化,助你掌握高并发下全局唯一ID的实现精髓。
342 160
|
5天前
|
人工智能 自然语言处理 API
n8n:流程自动化、智能化利器
流程自动化助你在重复的业务流程中节省时间,可通过自然语言直接创建工作流啦。
404 6
n8n:流程自动化、智能化利器
|
7天前
|
人工智能 API 开发工具
Skills比MCP更重要?更省钱的多!Python大佬这观点老金测了一周终于懂了
加我进AI学习群,公众号右下角“联系方式”。文末有老金开源知识库·全免费。本文详解Claude Skills为何比MCP更轻量高效:极简配置、按需加载、省90% token,适合多数场景。MCP仍适用于复杂集成,但日常任务首选Skills。推荐先用SKILL.md解决,再考虑协议。附实测对比与配置建议,助你提升效率,节省精力。关注老金,一起玩转AI工具。
|
14天前
|
机器学习/深度学习 安全 API
MAI-UI 开源:通用 GUI 智能体基座登顶 SOTA!
MAI-UI是通义实验室推出的全尺寸GUI智能体基座模型,原生集成用户交互、MCP工具调用与端云协同能力。支持跨App操作、模糊语义理解与主动提问澄清,通过大规模在线强化学习实现复杂任务自动化,在出行、办公等高频场景中表现卓越,已登顶ScreenSpot-Pro、MobileWorld等多项SOTA评测。
1535 7
|
4天前
|
Linux 数据库
Linux 环境 Polardb-X 数据库 单机版 rpm 包 安装教程
本文介绍在CentOS 7.9环境下安装PolarDB-X单机版数据库的完整流程,涵盖系统环境准备、本地Yum源配置、RPM包安装、用户与目录初始化、依赖库解决、数据库启动及客户端连接等步骤,助您快速部署运行PolarDB-X。
246 1
Linux 环境 Polardb-X 数据库 单机版 rpm 包 安装教程
|
8天前
|
人工智能 前端开发 API
Google发布50页AI Agent白皮书,老金帮你提炼10个核心要点
老金分享Google最新AI Agent指南:让AI从“动嘴”到“动手”。Agent=大脑(模型)+手(工具)+协调系统,可自主完成任务。通过ReAct模式、多Agent协作与RAG等技术,实现真正自动化。入门推荐LangChain,文末附开源知识库链接。
668 119