REST API using Axios

zzwwoonn·2022년 5월 25일
0

Web Front

목록 보기
13/13

REST API란 REST를 기반으로 만들어진 API를 말한다.

REST API

REST
REST는 Representational State Transfer 의 약자로 자원을 이름으로 구분하여 해당 자원의 상태를 주고받는 모든 것이다.

API
API는 Application Programming Interface의 약자로 소프트웨어가 다른 소프트웨어로 지정된 형식으로 요청, 명령을 받을 수 있는 수단이다.

=> 네트워크 상에서만 API가 있는 것은 아니다. 단적인 예로 로컬 프로그램인 브라우저(크롬, 사파리)는 Web API를 통해 자바스크립트로부터 특정 동작을 지시받는다.

REST 구성요소

  1. 자원(Resource) : HTTP URI
  2. 자원에 대한 행위 (Verb) : HTTP Method
  3. 자원에 대한 행위의 내용(Representations): HTTP Message Pay Load

쉽게 말하면

  1. HTTP URI를 통해 자원(Resource)를 명시하고 (어디서 작업 할건지)
  2. HTTP Method(POST, GET, PUT, DELETE)를 통해서
  3. 해당 자원(URI)에 대한 CRUD Operation을 적용하는 것 (어떤 작업 할건지)

CRUD Operation
CRUD는 대부분의 컴퓨터 소프트웨어가 가지는 기본적인 데이터 처리 기능인 Create(생성), Read(읽기), Update(갱신), Delete(삭제)를 묶어서 일컫는 말

REST에서의 CRUD Operation 동작 예시는 다음과 같다.

  • Create : 데이터 생성(POST)
  • Read : 데이터 조회(GET)
  • Update : 데이터 수정(PUT)
  • Delete : 데이터 삭제(DELETE)

추가로 PATCH

PUT 과 PATCH은 거의 유사하다. 보통 PUT으로 다 처리하긴 하지만 정석대로는 조금 차이가 있다.
PUT은 정보를 통째로 갈아 끼울 때
ex> 이름 : 서지원, 성별 : 남자, 나이 25 => 이름 : 이채원, 성별 : 여자, 나이 : 24
PATCH는 정보 중 일부를 특정 방식으로 변경할 때
ex> 이름 : 서지원, 성별 : 남자, 나이 25 => 이름 : 서지투, 성별 : 남자, 나이 25

REST API는 특정 기술이나 제품이 아니라 그저 "형식"일 뿐이기 때문에 어떤 프로그래밍 언어를 쓰던, 무슨 프레임워크를 쓰던, 어디다가 만들던 상관없이 REST API 폼에만 맞춰주면 되는 것이다.

REST의 특징

  1. Server-Client(서버-클라이언트 구조)
  2. Stateless(무상태)
  3. Cacheable(캐시 처리 가능)
  4. Layered System(계층화)
  5. Uniform Interface(인터페이스 일관성)

REST-ful

RESTFUL이란 REST의 원리를 따르는 시스템을 의미한다. 하지만 REST를 썼다고 해서 전부 RESTful 한건 아니다. REST API의 설계 규칙을 올바르게 지킨 시스템을 RESTful하다 말할 수 있으며 모든 CRUD 기능을 POST로 처리 하거나(보통의 경우 이러하다) 또는 URI 규칙을 올바르게 지키지 않았을 경우는 REST API를 사용하였지만 REST-ful 하지 못한 시스템이다.

실습

axios

Axios는 브라우저, Node.js를 위한 Promise API 기반 HTTP 비동기 통신 라이브러리이다. 쉽게 말해서 백엔드랑 프론트엔드랑 통신을 쉽고 간편하게 하기 위해 Ajax와 더불어 사용한다.

이미 자바스크립트에는 fetch api가 있지만, 프레임워크(리액트)에서 ajax를 구현할땐 axios를 쓰는 편이라고 보면 된다.

Axios 와 fetch 의 차이점

출처 - Dev Scroll

먼저 리액트에서 API를 호출할때에는 axios라는 라이브러리가 필요하다.
axios 라이브러리를 먼저 설치해주자.

$ npm install axios

기본 문법

axios({
  url: 'https://test/api/cafe/list/today', 
  // 통신할 웹문서
  method: 'get', 
  // 통신할 방식, get 방식이 기본값(default)이다.
  data: { 
    foo: 'diary'
  }
  // 인자로 보낼 데이터
});

실제로는 어떻게 사용하는지 아래의 실습 코드를 통해 확인해보자

실습 코드 -1

// App.js

import React from 'react';
import Users from './Users'
import UsersUsingBtn from './UsersUsingBtn'

function App() {
  return (
    <React.Fragment>
      <Users/>
    {/* <UsersUsingBtn/> */}
    </React.Fragment>
  );
}

