API 문서
1. 게시글목록 (Get)
<http://10.0.0.171:8080/api/post>
2. 게시글상세 (Get)
<http://10.0.0.171:8080/api/post/1>
3. 게시글쓰기 (Post)
<http://10.0.0.171:8080/api/post>
application/json
{"title": "제목입니다", "content":"내용입니다"}
4. 게시글삭제 (Delete)
<http://10.0.0.171:8080/api/post/1>
5. 게시글수정 (Put)
<http://10.0.0.171:8080/api/post/1>
application/json
{"title": "제목입니다", "content":"내용입니다"}
post_list_page
import 'package:blog/ui/components/custom_appbar.dart';
import 'package:blog/ui/list/components/post_list_body.dart';
import 'package:blog/ui/list/post_list_page_vm.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class PostListPage extends ConsumerWidget {
final refreshKey = GlobalKey<RefreshIndicatorState>();
@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
appBar: CustomAppBar(title: "Post List Page"),
body: RefreshIndicator(
key: refreshKey,
onRefresh: () async {
ref.read(postListProvider.notifier).notifyInit();
},
child: PostListBody(),
),
floatingActionButton: FloatingActionButton(
onPressed: (){
Navigator.pushNamed(context, "/write");
},
child: Icon(Icons.add),
),
);
}
}
post_list_body
import 'package:blog/data/post.dart';
import 'package:blog/ui/detail/post_detail_page.dart';
import 'package:blog/ui/list/post_list_page_vm.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class PostListBody extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
List<Post>? models = ref.watch(postListProvider);
if (models == null) {
return Center(child: CircularProgressIndicator());
} else {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: ListView.separated(
itemCount: models.length,
itemBuilder: (context, index) {
return ListTile(
leading: Text("${models[index].id}"),
title: Text("${models[index].title}"),
trailing: IconButton(
icon: Icon(Icons.arrow_forward_ios),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PostDetailPage(),
));
},
),
);
},
separatorBuilder: (context, index) => Divider(),
),
);
}
}
}
post_repository
import 'package:blog/core/utils.dart';
import 'package:blog/data/post.dart';
import 'package:dio/dio.dart';
class PostRepository {
// 1. 게시글목록
Future<List<Post>> findAll() async {
Response response = await dio.get("/api/post");
List<dynamic> list = response.data["body"];
List<Post> posts = list.map((e) => Post.fromJson(e)).toList();
return posts;
}
// 2. 게시글상세보기
Future<Post> findById(int id) async {
Response response = await dio.get("/api/post/$id");
Post post = Post.fromJson(response.data["body"]);
return post;
}
// 3. 게시글쓰기
Future<void> write(String title, String content) async {
try {
Response response = await dio.post(
"/api/post",
data: {
"title":title,
"content":content
},
);
} catch (error) {
throw Exception(error);
}
}
// 4. 게시글삭제
Future<void> deleteById(int id) async {
try {
Response response = await dio.delete("/api/post/$id");
} catch (error) {
throw Exception(error);
}
}
}
post_list_page_vm
import 'package:blog/data/post.dart';
import 'package:blog/data/post_repository.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
// 창고
class PostListVM extends StateNotifier<List<Post>?>{
PostListVM(super.state);
Future<void> notifyInit() async {
List<Post> posts = await PostRepository().findAll();
state = posts;
}
}
// 창고 관리자
final postListProvider = StateNotifierProvider<PostListVM, List<Post>?>((ref) {
return PostListVM(null)..notifyInit();
});
post_detail_page_vm
import 'package:blog/data/post.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
// 창고
class PostDetailVM extends StateNotifier<Post?>{
PostDetailVM(super.state);
Future<void> notifyInit() async {
// PostRepository().findById(1);
}
}
// 창고 관리자
final postDetailProvider = StateNotifierProvider<PostDetailVM, Post?>((ref) {
return PostDetailVM(null)..notifyInit();
});
post
class Post {
int id;
String title;
String content;
String createdAt;
String updateAt;
Post(this.id, this.title, this.content, this.createdAt, this.updateAt);
// Get 요청시 사용
Post.fromJson(Map<String, dynamic> json)
: id = json["id"] ?? "",
title = json["title"] ?? "",
content = json["content"] ?? "",
createdAt = json["createdAt"] ?? "",
updateAt = json["updateAt"] ?? "";
}