`api`、`common`、`service`、`web` 分层架构设计

451 阅读3分钟

分层架构设计apicommonserviceweb 是现代 Java 项目(尤其是基于 Spring Boot)中最常见的模块划分。

1、整体架构图(典型 Maven 多模块项目)

project-root
├── common          ← 公共模块
├── service         ← 业务逻辑模块
├── api             ← 对外 API 模块
└── web             ← Web 接口层(或 UI 层)

这是一种 “分层 + 模块化” 的设计,常见于微服务或大型单体应用。

2、各模块职责

2.1. common 模块(公共模块)

  • 存放跨模块共享的代码,避免重复,被其他所有模块依赖。

  • 包含内容:

    • 工具类:DateUtilsStringUtilsJsonUtils
    • 公共异常:BusinessExceptionGlobalException
    • 统一返回格式:ResponseResult<T>ErrorCode
    • 常量类:ConstantsStatusEnum
    • 基础配置:BaseConfigRedisTemplate 配置
    • 分页封装:PageResult<T>

示例:

// 统一响应格式
public class ResponseResult<T> {
    private int code;
    private String message;
    private T data;
    // getter/setter
}

2.2 service 模块(业务逻辑层)

  • 实现核心业务逻辑,依赖:common + mapper(或 repository)。

  • 包含内容:

    • Service 接口和实现类:UserServiceOrderService
    • 业务逻辑:事务控制、流程编排、规则判断
    • 调用 common 模块的工具和异常
    • 调用 dao / mapper(数据访问层,有时独立为 repository 模块)

示例:

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public User findById(Long id) {
        return userMapper.selectById(id);
    }

    @Transactional
    public void transferMoney(Long from, Long to, BigDecimal amount) {
        
    }
}

2.3. api 模块(接口定义层)

  • 对外暴露的服务接口(通常是接口类,不含实现),用于模块间解耦RPC 调用,依赖:common,被 web 和其他服务模块依赖。
  • 包含内容:
    • 接口定义:UserServiceApiOrderServiceApi
    • DTO(数据传输对象):UserDTOOrderDTO
    • RPC 调用参数和返回值

示例:

// 定义一个远程可调用的接口
public interface UserServiceApi {
    ResponseResult<UserDTO> getUserById(Long id);
    ResponseResult<List<UserDTO>> listUsers(PageQuery query);
}

使用场景:

  • 微服务之间通过 Dubbo、gRPC 调用
  • web 模块依赖 api,面向接口编程
  • 前后端分离时,api 模块也可生成 OpenAPI 文档

2.4. web 模块(Web 接口层)

  • 处理 HTTP 请求,接收参数、调用 serviceapi,返回 JSON,依赖:api + common, 对外暴露 HTTP 接口。
  • 包含内容:
    • Controller:UserControllerOrderController
    • 接收 @RequestParam@RequestBody
    • 参数校验(@Valid
    • 调用 service 或 api 客户端
    • 返回 ResponseResult<T>

示例:

@RestController
@RequestMapping("/api/user")
public class UserController {

    @Autowired
    private UserService userService; // 或 UserServiceApi

    @GetMapping("/{id}")
    public ResponseResult<UserDTO> getUser(@PathVariable Long id) {
        User user = userService.findById(id);
        return ResponseResult.success(UserConverter.toDTO(user));
    }
}

3、依赖原则

web → api → common
     ↘
service → common
  • web 依赖 api 和 common
  • service 依赖 common
  • api 依赖 common
  • common 不依赖任何模块(否则会循环依赖!)

原则

依赖只能向“上”或“同级”,不能“向下”
common 是最底层,web 是最上层。

4、父pom文件(Maven 多模块)

<!-- 父 pom.xml -->
<modules>
    <module>common</module>
    <module>service</module>
    <module>api</module>
    <module>web</module>
</modules>

每个模块都是一个独立的 Maven 项目:

  • common/pom.xml
  • service/pom.xml
  • api/pom.xml
  • web/pom.xml

5、设计优势

优势说明
解耦清晰各层职责分明,便于维护
复用性强common 被所有模块共享
便于测试可独立测试 service 逻辑
支持微服务api 模块可用于服务间调用
团队协作不同团队负责不同模块

6、常见错误

错误正确做法
common 依赖 service❌ common 不能依赖任何业务模块
web 直接访问 mapper❌ 应通过 service 或 api
service 返回 ResponseResult❌ service 只返回业务对象,web 层封装响应
api 包含实现类❌ api 只定义接口,不写实现

7、变体设计(根据项目规模调整)

项目规模推荐结构
小型项目单模块:controllerservicecommon 在同一个项目
中型项目四模块:commonserviceapiweb
大型微服务每个服务独立部署,api 模块单独发布为 SDK

总结

模块职责依赖谁被谁依赖
common工具、异常、常量所有模块
service业务逻辑commonweb、其他服务
api接口定义(RPC/远程调用)commonweb、其他服务
webHTTP 接口(Controller)api + common客户端(前端、App)