什么是RESTful API:

REST​(REpresentational State Transfer:表现层状态转换)是一种设计网络应用程序的架构风格,是一种流行的接口规范,是一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

REST并没有一个明确的标准,而更像是一种设计的风格,满足这种设计风格的程序或接口我们称之为RESTful(从单词字面来看就是一个形容词)。所以RESTful API 就是满足REST架构风格的接口。

综上,就是REST与RESTful的联系与区别

REST架构特征:

RESTful是一种风格而不是标准,这个风格有以下几个特征:

1. ​客户端-服务器分离(Client-Server Architecture)​​

  • 特征​:客户端负责用户界面和交互逻辑,服务器负责数据处理和存储,两者独立演化。

  • 意义​:解耦前端和后端,支持不同团队分工协作,提升可扩展性。

  • 例子​:浏览器(客户端)请求服务器 API 获取数据,渲染页面。

2. ​无状态(Stateless)​​

  • 特征​:每个客户端请求必须包含服务器处理该请求所需的所有信息,服务器不保存客户端状态。

  • 意义​:简化服务器设计,提高可伸缩性(无需维护会话状态)。

  • 例子​:

    • ✅ 正确:客户端在请求头中携带 Token(如 Authorization: Bearer xxx)标识身份。

    • ❌ 错误:服务器依赖 Session ID 维护登录状态。

3. ​可缓存(Cacheable)​​

  • 特征​:服务器需明确告知客户端哪些响应可以缓存,客户端或中间层(如 CDN)可缓存响应。

  • 意义​:减少重复请求,提升性能。

  • 实现方式​:

    • HTTP 头部字段:Cache-Control: max-age=3600(缓存 1 小时)。

    • 状态码:304 Not Modified(资源未变化,使用本地缓存)。

4. ​统一接口(Uniform Interface)​​

  • 特征​:客户端与服务器的交互方式标准化,包括:

    • 资源标识​:通过 URI(如 /users/123)唯一标识资源。

    • 资源操作​:通过 HTTP 方法(GET、POST、PUT、DELETE)定义操作。

    • 自描述消息​:消息(请求/响应)包含足够信息供接收方处理(如 Content-Type: application/json)。

    • HATEOAS​(可选):响应中提供资源相关的链接(如 "links": { "self": "/users/123" }),客户端通过链接导航。

  • 意义​:降低系统耦合度,提升通用性。

5. ​分层系统(Layered System)​​

  • 特征​:系统可分层构建(如负载均衡、缓存层、安全层),客户端无需关心底层结构。

  • 意义​:增强可扩展性和安全性。

  • 例子​:

    • 客户端请求 → 负载均衡器 → 缓存层 → 应用服务器 → 数据库。

6. ​按需代码(Code-On-Demand,可选)​​

  • 特征​:服务器可向客户端发送可执行代码(如 JavaScript),动态扩展客户端功能。

  • 意义​:灵活性高,但非强制要求。

  • 例子​:网页中嵌入 JavaScript 脚本,由浏览器执行。


REST 架构的衍生特征

除了六大核心约束,REST 架构在实践中还表现出以下特征:

1. ​资源为中心(Resource-Oriented)​​

  • 一切数据抽象为资源(如用户、订单),通过 URI 唯一标识。

  • 例子​:/products/456 表示 ID 为 456 的商品。

2. ​使用标准 HTTP 方法​

  • 通过 HTTP 方法(GET、POST、PUT、DELETE 等)表达操作意图,而非在 URI 中使用动词。

    • ✅ 正确:DELETE /users/123(删除用户)。

    • ❌ 错误:GET /deleteUser?id=123

3. ​无会话(Sessionless)​​

  • 服务器不维护客户端状态,每次请求独立处理。

  • 实现方式​:客户端通过 Token、API Key 等机制传递身份信息。

4. ​支持多种数据格式​

  • 数据格式不限定(如 JSON、XML),但需在请求头中声明(如 Accept: application/json)。

补充:

使用 ​Spring Boot 或 Spring MVC​ 框架本身不意味着自动符合 RESTful 规范。RESTful 是一种架构风格,而 Spring MVC 是技术实现工具。关键区别在于如何设计接口,而不仅仅是技术选型。

  • Spring MVC 可以构建 RESTful 接口,但也能构建非 RESTful 的传统 MVC 接口(如返回 HTML 页面)。

  • ​是否符合 RESTful 取决于接口设计,而非框架本身。

反例:

@Controller // 注意是 @Controller,不是 @RestController
public class UserController {
    @GetMapping("/users")
    public String listUsers(Model model) {
        model.addAttribute("users", userService.findAll());
        return "users.html"; // 返回 HTML 视图
    }
}

返回 HTML 页面,而非资源的表现层(如 JSON),属于传统 MVC 模式。

@RestController
public class BadController {
    // ❌ 路径包含动词,且使用 GET 方法修改资源
    @GetMapping("/createUser")
    public User createUser(@RequestParam String name) {
        return userService.save(name);
    }
}
  • URI 包含动词 createUser(应改为 /users + POST 方法)。

  • GET 方法用于修改资源(违反 HTTP 语义)。

正例:

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

    // 获取所有用户(GET 方法 + 资源路径)
    @GetMapping
    public List<User> getAllUsers() {
        return userService.findAll();
    }

    // 创建用户(POST 方法 + 资源路径)
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public User createUser(@RequestBody User user) {
        return userService.save(user);
    }

    // 获取单个用户(GET 方法 + 资源 ID)
    @GetMapping("/{id}")
    public User getUserById(@PathVariable Long id) {
        return userService.findById(id);
    }

    // 更新用户(PUT 方法 + 资源 ID)
    @PutMapping("/{id}")
    public User updateUser(@PathVariable Long id, @RequestBody User user) {
        return userService.update(id, user);
    }

    // 删除用户(DELETE 方法 + 资源 ID)
    @DeleteMapping("/{id}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void deleteUser(@PathVariable Long id) {
        userService.delete(id);
    }
}

符合 RESTful 的关键点:

  • ✅ URI 使用名词 /users,而非动词。

  • ✅ 正确使用 HTTP 方法(GET/POST/PUT/DELETE)。

  • ✅ 返回 JSON 数据(资源的表现层)。

  • ✅ 无状态(不依赖 Session 等服务器状态)。

Tip:前后端分离是一种架构模式(前端和后端独立开发部署),而 ​RESTful​ 是一种接口设计风格(关注资源、HTTP 方法、状态码)。二者可以自由组合,没有必然绑定。​Thymeleaf​ 是服务端渲染技术(适合简单页面或 SEO),但后端依然可以同时提供 ​RESTful API​(供其他客户端调用)。