spring-boot-rest-api-standards by giuseppe-trisciuoglio/developer-kit
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill spring-boot-rest-api-standards本技能为在 Spring Boot 应用程序中构建 RESTful API 提供全面指导,涵盖一致的设计模式、正确的错误处理、验证以及基于 REST 原则和 Spring Boot 约定的架构最佳实践。
Spring Boot REST API 标准为构建生产就绪的 REST API 建立了一致的模式。这些标准涵盖基于资源的 URL 设计、正确的 HTTP 方法使用、状态码约定、DTO 模式、验证、错误处理、分页、安全头和架构分层。实施这些模式以确保 API 的一致性、可维护性并遵守 REST 原则。
在以下情况下使用此技能:
按照以下步骤创建设计良好的 REST API 端点:
设计基于资源的 URL
实现正确的 HTTP 方法
使用适当的状态码
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
创建请求/响应 DTO
@Data/@Value实现验证
@RequestBody 参数上使用 @Valid 注解@NotBlank, @Email, @Size 等)MethodArgumentNotValidException 处理验证错误设置错误处理
@RestControllerAdvice 进行全局异常处理ResponseStatusException 处理特定的 HTTP 状态码配置分页
添加安全头
@RestController
@RequestMapping("/v1/users")
@RequiredArgsConstructor
@Slf4j
public class UserController {
private final UserService userService;
@GetMapping
public ResponseEntity<Page<UserResponse>> getAllUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int pageSize) {
log.debug("Fetching users page {} size {}", page, pageSize);
Page<UserResponse> users = userService.getAll(page, pageSize);
return ResponseEntity.ok(users);
}
@GetMapping("/{id}")
public ResponseEntity<UserResponse> getUserById(@PathVariable Long id) {
return ResponseEntity.ok(userService.getById(id));
}
@PostMapping
public ResponseEntity<UserResponse> createUser(@Valid @RequestBody CreateUserRequest request) {
UserResponse created = userService.create(request);
return ResponseEntity.status(HttpStatus.CREATED).body(created);
}
@PutMapping("/{id}")
public ResponseEntity<UserResponse> updateUser(
@PathVariable Long id,
@Valid @RequestBody UpdateUserRequest request) {
return ResponseEntity.ok(userService.update(id, request));
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.delete(id);
return ResponseEntity.noContent().build();
}
}
// Request DTO
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CreateUserRequest {
@NotBlank(message = "User name cannot be blank")
private String name;
@Email(message = "Valid email required")
private String email;
}
// Response DTO
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserResponse {
private Long id;
private String name;
private String email;
private LocalDateTime createdAt;
}
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleValidationException(
MethodArgumentNotValidException ex, WebRequest request) {
String errors = ex.getBindingResult().getFieldErrors().stream()
.map(f -> f.getField() + ": " + f.getDefaultMessage())
.collect(Collectors.joining(", "));
ErrorResponse errorResponse = new ErrorResponse(
HttpStatus.BAD_REQUEST.value(),
"Validation Error",
"Validation failed: " + errors,
request.getDescription(false).replaceFirst("uri=", "")
);
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(ResponseStatusException.class)
public ResponseEntity<ErrorResponse> handleResponseStatusException(
ResponseStatusException ex, WebRequest request) {
ErrorResponse error = new ErrorResponse(
ex.getStatusCode().value(),
ex.getStatusCode().toString(),
ex.getReason(),
request.getDescription(false).replaceFirst("uri=", "")
);
return new ResponseEntity<>(error, ex.getStatusCode());
}
}
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final EmailService emailService;
// Dependencies are explicit and testable
}
// Java records (JDK 16+)
public record UserResponse(Long id, String name, String email, LocalDateTime createdAt) {}
// Lombok @Value for immutability
@Value
public class UserResponse {
Long id;
String name;
String email;
LocalDateTime createdAt;
}
@PostMapping
public ResponseEntity<UserResponse> createUser(@Valid @RequestBody CreateUserRequest request) {
// Validation happens automatically before method execution
return ResponseEntity.status(HttpStatus.CREATED).body(userService.create(request));
}
return ResponseEntity.status(HttpStatus.CREATED)
.header("Location", "/api/users/" + created.getId())
.header("X-Total-Count", String.valueOf(userService.count()))
.body(created);
@Service
@Transactional
public class UserService {
@Transactional(readOnly = true)
public Optional<User> findById(Long id) {
return userRepository.findById(id);
}
@Transactional
public User create(User user) {
return userRepository.save(user);
}
}
@Slf4j
@Service
public class UserService {
public User create(User user) {
log.info("Creating user with email: {}", user.getEmail());
return userRepository.save(user);
}
}
/**
* Retrieves a user by id.
*
* @param id the user id
* @return ResponseEntity containing a UserResponse
* @throws ResponseStatusException with 404 if user not found
*/
@GetMapping("/{id}")
public ResponseEntity<UserResponse> getUserById(@PathVariable Long id)
使用 DTO 将 API 契约与领域模型分离。这可以防止意外暴露内部数据结构,并允许在不更改数据库模式的情况下进行 API 演进。
使用 @RestControllerAdvice 一致地捕获所有异常。不要让原始异常冒泡到客户端。
对于可能返回大量结果的 GET 端点,实现分页以防止性能问题和 DDoS 漏洞。
切勿信任客户端输入。在所有请求 DTO 上使用 Jakarta 验证注解,以在控制器边界验证数据。
避免字段注入(@Autowired),以获得更好的可测试性和明确的依赖声明。
控制器应仅处理 HTTP 请求/响应适配。将业务逻辑委托给服务层。
始终从一开始就对 API 进行版本控制(例如,/v1/users),以便在不破坏现有客户端的情况下进行未来更改。
切勿在 API 响应或日志中记录或暴露敏感数据(密码、令牌、个人身份信息)。
references/ 目录以获取全面的参考资料,包括 HTTP 状态码、Spring 注解和详细示例developer-kit-java:spring-boot-code-review-expert 代理以获取代码审查指南spring-boot-dependency-injection/SKILL.md 以了解依赖注入模式../spring-boot-test-patterns/SKILL.md 以了解测试 REST API 的方法每周安装次数
475
代码仓库
GitHub 星标数
173
首次出现
2026年2月3日
安全审计
安装于
opencode378
gemini-cli372
codex366
github-copilot351
cursor351
claude-code336
This skill provides comprehensive guidance for building RESTful APIs in Spring Boot applications with consistent design patterns, proper error handling, validation, and architectural best practices based on REST principles and Spring Boot conventions.
Spring Boot REST API standards establish consistent patterns for building production-ready REST APIs. These standards cover resource-based URL design, proper HTTP method usage, status code conventions, DTO patterns, validation, error handling, pagination, security headers, and architectural layering. Implement these patterns to ensure API consistency, maintainability, and adherence to REST principles.
Use this skill when:
Follow these steps to create well-designed REST API endpoints:
Design Resource-Based URLs
Implement Proper HTTP Methods
Use Appropriate Status Codes
Create Request/Response DTOs
@Data/@ValueImplement Validation
@Valid annotation on @RequestBody parameters@NotBlank, @Email, @Size, etc.)MethodArgumentNotValidExceptionSet Up Error Handling
@RestControllerAdvice for global exception handlingResponseStatusException for specific HTTP status codesConfigure Pagination
Add Security Headers
@RestController
@RequestMapping("/v1/users")
@RequiredArgsConstructor
@Slf4j
public class UserController {
private final UserService userService;
@GetMapping
public ResponseEntity<Page<UserResponse>> getAllUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int pageSize) {
log.debug("Fetching users page {} size {}", page, pageSize);
Page<UserResponse> users = userService.getAll(page, pageSize);
return ResponseEntity.ok(users);
}
@GetMapping("/{id}")
public ResponseEntity<UserResponse> getUserById(@PathVariable Long id) {
return ResponseEntity.ok(userService.getById(id));
}
@PostMapping
public ResponseEntity<UserResponse> createUser(@Valid @RequestBody CreateUserRequest request) {
UserResponse created = userService.create(request);
return ResponseEntity.status(HttpStatus.CREATED).body(created);
}
@PutMapping("/{id}")
public ResponseEntity<UserResponse> updateUser(
@PathVariable Long id,
@Valid @RequestBody UpdateUserRequest request) {
return ResponseEntity.ok(userService.update(id, request));
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.delete(id);
return ResponseEntity.noContent().build();
}
}
// Request DTO
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CreateUserRequest {
@NotBlank(message = "User name cannot be blank")
private String name;
@Email(message = "Valid email required")
private String email;
}
// Response DTO
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserResponse {
private Long id;
private String name;
private String email;
private LocalDateTime createdAt;
}
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleValidationException(
MethodArgumentNotValidException ex, WebRequest request) {
String errors = ex.getBindingResult().getFieldErrors().stream()
.map(f -> f.getField() + ": " + f.getDefaultMessage())
.collect(Collectors.joining(", "));
ErrorResponse errorResponse = new ErrorResponse(
HttpStatus.BAD_REQUEST.value(),
"Validation Error",
"Validation failed: " + errors,
request.getDescription(false).replaceFirst("uri=", "")
);
return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(ResponseStatusException.class)
public ResponseEntity<ErrorResponse> handleResponseStatusException(
ResponseStatusException ex, WebRequest request) {
ErrorResponse error = new ErrorResponse(
ex.getStatusCode().value(),
ex.getStatusCode().toString(),
ex.getReason(),
request.getDescription(false).replaceFirst("uri=", "")
);
return new ResponseEntity<>(error, ex.getStatusCode());
}
}
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final EmailService emailService;
// Dependencies are explicit and testable
}
// Java records (JDK 16+)
public record UserResponse(Long id, String name, String email, LocalDateTime createdAt) {}
// Lombok @Value for immutability
@Value
public class UserResponse {
Long id;
String name;
String email;
LocalDateTime createdAt;
}
@PostMapping
public ResponseEntity<UserResponse> createUser(@Valid @RequestBody CreateUserRequest request) {
// Validation happens automatically before method execution
return ResponseEntity.status(HttpStatus.CREATED).body(userService.create(request));
}
return ResponseEntity.status(HttpStatus.CREATED)
.header("Location", "/api/users/" + created.getId())
.header("X-Total-Count", String.valueOf(userService.count()))
.body(created);
@Service
@Transactional
public class UserService {
@Transactional(readOnly = true)
public Optional<User> findById(Long id) {
return userRepository.findById(id);
}
@Transactional
public User create(User user) {
return userRepository.save(user);
}
}
@Slf4j
@Service
public class UserService {
public User create(User user) {
log.info("Creating user with email: {}", user.getEmail());
return userRepository.save(user);
}
}
/**
* Retrieves a user by id.
*
* @param id the user id
* @return ResponseEntity containing a UserResponse
* @throws ResponseStatusException with 404 if user not found
*/
@GetMapping("/{id}")
public ResponseEntity<UserResponse> getUserById(@PathVariable Long id)
Use DTOs to separate API contracts from domain models. This prevents accidental exposure of internal data structures and allows API evolution without database schema changes.
Use @RestControllerAdvice to catch all exceptions consistently. Don't let raw exceptions bubble up to clients.
For GET endpoints that might return many results, implement pagination to prevent performance issues and DDoS vulnerabilities.
Never trust client input. Use Jakarta validation annotations on all request DTOs to validate data at the controller boundary.
Avoid field injection (@Autowired) for better testability and explicit dependency declaration.
Controllers should only handle HTTP request/response adaptation. Delegate business logic to service layers.
Always version APIs from the start (e.g., /v1/users) to allow future changes without breaking existing clients.
Never log or expose sensitive data (passwords, tokens, PII) in API responses or logs.
references/ directory for comprehensive reference material including HTTP status codes, Spring annotations, and detailed examplesdeveloper-kit-java:spring-boot-code-review-expert agent for code review guidelinesspring-boot-dependency-injection/SKILL.md for dependency injection patterns../spring-boot-test-patterns/SKILL.md for testing REST APIsWeekly Installs
475
Repository
GitHub Stars
173
First Seen
Feb 3, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode378
gemini-cli372
codex366
github-copilot351
cursor351
claude-code336
飞书OpenAPI Explorer:探索和调用未封装的飞书原生API接口
7,500 周安装
LLM提示词缓存优化指南:降低90%成本,实现多级缓存与语义匹配
323 周安装
小红书内容转换器:一键将通用文章转为小红书爆款笔记格式 | AI写作助手
323 周安装
内容摘要AI工具:智能提取YouTube、网页、PDF和推文内容,支持测验学习和深度探索
324 周安装
Notion知识捕获工具 - 将对话笔记自动转化为结构化Notion页面 | 知识管理自动化
324 周安装
现代Angular最佳实践指南:TypeScript严格性、信号响应式、性能优化与测试
324 周安装
iOS VoIP 通话开发:CallKit + PushKit 集成原生通话 UI 指南
324 周安装