RESTful API设计与实现
RESTful API设计与实现
概述
RESTful API是现代Web服务的标准接口风格。本教程介绍RESTful API的设计原则和Spring Boot实现。
1. RESTful API设计原则
// 资源命名规范
// /api/users - 用户集合
// /api/users/1 - 单个用户
// /api/users/1/orders - 用户的订单集合
// HTTP方法
// GET - 获取资源
// POST - 创建资源
// PUT - 更新资源
// DELETE - 删除资源
// PATCH - 部分更新资源
2. Spring Boot实现
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping("/api/v1/users")
@CrossOrigin(origins = "*")
public class UserApiController {
private final UserService userService;
public UserApiController(UserService userService) {
this.userService = userService;
}
@GetMapping
public ResponseEntity<List<UserDto>> getAllUsers() {
List<UserDto> users = userService.findAll();
return ResponseEntity.ok(users);
}
@GetMapping("/{id}")
public ResponseEntity<UserDto> getUserById(@PathVariable Long id) {
return userService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PostMapping
public ResponseEntity<UserDto> createUser(@Valid @RequestBody CreateUserRequest request) {
UserDto created = userService.create(request);
return ResponseEntity.ok(created);
}
@PutMapping("/{id}")
public ResponseEntity<UserDto> updateUser(
@PathVariable Long id,
@Valid @RequestBody UpdateUserRequest request) {
return userService.update(id, request)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PatchMapping("/{id}")
public ResponseEntity<UserDto> patchUser(
@PathVariable Long id,
@RequestBody Map<String, Object> updates) {
return userService.patch(id, updates)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
if (userService.delete(id)) {
return ResponseEntity.noContent().build();
}
return ResponseEntity.notFound().build();
}
@GetMapping("/search")
public ResponseEntity<List<UserDto>> searchUsers(
@RequestParam String name,
@RequestParam(required = false) Integer age) {
return ResponseEntity.ok(userService.search(name, age));
}
}
3. 错误处理
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ErrorResponse> handleUserNotFound(UserNotFoundException ex) {
ErrorResponse error = new ErrorResponse(
HttpStatus.NOT_FOUND.value(),
ex.getMessage()
);
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
}
@ExceptionHandler(ValidationException.class)
public ResponseEntity<ErrorResponse> handleValidation(ValidationException ex) {
ErrorResponse error = new ErrorResponse(
HttpStatus.BAD_REQUEST.value(),
ex.getMessage()
);
return ResponseEntity.badRequest().body(error);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGeneral(Exception ex) {
ErrorResponse error = new ErrorResponse(
HttpStatus.INTERNAL_SERVER_ERROR.value(),
"服务器内部错误"
);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
}
4. 实际应用示例
分页查询
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
@RestController
@RequestMapping("/api/products")
public class ProductController {
@GetMapping
public Page<ProductDto> getProducts(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "id") String sort) {
Pageable pageable = PageRequest.of(page, size, Sort.by(sort));
return productService.findAll(pageable);
}
}
API版本控制
@RestController
@RequestMapping("/api/v1/users")
public class UserApiControllerV1 {
// v1版本的实现
}
@RestController
@RequestMapping("/api/v2/users")
public class UserApiControllerV2 {
// v2版本的实现
}
5. 最佳实践
- 使用资源命名规范:清晰的URL结构
- 正确使用HTTP方法:GET、POST、PUT、DELETE
- 使用状态码:200、201、404、500等
- 使用DTO:分离API层和业务层
- 文档化API:使用Swagger/OpenAPI
总结
RESTful API是现代Web服务的标准接口风格。掌握RESTful API的设计原则和实现方法,可以构建高质量的Web服务。