Skip to content

RESTful API 示例

构建符合 REST 规范的 API 服务。

API 设计

资源定义

GET    /api/users          # 获取用户列表
GET    /api/users/{id}     # 获取单个用户
POST   /api/users          # 创建用户
PUT    /api/users/{id}     # 更新用户
DELETE /api/users/{id}     # 删除用户

Controller 实现

java
@RestController("/api/users")
public class UserRestController {
    
    private final UserService userService;
    
    @GetMapping
    public ResponseEntity<List<User>> listUsers(
        @RequestParam(defaultValue = "0") int page,
        @RequestParam(defaultValue = "20") int size
    ) {
        Page<User> users = userService.findAll(page, size);
        return ResponseEntity.ok(users.getContent());
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        return userService.findById(id)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.notFound().build());
    }
    
    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody @Valid UserRequest request) {
        User user = userService.create(request);
        return ResponseEntity
            .created(URI.create("/api/users/" + user.getId()))
            .body(user);
    }
    
    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(
        @PathVariable Long id,
        @RequestBody @Valid UserRequest request
    ) {
        return userService.update(id, request)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.notFound().build());
    }
    
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.delete(id);
        return ResponseEntity.noContent().build();
    }
}

请求验证

java
public class UserRequest {
    
    @NotBlank(message = "用户名不能为空")
    @Size(min = 3, max = 20, message = "用户名长度必须在 3-20 之间")
    private String username;
    
    @NotBlank(message = "邮箱不能为空")
    @Email(message = "邮箱格式不正确")
    private String email;
    
    @Min(value = 18, message = "年龄必须大于 18")
    private Integer age;
    
    // Getters and Setters
}

统一响应格式

java
public class ApiResponse<T> {
    
    private int code;
    private String message;
    private T data;
    
    public static <T> ApiResponse<T> success(T data) {
        return new ApiResponse<>(200, "success", data);
    }
    
    public static <T> ApiResponse<T> error(int code, String message) {
        return new ApiResponse<>(code, message, null);
    }
}

// 使用
@GetMapping("/{id}")
public ApiResponse<User> getUser(@PathVariable Long id) {
    User user = userService.findById(id);
    return ApiResponse.success(user);
}

异常处理

java
@RestControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(NotFoundException.class)
    public ResponseEntity<ApiResponse<Void>> handleNotFound(NotFoundException e) {
        return ResponseEntity
            .status(HttpStatus.NOT_FOUND)
            .body(ApiResponse.error(404, e.getMessage()));
    }
    
    @ExceptionHandler(ValidationException.class)
    public ResponseEntity<ApiResponse<Void>> handleValidation(ValidationException e) {
        return ResponseEntity
            .status(HttpStatus.BAD_REQUEST)
            .body(ApiResponse.error(400, e.getMessage()));
    }
    
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ApiResponse<Void>> handleGeneral(Exception e) {
        return ResponseEntity
            .status(HttpStatus.INTERNAL_SERVER_ERROR)
            .body(ApiResponse.error(500, "服务器内部错误"));
    }
}

分页支持

java
public class Page<T> {
    
    private List<T> content;
    private int page;
    private int size;
    private long total;
    
    public int getTotalPages() {
        return (int) Math.ceil((double) total / size);
    }
    
    public boolean hasNext() {
        return page < getTotalPages() - 1;
    }
}

// Service 层
public Page<User> findAll(int page, int size) {
    long total = userRepository.count();
    List<User> users = userRepository.findAll(page * size, size);
    return new Page<>(users, page, size, total);
}

API 文档

java
/**
 * 用户管理 API
 */
@RestController("/api/users")
@ApiDoc(
    title = "用户管理",
    description = "用户的增删改查操作"
)
public class UserRestController {
    
    /**
     * 获取用户列表
     * 
     * @param page 页码(从 0 开始)
     * @param size 每页大小
     * @return 用户列表
     */
    @GetMapping
    @ApiOperation(
        summary = "获取用户列表",
        description = "分页获取所有用户"
    )
    public ResponseEntity<List<User>> listUsers(
        @ApiParam(value = "页码", example = "0") int page,
        @ApiParam(value = "每页大小", example = "20") int size
    ) {
        // ...
    }
}

下一步

Released under the Apache License 2.0