RESTful API 设计规范
REST(Representational State Transfer)是一种软件架构风格,用于设计可扩展的网络应用程序。RESTful API 根据 REST 原则构建,旨在利用现有的网络协议(特别是 HTTP)来创建高效、可扩展和易于维护的接口。RESTful API 包含一些关键设计规范和最佳实践:
1. 资源导向
所有的实体(如用户、订单、产品)都被视为资源,每个资源通过唯一的 URI(统一资源标识符)进行标识
plain
https://api.example.com/users
https://api.example.com/orders/{id}
https://api.example.com/products/{id}
在RESTful架构中,每个网址代表一种资源(resource),所以网址中不能有动词。一般来说,数据库中的表都是同种记录的"集合"(collection),所以 API 中的名词也应该使用复数。
2. 使用标准的 HTTP 方法
- GET:检索资源。例如,
GET /users
获取用户列表,GET /users/{id}
获取特定用户。 - POST:创建新资源。例如,
POST /users
创建新用户。 - PUT:更新资源的全部内容。例如,
PUT /users/{id}
更新特定用户的所有信息。 - PATCH:部分更新资源。例如,
PATCH /users/{id}
部分更新用户信息。 - DELETE:删除资源。例如,
DELETE /users/{id}
删除特定用户。
3. 版本控制
通过 URI 版本号或其他方式管理 API 的版本,确保向后兼容。例如:
/v1/users
/api/v2/orders
4. 分页、过滤和排序
对于返回大量数据的 API,提供分页、过滤和排序功能,以提高性能和用户体验。例如:
ini
GET /users?page=2&size=20&sort=name,asc
GET /products?category=electronics&price_lt=500
5. 返回结果
针对不同操作,服务器向用户返回的结果应该符合以下规范。
plain
GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
PATCH /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档
Spring MVC
Spring MVC 是 Spring 框架中的一个模块,专门用于构建 Web 应用程序,借助 Spring MVC,开发者可以方便地创建 RESTful 风格的 Web 服务
控制器
在 RESTful 服务中,控制器负责处理 HTTP 请求,并返回资源表示。Spring MVC 提供了多个注解来简化这一过程
- @RestController:表示控制器中的所有方法默认返回 JSON 或 XML 数据,而不是视图
- @RequestMapping:将特定的 HTTP 请求路径和方法与控制器的方法关联起来,实现资源的操作。为了简化常用的HTTP方法映射,Spring MVC提供了一系列快捷注解,如 @GetMapping、@PostMapping 等
java
@RestController
@RequestMapping("/api/users")
public class UserController {
// 继承类级别的基础路径 /api/users
@GetMapping
public List<User> getAllUsers() {
// 获取所有用户
}
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
// 根据 ID 获取用户
}
@PostMapping
public User createUser(@RequestBody User user) {
// 创建新用户
}
@PutMapping("/{id}")
public User updateUser(@PathVariable Long id, @RequestBody User user) {
// 更新用户信息
}
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable Long id) {
// 删除用户
}
}
请求与响应
- @RequestBody:将HTTP请求体中的JSON或XML数据绑定到方法参数中。
- @PathVariable:从URL路径中提取变量。
- @RequestParam:从查询参数(query)中提取变量。
- @ResponseStatus:用于为方法或异常类设置HTTP响应状态码
java
@PutMapping("/users/{id}")
@ResponseStatus(HttpStatus.CREATED)
public User updateUser(@PathVariable Long id, @RequestBody User user) {
// 方法实现
}
简单 demo
java
@RestController
@RequestMapping("/api/users")
public class UserController {
private final Map<Long, User> userRepository = new ConcurrentHashMap<>();
@GetMapping
public Collection<User> getAllUsers() {
return userRepository.values();
}
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
User user = userRepository.get(id);
if (user != null) {
return ResponseEntity.ok(user);
} else {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
}
}
@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
user.setId(System.currentTimeMillis());
userRepository.put(user.getId(), user);
return ResponseEntity.status(HttpStatus.CREATED).body(user);
}
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User user) {
if (userRepository.containsKey(id)) {
user.setId(id);
userRepository.put(id, user);
return ResponseEntity.ok(user);
} else {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
}
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
if (userRepository.containsKey(id)) {
userRepository.remove(id);
return ResponseEntity.noContent().build();
} else {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
}
}