Compare commits

1 Commits
Author SHA1 Message Date
jieun 9418e8b345 Complete manual Spring Boot subject API 2026-10-20 17:37:40 +09:00
4 changed files with 102 additions and 0 deletions

No files matched your search

@@ -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<Subject> 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<Subject> findAll() {
return subjectService.findAll();
}
@GetMapping("/{id}")
public Subject findById(@PathVariable Long id) {
return subjectService.findById(id)
.orElseThrow(() -> new ResponseStatusException(
HttpStatus.NOT_FOUND,
"과목을 찾을 수 없습니다. id=" + id
));
}
}
@@ -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
) {
}
@@ -0,0 +1,5 @@
package com.example.questionbank.manual.subject;
public record Subject(Long id, String name) {
}
@@ -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<Long, Subject> 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<Subject> findAll() {
return subjects.values()
.stream()
.sorted(Comparator.comparing(Subject::id))
.toList();
}
public Optional<Subject> findById(Long id) {
return Optional.ofNullable(subjects.get(id));
}
}