GET /api/memos/1
GET /api/memos/99999 → 404
목록(GET /api/memos)은 있고, 한 건만 가져오는 API는 없었다.
수정/삭제는 /{id}가 있었지만 조회는 목록에서만 쓰고 있었다.
| 목록 | 단건 | |
|---|---|---|
| URL | GET /api/memos | GET /api/memos/{id} |
| 응답 | page + items[] | MemoVO 하나 |
| 없을 때 | 빈 배열 | 404 |
Vue 화면에는 당장 꽂을 곳이 없어도, REST 기본 패턴이라 API만 만들어 놓았다.
확인은 Postman / 브라우저 Console로만 간단히 할 것.
SELECT ID AS id, TITLE AS title, CONTENT AS content,
STATUS AS status, CREATED_AT AS createdAt,
UPDATED_AT AS updatedAt, DEL_YN AS delYn
FROM MEMO
WHERE ID = 1
AND DEL_YN = 'N';
<select id="selectMemoById" parameterType="int" resultType="MemoVO">
SELECT ID AS "id", TITLE AS "title", ...
FROM MEMO
WHERE ID = #{id}
AND DEL_YN = 'N'
</select>
검증(400)이랑 짝으로, 없는 리소스용 예외를 둔다.
public class MemoNotFoundException extends RuntimeException {
public MemoNotFoundException(String message) {
super(message);
}
}
| 예외 | HTTP |
|---|---|
| MemoValidationException | 400 |
| MemoNotFoundException | 404 |
public MemoVO selectMemo(int id) {
MemoVO memo = memoMapper.selectMemoById(id);
if (memo == null) {
throw new MemoNotFoundException("메모를 찾을 수 없습니다");
}
return memo;
}
@GetMapping("/{id}")
public MemoVO get(@PathVariable int id) {
return memoService.selectMemo(id);
}
@ExceptionHandler(MemoNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public Map<String, String> handleNotFound(MemoNotFoundException e) {
Map<String, String> error = new HashMap<>();
error.put("message", e.getMessage());
return error;
}
검증 handler랑 같은 클래스에 추가하면 된다.
fetch('/api/memos/1').then(r => r.json()).then(console.log)
// → 200, 메모 객체
fetch('/api/memos/99999').then(async r => console.log(r.status, await r.json()))
// → 404, { message: "메모를 찾을 수 없습니다" }
Vue는 getMemo(id)만 api에 두고, 화면에는 연결하지 않았다.
GET /{id}