Axios를 이용해서 API서버와 통신해보자

lovjgb·2022년 8월 5일
0
post-custom-banner

Axios를 이용해서 API서버와 통신해보자

Axios란?

  • JavaScript의 라이브러리중 하나로 Asynchronous(비동기) Javascript(자바스크립트) And  Xml(비동기식 자바스크립트와 xml)의 약자이다.
  • 브라우저가 가진 XMLHttpRequest객체를 이용한 전체 페이지를 새로 고치지 않고도 페이지의 일부만을 위한 데이터를 로드하는 기법
  • Javascript를 사용한 통신, 클라이언트와 서버간에 XML 데이터를 주고받는 기술이다.
  • 정리하면, 자바스크립트를 통해서 서버에 데이터를 요청하는 것
  • 다른말로 정리하면, node.js와 브라우저를 위한 Promise 기반 http 클라이언트이다.
  • http를 이용해서 서버와 통신하기 위해 사용하는 패키지이다.
  • 먼저 Get 과 Post 의 반환값은 Promise 객체이다.
  • JSON 데이터 자동 변환
    • 일반적으로 Fetch API를 사용할 경우, HTTP 요청을 보내고 그 응답을 받아옵니다. 이때 받아온 응답은 Response 객체라는 형태를 가지게 됩니다. 그렇기에 json()메서드를 호출하여 응답 본문의 내용을 Javascript객체로 변환해야 한다.
      - 하지만 Axios를 사용하면 JSON데이터를 자동 변환 해주므로 json()를 사용하지 않아도 된다. 바로 data를 사용할 수 있다.
      https://axios-http.com/docs/res_schema
    // fetch를 사용하는 경우는 아래와 같이 작성했어야 됐다.
    fetch('/api/todos')
    .then(res => res.json())
    .then(todos => console.log(todos))
    .catch(err => console.error(err));
    		```
  • 사용 방법
    • 설치
      • npm i axios
    • axios 임포트
  • 1.GET
axios.get(url,[,config])
    1. POST
axios.post("url주소",{
data객체
},[,config])
  • 3 DELETE
axios.delete(url,[,config]);
  1. PUT
axios.put(url[, data[, config]])

https://koras02.tistory.com/48

  • 아래에서 예습을 해봅시다.

1. GET

  • GET 요청은 https://haneulsunny.tistory.com/30 링크 절차를 밟으면 끝
  • 우리가 컴포넌트에서 사용할때 GET 요청으로 작성될 코드 형식은 아래와 같다.
// url에는 서버의 url이 들어가고, config에는 기타 여러가지 설정을 추가할 수 있습니다.
// config는 axios 공식문서에서 확인하세요.
axios.get(url\[, config\]) // GET

json-server API 명세서 확인

  • 전체 정보나 상세 정보
    • path variable로 url을 작성한다.
    • 예시)
  • filter와 같은 기능을 위해서 GET요청을 하고자 할 때
    - query로 보낸다.
    - 예시)
  • 코드로 보는 예시
    • 아래 예시는 json-server에 있는 todos를 axios를 이용해서 fetching하고 useState를 통해서 관리하는 로직이다.
    • 테스트용 db 상태는 먼저, 아래와 같다.
//db.json - 테스트용 db
{
  "todos": [
    {
      "id": "1",
      "title": "react"
    }
  ]
}
  • App.js 코드는 아래와 같다.
// src/App.js

import React, { useEffect, useState } from "react";
import axios from "axios"; // axios import 합니다.

const App = () => {
  const [todos, setTodos] = useState(null);

    // axios를 통해서 get 요청을 하는 함수를 생성합니다.
    // 비동기처리를 해야하므로 async/await 구문을 통해서 처리합니다.
  const fetchTodos = async () => {
    const { data } = await axios.get("http://localhost:3001/todos");
    setTodos(data); // 서버로부터 fetching한 데이터를 useState의 state로 set 합니다.
  };

    // 생성한 함수를 컴포넌트가 mount 됐을 떄 실행하기 위해 useEffect를 사용합니다.
  useEffect(() => {
        // effect 구문에 생성한 함수를 넣어 실행합니다.
    fetchTodos();
  }, []);

    // data fetching이 정상적으로 되었는지 콘솔을 통해 확인합니다.
  console.log(todos); // App.js:16
  //db.json에 기재했었던 {id: '1', title: 'react'} 가 콘솔 창에 뜬다.
  return <div>App</div>;
};

export default App;

POST

Axios POST

  • post는 보통 서버에 데이터를 추가할 때 사용한다.

  • 다만, post 요청에 대한 로직은 BE 개발자가 구현하는 것이기때문에 추가외에 다른 용도로 사용될 수 있지만, 보통은 클라이언트의 데이터를 body형태로 서버에 보내고자 할 때 사용한다.

  • 우리가 컴포넌트에서 사용할때 POST 요청으로 작성될 코드 형식은 아래와 같다.

    axios.post(url[, data[, config]]) // POST
  • 코드로 보는 예시

    • 아래 예시는 인풋 창에 값을 입력하고, 버튼을 클릭했을 때 그 내용물을 body에 담아 서버로 POST요청을 보내는 예시이다.
    • 위에서 작성했던 get코드 예시는 그대로 두고, todo라는 usestate를 새로 만들어서 post연결을 해본 예시코드이다.
// src/App.jsx      
// src/App.jsx

import React, { useEffect, useState } from "react";
import axios from "axios"; // axios import 합니다.

const App = () => {
  // 새롭게 생성하는 todo를 관리하는 state
  const [todo, setTodo] = useState({
    title: "",
  });

  const [todos, setTodos] = useState(null);

  const fetchTodos = async () => {
    const { data } = await axios.get("http://localhost:3001/todos");
    setTodos(data);
  };

  const onSubmitHandler = (todo) => {
    axios.post("http://localhost:3001/todos", todo);
  };

  useEffect(() => {
    fetchTodos();
  }, []);

  return (
    <>
      <form
        onSubmit={(e) => {
					// 👇 submit했을 때 브라우저의 새로고침을 방지합니다. 
          e.preventDefault();
          onSubmitHandler(todo);
        }}
      >
        <input
          type="text"
          onChange={(ev) => {
            const { value } = ev.target;
            setTodo({
              ...todo,
              title: value,
            });
          }}
        />
        <button>추가하기</button>
      </form>
      <div>
        {todos?.map((todo) => (
          <div key={todo.id}>{todo.title}</div>
        ))}
      </div>
    </>
  );
};

export default App;
  • 새로고침을 해보면 아래와 같은 이미지 상태가 된다.

  • 인풋 창에 내용을 입력하고 추가하기를 누르면?
    • db.json에 내용 추가!
    • 하지만, 화면은 바로 업데이트가 되지 않고 있다!

  • 새로고침을 해보자
    • 잘 추가된 것을 알 수 있다.
    • 우리가 이것을 새로고침을 하지 않고도 하는 방법은? return에 뿌려주는 걸 하면 되겠지요~

네트워크 탭 확인하기

  • Response값은 자동으로 생성되는 것이 아니라, FE 개발자가 BE 개발자에게 요청한 것을 직접 개발을 해야 생기는 값이다.
  • 아래에 나와 있는 statuscode는 BE개발자가 설정해야만 브라우저에서 볼 수 있다.(문맥과 다른 내용이 나올 수도 있다.)
  • 그 밖에도 request headers와 response headers 정보가 추가적으로 있다. 이 부분은 각 항목들이 어떤 것을 우리게 보여주는지 더 알아보면 좋다.

DELETE

Axios Delete

  • DELETE는 저장되어 있는 데이터를 삭제하고자 요청을 보낼 때 사용
axios.delete(url[, config])  // DELETE

코드 예시

// src/App.jsx

import React, { useEffect, useState } from "react";
import axios from "axios"; 

const App = () => {
  const [todo, setTodo] = useState({
    title: "",
  });

  const [todos, setTodos] = useState(null);

  const fetchTodos = async () => {
    const { data } = await axios.get("http://localhost:3001/todos");
    setTodos(data); 
  };

  const onSubmitHandler = (todo) => {
    axios.post("http://localhost:3001/todos", todo);
  };

	// 새롭게 추가한 삭제 버튼 이벤트 핸들러 
  const onClickDeleteButtonHandler = (todoId) => {
    axios.delete(`http://localhost:3001/todos/${todoId}`);
  };

  useEffect(() => {
    fetchTodos();
  }, []);

  return (
    <>
      <form
        onSubmit={(e) => {
          e.preventDefault();
          onSubmitHandler(todo);
        }}
      >
        <input
          type="text"
          onChange={(ev) => {
            const { value } = ev.target;
            setTodo({
              ...todo,
              title: value,
            });
          }}
        />
        <button>추가하기</button>
      </form>
      <div>
        {todos?.map((todo) => (
          <div key={todo.id}>
            {todo.title}
            {/*  디자인이 요상하긴 하지만..! 삭제 버튼 추가 */}
            <button
              type="button"
              onClick={() => onClickDeleteButtonHandler(todo.id)}
            >
              삭제하기
            </button>
          </div>
        ))}
      </div>
    </>
  );
};

