axios-mock-adapter를 사용해 백엔드 없이 api 주고받기 [with React]

wkahd01·2021년 10월 30일
2

Toy-Project

목록 보기
13/13
post-thumbnail

오늘은 간단하게 faker 라이브러리를 사용해 사진첩을 만들었다.

원하는 데이터를 가지고 api 통신을 하려면 백엔드의 존재가 필수적이였는데,

이를 axios-mock-adapter를 사용해 백엔드를 대체하였다.

준비

사용한 라이브러리는 다음과 같다.


  • axios: 비동기 통신 라이브러리
    설치: yarn add axios

  • axios-mock-adapter: axios 를 사용했을 때 가짜 요청을 발생시키는 라이브러리
    설치: axios-mock-adapter

  • faker: 가짜 데이터를 생성해주는 라이브러리
    설치: yarn add faker

  • antd: antd 디자인 라이브러리
    설치: yarn add antd

과정

  1. 버튼을 클릭.

  2. 버튼 클릭 이벤트로 mock 데이터 가져옴(with axios-mock-adapter)
    (여기서 mock 데이터는 faker를 통해 생성한다.)

  3. 가져온 mock 데이터를 화면에 출력한다.

1. 라이브러리 불러오기

import React, { useState } from "react";

import axios from "axios";
import AxiosMockAdapter from "axios-mock-adapter";
import faker from "faker";

const mock = new AxiosMockAdapter(axios);

const App = () => {
  return (
    <div>
    </div>
  )
}

export default App

2. mock 데이터 생성하기

/* 
import React, { useState } from "react";

import axios from "axios";
import AxiosMockAdapter from "axios-mock-adapter";
import faker from "faker";

const mock = new AxiosMockAdapter(axios); 
*/

const posts = [...Array(23)].map((_, index) => {
  const setIndex = index + 1;
  return {
    id: `postId-${setIndex}`,
    title: faker.lorem.words(),
    content: faker.lorem.lines(2),
    image: `${faker.image.animals()}?random=${Math.round(Math.random() * 1000)}`
  };
});

/*
const App = () => {
  return <div></div>;
};

export default App;
*/

여러 포스트들을 한번에 만들기 위해 다음과 같은 코드를 사용했다.

const posts = [...Array(23)].map((_, index) => {})
설명: [] 안에 배열 23개를 만들어주고, map으로 순회를 돌면서
{}내부 값으로 채워나가는 코드이다.

faker는 faker.[대분류].[소분류]()의 형태를 사용해야 한다.
자세한 사용법은 https://www.npmjs.com/package/faker 를 참조하면 된다.

title: faker.lorem.words()
=> lorem.words()는 단어 여러개를 가짜로 만든다는 뜻이다.