export default App;

// <UsersUsingBtn/> 는 바로 아래서 다시 보자
// Users.jsx

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

function Users() {
    const [users, setUsers] = useState(null);
    // users 데이터 -> state로 관리

    const [loading, setLoading] = useState(false);
    // 로딩 중인지 아닌지 체크

    const [error, setError] = useState(null);
    // 에러 발생 여부 체크

    useEffect(() => {
        console.log("come in useEffect")
        const fetchUsers = async () => {
            try {
                console.log("try request")
                // 요청 시작 할 때 error 와 users 를 초기화
                setError(null);
                setUsers(null);
                setLoading(true);
                // 아직 요청 보내기 전(시작) => loading : true 

                const response = await axios.get(
                    // GET 으로는 안된다. 이거 때메 30분 삽질
                    // get 으로 해야함
                    'https://jsonplaceholder.typicode.com/users'
                );
                // 요청 보내놨고, 제대로 왔으면 response 에 있겠지  => await 다 될 때까지 기다려
                // get 으로 보냄

                setUsers(response.data); 
                // 데이터는 response.data 안에 들어있지 
                // 그거를 user state 에다가 넣어놔
                // 그럼 결론적으로 통신이 잘 되서 데이터 잘 받아왔으면 user 에 들어가있겠지

            } catch (e) {
                console.log(e)
                setError(e);
                // 에러 발생 했으면 바로 캐치해서 state 값 설정
            }
            // try, catch 끝나고나서
            
            setLoading(false);
            // 다 받아왔으니까 loading : false
        };

        // 1. useEffect 뒤에 인자가 없으니까 바로 실행
        // 2. fetchUsers 바로 실행
        // 3. fetchUsers 안으로 바로 들어가 => get 보내겠지

    fetchUsers();

    }, []);
    // 아무것도 안넣어줬어 => 처음 웹 렌더링 될 때 바로 실행

    // useEffect 실행하고 나서 바로 밑에 문장들 순서대로 수행

    if (loading) 
        return <div>로딩중..</div>;
        // loading state 보고 True 면 => 통신하는 도중

    if (error) 
        return <div>에러가 발생했습니다</div>;
        // error state 보고 True 면 => 통신하는 과정에서 에러
    if (!users) 
        return null;
        // 데이터 받아왔는데 만약에 아무것도 없으면 => 받아오긴 했는데 아무것도 없다는 소리 

    return (
        <React.Fragment>
            {/* <> </> 으로 대체가능 */}

            <h1>Axios Example</h1>

            <ul>
                {users.map(user => (
                    <li key={user.id}>
                        {user.username} ({user.name})
                    </li>
                ))}
            </ul>
        </React.Fragment>
    );
}

export default Users;

실행 결과 -1

웹이 렌더링 되자마자 바로 데이터가 뜨는 것을 볼 수 있다.
(인터넷이 조금.. 느리다면? 로딩중.. 이라는 문구가 뜰 수도 있다)

조금 더 심화 과정으로 만약 특정 버튼을 눌렀을 때 요청을 보내고 그 때 받아온 정보를 띄워주고 싶다면? (데이터가 있을 때와 없을 때를 구분하여)

실습 코드 -2

// App.js

import React from 'react';
import Users from './Users'
import UsersUsingBtn from './UsersUsingBtn'

function App() {
  return (
    <React.Fragment>
      {/* <Users/> */}
      <UsersUsingBtn/>
    </React.Fragment>
  );
}

export default App;

UsersUsingBtn 를 활성화 시켜주고

// UsersUsingBtn.jsx

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

function UsersUsingBtn() {
    const [users, setUsers] = useState(null);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);

    const fetchUsers = async () => {
        try {
            setError(null);
            setUsers(null);
            setLoading(true);

            const response = await axios.get(
                'https://jsonplaceholder.typicode.com/users'
            );

            setUsers(response.data); 

        } catch (e) {
            console.log(e)
            setError(e);
        }        
        setLoading(false);
    };

    if (loading) 
        return <div>로딩중..</div>;

    if (error) 
        return <div>에러가 발생했습니다</div>;

    return (
        <>
            {users ?
                <> 
                    <h1>받아온 데이터</h1>
                    <ul>
                        {users.map(user => (
                            <li key={user.id}>
                                {user.username} ({user.name})
                            </li>
                        ))}
                    </ul>
                </>
                :
                <>
                    <h1>Axios Example using Btn</h1>
                    <button onClick={fetchUsers}> 데이터 불러오기</button>
                </>
            }          
        </>
    );
}

export default UsersUsingBtn;

가독성을 높이기 위해 주석은 모두 제거하였다.

실행 결과 -2

데이터 불러오기 버튼을 누르면?

잠시 0.1초 정도 로딩중.. 이 뜨고 나서

0개의 댓글