export default App;
  • 삭제하기 버튼 클릭 시 동일하게 바로 업데이트는 되지 않는다.

PATCH

(1) Axios patch

  • patch는 보통 어떤 데이터를 수정하고자 서버에 요청을 보낼 때 사용하는 메서드
axios.patch(url[, data[, config]])  // PATCH
  • 예시코드
    • 필요 데이터 : todo의 id, 수정하고자 하는 값
    • 아래 예시는 간단한 예시로, id를 넘겨줘서 처리하는 방식으로 간단하게 구현하였다(실제론 이렇게 id를 입력하지 않는다)
// src/App.jsx

import React, { useEffect, useState } from "react";
import axios from "axios";

const App = () => {
  const [todo, setTodo] = useState({
    title: "",
  });
  const [todos, setTodos] = useState(null);

  // patch에서 사용할 id, 수정값의 state를 추가
  const [targetId, setTargetId] = useState(null);
  const [editTodo, setEditTodo] = useState({
    title: "",
  });

  const fetchTodos = async () => {
    const { data } = await axios.get("http://localhost:3001/todos");
    setTodos(data);
  };

  const onSubmitHandler = (todo) => {
    axios.post("http://localhost:3001/todos", todo);
  };

  const onClickDeleteButtonHandler = (todoId) => {
    axios.delete(`http://localhost:3001/todos/${todoId}`);
  };

  // 수정버튼 이벤트 핸들러 추가 👇
  const onClickEditButtonHandler = (todoId, edit) => {
    axios.patch(`http://localhost:3001/todos/${todoId}`, edit);
  };

  useEffect(() => {
    fetchTodos();
  }, []);

  return (
    <>
      <form
        onSubmit={(e) => {
          e.preventDefault();
          onSubmitHandler(todo);
        }}
      >
        {/* 👇 수정기능에 필요한 id, 수정값 input2개와 수정하기 버튼을 추가 */}
        <div>
          <input
            type="text"
            placeholder="수정하고싶은 Todo ID"
            onChange={(ev) => {
              setTargetId(ev.target.value);
            }}
          />
          <input
            type="text"
            placeholder="수정값 입력"
            onChange={(ev) => {
              setEditTodo({
                ...editTodo,
                title: ev.target.value,
              });
            }}
          />
          <button
						{/* type='button' 을 추가해야 form의 영향에서 벗어남 */}
            type="button"
            onClick={() => onClickEditButtonHandler(targetId, editTodo)}
          >
            수정하기
          </button>
        </div>
        <input
          type="text"
          onChange={(ev) => {
            const { value } = ev.target;
            setTodo({
              ...todo,
              title: value,
            });
          }}
        />
        <button>추가하기</button>
      </form>
      <div>
        {todos?.map((todo) => (
          <div key={todo.id}>
						{/* todo의 아이디를 화면에 표시 */}
            {todo.id} :{todo.title}
            <button
              type="button"
              onClick={() => onClickDeleteButtonHandler(todo.id)}
            >
              삭제하기
            </button>
          </div>
        ))}
      </div>
    </>
  );
};

export default App;

https://www.npmjs.com/package/json-server

profile
lovjgb
post-custom-banner

0개의 댓글