서버
record 문법

커스텀 생성자 DTO(Post post)를 통해 Post 객체로부터 DTO
public record DTO(Integer id, String title) {
public DTO(Post post) {
this(post.getId(), post.getTitle());
}
}
내부적으로 자동 생성되는 코드 예상
public final class DTO {
private final Integer id;
private final String title;
public DTO(Integer id, String title) { ... }
public Integer id() { return id; }
public String title() { return title; }
public boolean equals(Object o) { ... }
public int hashCode() { ... }
public String toString() { ... }
}
게시글 쓰기

게시글 목록

게시글 삭제

프론트
요구사항
# 플러터 CRUD (기초)
## 게시글 목록
- 화면에 id, title만 출력
- PostListVM 만들기 -> 컬렉션 관리
## 게시글 쓰기
- TextEditingController를 사용
- PostListVM에서 글쓰기 하기
## 게시글 상세보기
- PostList 화면에서 Post 객체 전달해서 출력하기 (뒤로가기 할 때 vm이 없으니까 autoDispose 필요X)
- PostDetail 화면은 ViewModel이 없음
## 게시글 삭제하기
- PostListVM에 삭제하기 요청
- PostList 화면의 상태 변경 (다시 통신X)
## 게시글 수정하기
- 없음
Riverpod으로 상태 관리
상태관리할 범위 정하고 시작해야한다!

게시글 목록
post_list_vm


PostRepository getList 테스트
C:\workspace\tools\flutter\bin\flutter.bat --no-color test --machine --start-paused test\data\post_repository_test.dart
Testing started at 오전 10:18 ...
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ #0 PostRepository.getList (package:blog/data/post_repository.dart:9:14)
│ #1 <asynchronous suspension>
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ 🐛 {
│ 🐛 "status": 200,
│ 🐛 "msg": "성공",
│ 🐛 "body": [
│ 🐛 {
│ 🐛 "id": 23,
│ 🐛 "title": "title 23",
│ 🐛 "content": "content 23",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 22,
│ 🐛 "title": "title 22",
│ 🐛 "content": "content 22",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 21,
│ 🐛 "title": "title 21",
│ 🐛 "content": "content 21",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 20,
│ 🐛 "title": "title 20",
│ 🐛 "content": "content 20",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 19,
│ 🐛 "title": "title 19",
│ 🐛 "content": "content 19",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 18,
│ 🐛 "title": "title 18",
│ 🐛 "content": "content 18",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 17,
│ 🐛 "title": "title 17",
│ 🐛 "content": "content 17",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 16,
│ 🐛 "title": "title 16",
│ 🐛 "content": "content 16",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 15,
│ 🐛 "title": "title 15",
│ 🐛 "content": "content 15",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 14,
│ 🐛 "title": "title 14",
│ 🐛 "content": "content 14",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 13,
│ 🐛 "title": "title 13",
│ 🐛 "content": "content 13",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 12,
│ 🐛 "title": "title 12",
│ 🐛 "content": "content 12",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 11,
│ 🐛 "title": "title 11",
│ 🐛 "content": "content 11",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 10,
│ 🐛 "title": "title 10",
│ 🐛 "content": "content 10",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 9,
│ 🐛 "title": "title 9",
│ 🐛 "content": "content 9",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 8,
│ 🐛 "title": "title 8",
│ 🐛 "content": "content 8",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 7,
│ 🐛 "title": "title 7",
│ 🐛 "content": "content 7",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 6,
│ 🐛 "title": "title 6",
│ 🐛 "content": "content 6",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 5,
│ 🐛 "title": "title 5",
│ 🐛 "content": "content 5",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 4,
│ 🐛 "title": "title 4",
│ 🐛 "content": "content 4",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 3,
│ 🐛 "title": "title 3",
│ 🐛 "content": "content 3",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 2,
│ 🐛 "title": "title 2",
│ 🐛 "content": "content 2",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 },
│ 🐛 {
│ 🐛 "id": 1,
│ 🐛 "title": "title 1",
│ 🐛 "content": "content 1",
│ 🐛 "createdAt": "2025-06-11"
│ 🐛 }
│ 🐛 ]
│ 🐛 }
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
No tests were found.
post_list_body

실행 결과

게시글 상세보기
post 넘기기

post_detail_body

실행 결과

게시글 쓰기
통신

통신 테스트

post_write_form
TextEditingController를 사용할 것이므로 post_list_vm에 write 함수를 만들고 title과 content를 vm에게 write 함수를 통해 전달해야함.

post_list_vm의 write 함수

실행 결과
게시글 등록 후 목록으로 돌아간다.

상세보기 화면

게시글 삭제
통신

통신 테스트

post_detail_body

post_list_vm의 deleteOne 함수

실행 결과
삭제 후 목록으로 돌아갈 때 재통신 하지 않는 것이 요구사항이었다. id = 21 게시글을 삭제 후 삭제 통신에 대한 응답은 왔으나 목록에 대한 통신의 응답은 오지 않았기 때문에 재통신이 일어나지 않고 상태를 갱신한 것을 확인할 수 있다.

Share article