作为前端开发者,拓宽技术栈、理解后端逻辑是提升综合能力的关键一步。本文将以广泛使用的开源后台管理系统RuoYi为例,结合SpringBoot框架,从前端工程师的视角出发,拆解一个后端接口从设计到实现的完整流程,帮助前端同学快速理解并上手后端开发。
一、RuoYi 项目目录结构(前端视角解读)
了解项目结构是理解代码组织方式的第一步。若依的标准项目结构如下:
com.ruoyi
├── common // 通用工具层
│ ├── annotation // 自定义注解
│ ├── config // 全局配置
│ ├── constant // 系统常量
│ ├── core // 核心处理(如分页、基类)
│ ├── enums // 通用枚举
│ ├── exception // 异常处理
│ ├── json // JSON转换处理
│ ├── utils // 工具方法
│ └── xss // XSS 过滤
├── framework // 框架核心层
│ ├── aspectj // 注解 AOP 实现
│ ├── config // 系统配置
│ ├── datasource // 数据权限
│ ├── interceptor // 拦截器
│ ├── manager // 异步任务
│ ├── shiro/security // 权限控制
│ └── web // Web 配置(跨域等)
├── ruoyi-generator // 代码生成器
├── ruoyi-quartz // 定时任务
├── ruoyi-system // 核心业务模块(接口主要写这里)
├── ruoyi-admin // 后台服务(启动入口)
└── ruoyi-xxxxxx // 其他业务模块
对于前端开发者而言,最常接触和编写代码的模块是 ruoyi-system,它是核心业务逻辑的存放地。
二、一个接口从无到有的开发流程(前端视角)
在后端SpringBoot项目中,开发一个标准的 RESTful 接口通常遵循以下分层调用流程,这与前端的模块化思想有异曲同工之妙:
Controller (定义路由和入口)
↓ 调用
Service Interface (定义业务接口)
↓ 实现
ServiceImpl (编写具体业务逻辑)
↓ 调用
Mapper Interface (声明数据库操作方法)
↓ 映射
Mapper XML (编写实际SQL语句)
↓ 操作
数据库表
↓ 返回结果
Domain/DO (数据实体对象,用于入参和出参)
三、用前端视角重新理解后端文件类型
为了便于理解,我们可以将后端开发中的各类文件与前端熟悉的概念进行类比:
| 文件类型 |
后端职责 |
前端如何理解 |
| Controller |
暴露 API 路由,接收和响应HTTP请求 |
相当于前端的 api/user.js 路由定义文件 |
| Service 接口 |
定义业务逻辑的结构和契约 |
类似 TypeScript 中的 interface,只定义方法签名 |
| ServiceImpl |
实现 Service 接口中定义的业务逻辑 |
相当于实现上述 interface 的具体 class |
| Mapper 接口 |
声明对数据库进行操作的方法 |
可理解为“数据库操作的 TypeScript 类型声明” |
| Mapper XML |
编写具体的 SQL 语句,与 Mapper 接口方法映射 |
类似于 SQL 的模板或配置文件 |
| Domain/DO |
数据实体类,定义对象的属性结构 |
完全对应 TypeScript 中的 interface 或类型定义 |
四、精简示例代码(前端视角友好版)
下面我们通过一个查询用户列表的简单接口,来具体看每一层代码如何编写。
1️⃣ Controller(定义路由)
Controller 层负责定义 API 端点,类似你配置路由。
@RestController
@RequestMapping("/demo/user")
public class DemoUserController {
@Autowired
private IDemoUserService demoUserService;
@GetMapping("/list")
public List<DemoUser> list(DemoUser user) {
return demoUserService.selectUserList(user);
}
}
2️⃣ Service(接口)
Service 接口定义业务方法,不涉及具体实现。
public interface IDemoUserService {
List<DemoUser> selectUserList(DemoUser user);
}
3️⃣ ServiceImpl(接口实现)
ServiceImpl 是实现业务逻辑的核心层,这里可以处理各种业务规则。
@Service
public class DemoUserServiceImpl implements IDemoUserService {
@Autowired
private DemoUserMapper demoUserMapper;
@Override
public List<DemoUser> selectUserList(DemoUser user) {
// 这里可以添加业务逻辑,如权限校验、数据加工等
return demoUserMapper.selectUserList(user);
}
}
4️⃣ Mapper 接口(数据库方法声明)
Mapper 接口声明要对数据库进行哪些操作。
public interface DemoUserMapper {
List<DemoUser> selectUserList(DemoUser user);
}
5️⃣ Mapper XML(SQL)
在 Mapper XML 文件中编写具体的 SQL 语句,这是与数据库(如MySQL)交互的地方。
<!-- 通常位于 resources/mapper/system/ 目录下 -->
<mapper namespace="com.ruoyi.system.mapper.DemoUserMapper">
<select id="selectUserList" parameterType="DemoUser" resultType="DemoUser">
SELECT * FROM demo_user
<where>
<if test="nickName != null and nickName != ''">
AND nick_name like concat('%', #{nickName}, '%')
</if>
</where>
</select>
</mapper>
6️⃣ Domain(实体类)
实体类定义了数据的结构,与数据库表字段相对应。
@Data // Lombok 注解,自动生成getter/setter等方法
public class DemoUser {
private Long userId;
private String nickName;
private String email;
// ... 其他字段
}
五、总结:前端如何快速理解 RuoYi 接口开发
若依(RuoYi)基于SpringBoot的接口开发流程,本质上是将前端熟悉的模块化、接口化思想应用到了后端架构中,只是分层更细致,职责更明确。
- Controller → 前端的 API 路由管理器(如
router.js)
- Service Interface → TypeScript 中的
interface(定义契约)
- ServiceImpl → 实现
interface 的具体 class(业务逻辑主场)
- Mapper Interface → 另一层
interface,专用于声明数据操作
- Mapper XML → 分离的 SQL 脚本或查询模板
- Domain/DO → 对应 TypeScript 的
interface(定义数据结构)
掌握这种“前端思维”到“后端分层”的映射关系,你就能快速在若依这类项目中定位代码、理解流程并开始开发自己的接口,从而打通全栈开发的关键一环。