👉 mock: 거짓된, 가짜의
👉 mock data: 가짜 데이터, 샘플 데이터
실제 데이터 대신, 가짜 데이터를 사용하는 것을 말한다!
Youtube 오픈 API 를 이용해서 리액트로 클론코딩 프로젝트를 진행하였다. 이번 프로젝트를 진행하면서 실제 API 에서 받아온 데이터가 아닌 샘플로 만든 Mock data를 사용해서 개발을 진행해보았다! 왜 샘플 데이터를 사용했을까? 😚
👉 Mock data를 사용하는 이유
개발 초기 단계에서: 데이터베이스 스키마나 API 명세 등이 아직 정해지지 않았을 때 개발을 시작하기 위해 사용된다. 이를 통해 실제 데이터에 영향을 주지 않으면서 빠르게 개발할 수 있다.
테스트: 테스트 시에는 가짜 데이터를 사용하여 애플리케이션의 동작을 확인할 수 있다. 이를 통해 실제 데이터를 사용하지 않고도 다양한 경우를 시도하고 버그를 발견할 수 있다.
보안: 실제 데이터를 사용하는 것은 보안 상의 문제가 있을 수 있다. 일부 데이터는 액세스 권한이 필요하거나 민감한 데이터일 수 있다. 이러한 경우, mock data를 사용하여 해당 데이터의 더미를 만들어서 개발을 계속할 수 있다.
확장성: 대규모 애플리케이션에서는 데이터베이스나 API에서 대량의 데이터를 가져오는 것이 많은 리소스를 소모한다. 이때 Mock data를 사용하여 개발자가 애플리케이션의 확장성을 테스트할 수 있다.
👉 나는 아래와 같은 이유로 Mock data를 만들어 사용했다.
만약 개발 도중, 하루 API 요청 수가 초과되었다면 개발 중 정말 난감했을 것 같다.
따라서 Mock data를 만들어 사용하게 되었다. 그러면 매번 API를 호출하지 않고 자유롭게 개발할 수 있었다 👍
실제로 현업에서는 프론트엔드 개발을 진행하려는데 필요한 백엔드 API가 완성이 되지 않았을 경우가 있어 이 작업이 완성될 때까지 무작정 기다리는 것이 아닌,
mock data를 만들어 데이터가 들어오는 형태와 상황을 미리 대비하고 의도에 맞게 먼저 UI 구현을 진행한다고 한다.
❗️ mock data를 적용해서 짠 코드가 실제 API를 호출해도 잘 돌아가는지 확인이 필요하며, API 호출하는 코드로 변경하게되면 지금까지 짜 놓은 코드가 불필요해지는 단점이 발생할 수 있다.
sample.json
파일 생성 (파일이름은 데이터 내용에 맞게 지어주면 좋을 것 같다 🙌)sample.json
파일에 붙혀넣어준다.데이터가 사용되는 Videos 컴포넌트에서 Mock data를 받아오는 코드를 작성하였다.
const {
isLoading,
error,
data: videos,
} = useQuery(['videos', keyword], async () => {
return fetch(`/videos/${keyword ? 'search' : 'popular'}.json`)
.then((res) => res.json())
.then((data) => data.items);
});
const {
isLoading,
error,
data: videos,
} = useQuery(['videos', keyword], async () => {
return axios.get(`/videos/${keyword ? 'search' : 'popular'}.json`)
.then((res) => res.data.items);
});
위의 문제점 4-6번을 해결하기 위해
src > api 폴더를 만들어 api 통신 관련 코드를 함수로 분리해준다.
// src > api > youtube.js 파일
const search = async (keyword) => {
return axios.get(`/videos/${keyword ? 'search' : 'popular'}.json`).then((res) => res.data.items);
};
export default search;
// api 함수를 쓰는 컴포넌트 : search 함수를 import해서 사용
const {
isLoading,
error,
data: videos,
} = useQuery(['videos', keyword], () => search(keyword));
위의 문제점 1-3번을 해결하기 위해
mockdata를 사용하는 코드
와
실제로 유튜브 API 통신 하는 코드
를
효율적으로 변환하여 사용될 수 있도록 리팩토링을 진행하였다.
👉 youtube라는 동일한 api가 있는 두 가지 구현사항을 만들 것!
앞서 생성한 api 폴더 내 youtube.js 파일을 복사하여 fakeYoutube.js 파일을 추가로 만든다.
fakeYoutube에서는 json을 읽어오도록 하고,
youtube에서는 실제로 네트워크 통신을 하도록 만든다.
class FakeYoutube {
constructor() {}
async search(keyword) {
return keyword ? this.#searchByKeyword(keyword) : this.#mostPopular();
}
async #searchByKeyword() {
return axios
.get(`/videos/search.json`)
.then((res) => res.data.items)
.then((items) => items.map((item) => ({ ...item, id: item.id.videoId })));
}
async #mostPopular() {
return axios.get(`/videos/popular.json`).then((res) => res.data.items);
}
}
class Youtube {
constructor() {
this.httpClient = axios.create({
baseURL: 'https://www.googleapis.com/youtube/v3',
params: { key: precess.env.REACT_APP_YOUTUBE_API_KEY }, // key값이 담겨있는 환경변수
});
}
async search(keyword) {
return keyword ? this.#searchByKeyword(keyword) : this.#mostPopular();
}
async #searchByKeyword(keyword) {
return this.httpClient
.get('search', {
params: {
part: 'snippet',
maxResults: 25,
type: 'video',
q: keyword,
},
})
.then((res) => res.data.items)
.then((items) => items.map((item) => ({ ...item, id: item.id.videoId })));
}
async #mostPopular() {
return this.httpClient
.get('videos', {
params: {
part: 'snippet',
maxResults: 25,
chart: 'mostPopular',
},
})
.then((res) => res.data.items);
}
}
const {
isLoading,
error,
data: videos,
} = useQuery(['videos', keyword], () => {
const youtube = new Youtube();
// const youtube = new FakeYoutube();
return youtube.search(keyword);
});