# 아키텍처 가이드
# API 호출 및 상태관리
- 기본적으로는 MVVM 형태
- api는 rest 서버 호출을 캡슐화 합니다.
- store는 ViewModel에 해당하며 클라이언트의 비지니스 로직을 캡슐화 합니다.
# rest.js
api 호출의 공통적인 처리 루틴을 라이브러리로 만든 것입니다.
import axios from "axios";
import {useMainStore} from '@/store/main'
import {useEtcStore} from '@/store/etc'
import errorLog from "./errorLog";
const mainStore = useMainStore();
const etcStroe = useEtcStore();
const instance = axios.create({
baseURL: process.env.VUE_APP_API_BASEURL,
});
instance.interceptors.request.use(function (config) {
etcStroe.setLoading(true);
if (mainStore.token !== null) {
config["headers"] = {
Authorization: `Bearer ${mainStore.token}`,
};
}
return config;
});
instance.interceptors.response.use(
function (response) {
etcStroe.setLoading(false);
return Promise.resolve(response);
},
function (error) {
etcStroe.setLoading(false);
errorLog.sendMessage(0, JSON.stringify(error));
return Promise.reject(error);
}
);
export default instance;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
- 14, 26, 31: API 호출 후 응답이 늦어지면 로딩 중 아이콘 표시하기
- 16-20: 토큰 정보가 있으면 헤더에 자동으로 포함 시켜서 전송하기
- 32: 에러가 발생하면 에러 로그 서버로 메시지 자동으로 전송하기
# api
import rest from "@/utils/rest";
export default {
async getPosts() {
return rest.get("/posts");
},
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# store
import { defineStore } from "pinia";
import apiPost from "@/api/post";
export const usePostStore = defineStore("post", {
id: "post",
state: () => ({
posts: [],
}),
actions: {
async fetchPosts() {
try {
const response = await apiPost.getPosts();
this.posts = response.data;
} catch (error) {
this.posts = [];
}
}
},
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# view
<template>
<div v-for="post in postStore.posts" :key="post.id">
<PostDetailComponent :post="post" />
<CommentComponent :post="post" />
</div>
</template>
<script>
import { usePostStore } from '@/store/post'
import PostDetailComponent from '@/components/PostDetailComponent.vue'
import CommentComponent from '@/components/CommentComponent.vue'
export default {
components: {
PostDetailComponent,
CommentComponent,
},
setup() {
const postStore = usePostStore()
return { postStore }
},
mounted() {
this.postStore.fetchPosts()
},
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28