From 9418e8b3458a2203bc1522cf117b8f33ac15dff4 Mon Sep 17 00:00:00 2001 From: jieun Date: Tue, 20 Oct 2026 17:37:40 +0900 Subject: [PATCH] Complete manual Spring Boot subject API --- .../manual/SubjectController.java | 52 +++++++++++++++++++ .../manual/subject/CreateSubjectRequest.java | 11 ++++ .../questionbank/manual/subject/Subject.java | 5 ++ .../manual/subject/SubjectService.java | 34 ++++++++++++ 4 files changed, 102 insertions(+) create mode 100644 src/main/java/com/example/questionbank/manual/SubjectController.java create mode 100644 src/main/java/com/example/questionbank/manual/subject/CreateSubjectRequest.java create mode 100644 src/main/java/com/example/questionbank/manual/subject/Subject.java create mode 100644 src/main/java/com/example/questionbank/manual/subject/SubjectService.java diff --git a/src/main/java/com/example/questionbank/manual/SubjectController.java b/src/main/java/com/example/questionbank/manual/SubjectController.java new file mode 100644 index 0000000..b4cbad9 --- /dev/null +++ b/src/main/java/com/example/questionbank/manual/SubjectController.java @@ -0,0 +1,52 @@ +package com.example.questionbank.manual; + +import com.example.questionbank.manual.subject.CreateSubjectRequest; +import com.example.questionbank.manual.subject.Subject; +import com.example.questionbank.manual.subject.SubjectService; +import jakarta.validation.Valid; +import java.net.URI; +import java.util.List; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; + +@RestController +@RequestMapping("/api/subjects") +public class SubjectController { + + private final SubjectService subjectService; + + public SubjectController(SubjectService subjectService) { + this.subjectService = subjectService; + } + + @PostMapping + public ResponseEntity create( + @Valid @RequestBody CreateSubjectRequest request + ) { + Subject created = subjectService.create(request.name()); + return ResponseEntity + .created(URI.create("/api/subjects/" + created.id())) + .body(created); + } + + @GetMapping + public List findAll() { + return subjectService.findAll(); + } + + @GetMapping("/{id}") + public Subject findById(@PathVariable Long id) { + return subjectService.findById(id) + .orElseThrow(() -> new ResponseStatusException( + HttpStatus.NOT_FOUND, + "과목을 찾을 수 없습니다. id=" + id + )); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/questionbank/manual/subject/CreateSubjectRequest.java b/src/main/java/com/example/questionbank/manual/subject/CreateSubjectRequest.java new file mode 100644 index 0000000..2520c9f --- /dev/null +++ b/src/main/java/com/example/questionbank/manual/subject/CreateSubjectRequest.java @@ -0,0 +1,11 @@ +package com.example.questionbank.manual.subject; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; + +public record CreateSubjectRequest( + @NotBlank(message = "과목명은 필수입니다.") + @Size(max = 100, message = "과목명은 100자 이하여야 합니다.") + String name +) { +} \ No newline at end of file diff --git a/src/main/java/com/example/questionbank/manual/subject/Subject.java b/src/main/java/com/example/questionbank/manual/subject/Subject.java new file mode 100644 index 0000000..d5efbc3 --- /dev/null +++ b/src/main/java/com/example/questionbank/manual/subject/Subject.java @@ -0,0 +1,5 @@ +package com.example.questionbank.manual.subject; + +public record Subject(Long id, String name) { + +} \ No newline at end of file diff --git a/src/main/java/com/example/questionbank/manual/subject/SubjectService.java b/src/main/java/com/example/questionbank/manual/subject/SubjectService.java new file mode 100644 index 0000000..503ce88 --- /dev/null +++ b/src/main/java/com/example/questionbank/manual/subject/SubjectService.java @@ -0,0 +1,34 @@ +package com.example.questionbank.manual.subject; + +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; +import org.springframework.stereotype.Service; + +@Service +public class SubjectService { + + private final Map subjects = new ConcurrentHashMap<>(); + private final AtomicLong sequence = new AtomicLong(); + + public Subject create(String name) { + long id = sequence.incrementAndGet(); + Subject subject = new Subject(id, name.trim()); + subjects.put(id, subject); + return subject; + } + + public List findAll() { + return subjects.values() + .stream() + .sorted(Comparator.comparing(Subject::id)) + .toList(); + } + + public Optional findById(Long id) { + return Optional.ofNullable(subjects.get(id)); + } +} \ No newline at end of file