image: faker.image.animals()?random={faker.image.animals()}?random={Math.round(Math.random() * 1000)}=> 해당 코드는faker.image.animals()`를 사용하였을 때, 하나의 이미지만 반복되어서 랜덤으로 생성하기 위해 위와 같이 짰다.

3. axios-mock-adapter 설정

/* 
import React, { useState } from "react";

import axios from "axios";
import AxiosMockAdapter from "axios-mock-adapter";
import faker from "faker";

const mock = new AxiosMockAdapter(axios); 

const posts = [...Array(23)].map((_, index) => {
  const setIndex = index + 1;
  return {
    id: `postId-${setIndex}`,
    title: faker.lorem.words(),
    content: faker.lorem.lines(2),
    image: `${faker.image.animals()}?random=${Math.round(Math.random() * 1000)}`
  };
});
*/
mock.onGet("/posts").reply(() => {
  try {
    const results = posts;
    return [200, results];
  } catch (error) {
    console.error(error);
    return [500, { message: "Internal server error" }];
  }
});
/*
const App = () => {
  return <div></div>;
};

export default App;
*/

mock.onGet("/posts")은 나중에 api 통신에서 "/posts"로 get 요청을 받을 때 사용한다.

더 자세한 정보는 https://www.npmjs.com/package/axios-mock-adapter를 참고하면 된다.

4. 기본 ui 만들기

/*
import React, { useState } from "react";
import axios from "axios";

import AxiosMockAdapter from "axios-mock-adapter";
import faker from "faker";
*/
import "antd/dist/antd.css";
import { Card, Col, Row, Button } from "antd";
/*
const mock = new AxiosMockAdapter(axios);

const posts = [...Array(23)].map((_, index) => {
  const setIndex = index + 1;
  return {
    id: `postId-${setIndex}`,
    title: faker.lorem.words(),
    content: faker.lorem.lines(2),
    image: `${faker.image.animals()}?random=${Math.round(Math.random() * 1000)}`
  };
});

mock.onGet("/posts").reply(() => {
  try {
    const results = posts;
    return [200, results];
  } catch (error) {
    console.error(error);
    return [500, { message: "Internal server error" }];
  }
});
*/
function App() {
  const [posts, setPosts] = useState([]);
  
  const onClick = async (e) => {};
  
  return (
    <>
      <Button onClick={onClick} style={{ margin: "2rem" }}>
        버튼
      </Button>
      <Row>
        {posts?.map((post) => (
          <Col key={post.id}>
            <Card
              title={post.title}
              style={{
                margin: "2rem",
                width: "20rem"
              }}
            >
              <p>{post.content}</p>
              <img src={post.image} alt="img" style={{ width: "100%" }} />
            </Card>
          </Col>
        ))}
      </Row>
    </>
  );
}

export default App;

ui를 조금 더 빠르고 편리하게 디자인하기 위해 antd라이브러리를 사용했다.

Card는 카드 형식을 만들기 위해 사용했다.
Button은 디자인된 버튼이다.
Card, Col는 antd에서 사용되는 grid이다.

자세한 정보는 공식 사이트에 있다. => https://ant.design/components/overview/

5. 이벤트 넣기(완료)

/*
import React, { useState } from "react";
import axios from "axios";

import AxiosMockAdapter from "axios-mock-adapter";
import faker from "faker";

import "antd/dist/antd.css";
import { Card, Col, Row, Button } from "antd";

const mock = new AxiosMockAdapter(axios);

const posts = [...Array(23)].map((_, index) => {
  const setIndex = index + 1;
  return {
    id: `postId-${setIndex}`,
    title: faker.lorem.words(),
    content: faker.lorem.lines(2),
    image: `${faker.image.animals()}?random=${Math.round(Math.random() * 1000)}`
  };
});

mock.onGet("/posts").reply(() => {
  try {
    const results = posts;
    return [200, results];
  } catch (error) {
    console.error(error);
    return [500, { message: "Internal server error" }];
  }
});
function App() {
  const [posts, setPosts] = useState([]);
*/
  const onClickEvent = async (e) => {
  	const mockData = await axios.get("/posts");
    setPosts(mockData.data);
  };
/*
  return (
    <>
      <Button onClick={onClickEvent} style={{ margin: "2rem" }}>
        버튼
      </Button>
      <Row>
        {posts?.map((post) => (
          <Col key={post.id}>
            <Card
              title={post.title}
              style={{
                margin: "2rem",
                width: "20rem"
              }}
            >
              <p>{post.content}</p>
              <img src={post.image} alt="img" style={{ width: "100%" }} />
            </Card>
          </Col>
        ))}
      </Row>
    </>
  );
}

export default App;
*/

axios.get("/posts");을 통해 요청을 하면,
아까 우리가 만들어 주었던 mock.onGet("/posts")이 이를 받아 데이터를 반환한다.

따라서 이렇게 return 된 데이터를 setPosts(mockData.data);을 통해 posts에 저장시켜 주었다.

동작 영상

  1. 버튼 클릭
  2. 동물 사진첩 나타남.

전체 코드

import React, { useState } from "react";
import axios from "axios";
import "antd/dist/antd.css";
import { Card, Col, Row, Button } from "antd";
import AxiosMockAdapter from "axios-mock-adapter";
import faker from "faker";

let mock = new AxiosMockAdapter(axios);

let posts = [...Array(23)].map((_, index) => {
  const setIndex = index + 1;
  return {
    id: `postId-${setIndex}`,
    title: faker.lorem.words(),
    content: faker.lorem.lines(2),
    image: `${faker.image.animals()}?random=${Math.round(Math.random() * 1000)}`
  };
});

mock.onGet("/posts").reply(() => {
  try {
    const results = posts;
    return [200, results];
  } catch (error) {
    console.error(error);
    return [500, { message: "Internal server error" }];
  }
});

function App() {
  const [posts, setPosts] = useState([]);
  //console.log(posts);

  const onClick = async (e) => {
    e.preventDefault();
    const mockData = await axios.get("/posts");
    setPosts(mockData.data);
  };
  return (
    <>
      <Button onClick={onClick} style={{ margin: "2rem" }}>
        버튼
      </Button>
      <Row>
        {posts?.map((post) => (
          <Col key={post.id}>
            <Card
              title={post.title}
              style={{
                margin: "2rem",
                width: "20rem"
              }}
            >
              <p>{post.content}</p>
              <img src={post.image} alt="a" style={{ width: "100%" }} />
            </Card>
          </Col>
        ))}
      </Row>
    </>
  );
}

export default App;
profile
꾸준하게 공부하기

0개의 댓글