$ loading_
帮助用户设计和实现 Spring Boot 后端架构、REST API 与常见工程模式。
复制安装指令,让 AI 自动完成配置 · 推荐新手
请帮我安装 askskill 上的 "springboot-patterns" 技能: 1. 下载 https://raw.githubusercontent.com/affaan-m/ECC/main/docs/ja-JP/skills/springboot-patterns/SKILL.md 2. 保存为 ~/.claude/skills/springboot-patterns/SKILL.md 3. 装好后重载技能,告诉我可以用了
请为一个 Spring Boot 电商系统设计分层架构,包含 controller、service、repository、dto、entity 的职责划分,并给出推荐的项目目录结构与示例代码骨架。
输出清晰的分层架构说明、目录结构建议,以及可直接参考的代码模板。
请检查以下 Spring Boot REST API 设计是否符合最佳实践,并从资源命名、状态码、分页、错误响应和版本控制角度给出改进建议与示例。
输出 REST API 设计问题清单、优化建议和更规范的接口示例。
我有一个 Spring Boot 服务需要提升查询性能,请给出使用 Spring Cache 和异步处理的方案,包括适用场景、配置方式、注解示例,以及日志记录和异常处理建议。
输出缓存与异步处理的实现方案、配置示例,以及配套的日志和异常处理建议。
スケーラブルで本番グレードのサービスのためのSpring BootアーキテクチャとAPIパターン。
@RestController
@RequestMapping("/api/markets")
@Validated
class MarketController {
private final MarketService marketService;
MarketController(MarketService marketService) {
this.marketService = marketService;
}
@GetMapping
ResponseEntity<Page<MarketResponse>> list(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size) {
Page<Market> markets = marketService.list(PageRequest.of(page, size));
return ResponseEntity.ok(markets.map(MarketResponse::from));
}
@PostMapping
ResponseEntity<MarketResponse> create(@Valid @RequestBody CreateMarketRequest request) {
Market market = marketService.create(request);
return ResponseEntity.status(HttpStatus.CREATED).body(MarketResponse::from(market));
}
}
public interface MarketRepository extends JpaRepository<MarketEntity, Long> {
@Query("select m from MarketEntity m where m.status = :status order by m.volume desc")
List<MarketEntity> findActive(@Param("status") MarketStatus status, Pageable pageable);
}
@Service
public class MarketService {
private final MarketRepository repo;
public MarketService(MarketRepository repo) {
this.repo = repo;
}
@Transactional
public Market create(CreateMarketRequest request) {
MarketEntity entity = MarketEntity.from(request);
MarketEntity saved = repo.save(entity);
return Market.from(saved);
}
}
public record CreateMarketRequest(
@NotBlank @Size(max = 200) String name,
@NotBlank @Size(max = 2000) String description,
@NotNull @FutureOrPresent Instant endDate,
@NotEmpty List<@NotBlank String> categories) {}
public record MarketResponse(Long id, String name, MarketStatus status) {
static MarketResponse from(Market market) {
return new MarketResponse(market.id(), market.name(), market.status());
}
}
@ControllerAdvice
class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
ResponseEntity<ApiError> handleValidation(MethodArgumentNotValidException ex) {
String message = ex.getBindingResult().getFieldErrors().stream()
.map(e -> e.getField() + ": " + e.getDefaultMessage())
.collect(Collectors.joining(", "));
return ResponseEntity.badRequest().body(ApiError.validation(message));
}
@ExceptionHandler(AccessDeniedException.class)
ResponseEntity<ApiError> handleAccessDenied() {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(ApiError.of("Forbidden"));
}
@ExceptionHandler(Exception.class)
ResponseEntity<ApiError> handleGeneric(Exception ex) {
// スタックトレース付きで予期しないエラーをログ
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(ApiError.of("Internal server error"));
}
}
構成クラスで@EnableCachingが必要です。
@Service
public class MarketCacheService {
private final MarketRepository repo;
public MarketCacheService(MarketRepository repo) {
this.repo = repo;
}
@Cacheable(value = "market", key = "#id")
public Market getById(Long id) {
return repo.findById(id)
.map(Market::from)
.orElseThrow(() -> new EntityNotFoundException("Market not found"));
}
@CacheEvict(value = "market", key = "#id")
public void evict(Long id) {}
}
構成クラスで@EnableAsyncが必要です。
@Service
public class NotificationService {
@Async
public CompletableFuture<Void> sendAsync(Notification notification) {
// メール/SMS送信
return CompletableFuture.completedFuture(null);
}
}
@Service
public class ReportService {
private static final Logger log = LoggerFactory.getLogger(ReportService.class);
public Report generate(Long marketId) {
log.info("generate_report marketId={}", marketId);
try {
// ロジック
…
通过双评审智能体对结果进行对抗式校验,提升输出发布前的可靠性
帮助开发者梳理后端架构模式、API设计与数据库优化最佳实践