본문 바로가기
서버/AJAX

AJAX 요청 (React, 기본문법)

by whale in milktea 2023. 3. 5.

용어 및 관계 정리

먼저 HTTP, RESTful API, AJAX 이 3가지 서버와 관련된 통신들이 너무나 헷갈리기에 이에 관해 먼저 정리하고 각 개념을 카테고리로 묶어 정리하고자 한다.

HTTP HTTP는 인터넷에서 데이터를 전송하는데 사용되는 프로토콜이다. 

* 프로토콜(Protocal) : 2개 이상의 컴퓨터가 서로 데이터를 주고 받을 때 (통신할 때), 사용되는 규칙 혹은 규약이다.

즉 HTTP는 아주 단순하게 2개 이상의 컴퓨터가 통신할 때 규칙이나 규약이 정해져 있지 않고 제각기 통신하게 되면 이를 분석하고 핵심 내용을 파악하는데 시간이 너무 오래걸리거나 혹은 통신이 불가능해지기 때문에 "인간"이 규칙이나 약속을 정해놔서 원활하게 통신할 수 있도록 정해놓은 것이다.
RESTful API RESTful API는 HTTP 프로토콜을 기반으로 하는 웹 서비스 아키텍쳐 스타일 중 하나다.

즉, HTTP를 기반으로 한 웹 서비스 아키텍쳐 스타일은 이 외에도 다양할 것이지만(client-server architecutre/microservice architecture etc...), 가장 효과적인 모형이 RESTful API이기에 이를 채택하는 것이다.

* 웹 아키텍쳐 스타일 : HTTP 메소드(GET, PUT, POST, DELETE, OPTION 등)를 활용하여 서버와 클라이언트가 통신하는 모형
AJAX AJAX는 클라이언트에서 비동기로 서버와 통신하며 데이터를 가져오는 기술이다.

AJAX의 주요한 특징으로는, 1) 비동기로 서버와 통신한다. 2) 리렌더링 없이 서버에서 가져온 데이터를 반영할 수 있다. 는 2가지로 볼 수 있다.

즉, AJAX는 실제 코드에서 통신규약과 모형을 반영한 통신기술을 구현한 것으로 이해할 수 있다.

AJAX란?

AJAX(Asynchronous Javascript and XML)는 이름에서도 알 수 있듯, 비동기적으로 서버와 브라우저 간의 데이터를 주고 받는 기술을 말한다. 따라서, JS를 지원하는 모든 브라우저에서 AJAX를 활용하여 서버와 통신할 수 있으며, 비동기적으로 통신하기에 굳이 웹을 리렌더링 하지 않아도 웹에 표시되는 정보를 업데이트 할 수 있다는 장점이 있다.

 

이름에서 보이는 XML이란, 다목적 마크업 언어로, 데이터를 저장하고 전송하기 위한 형식을 말한다. 즉, 기본적으로 렌더링된 페이지는 트리 형식의 마크업 언어인 HTML로 표시되는데 이를 일정한 형식에 맞춰 재구성하여 브라우저와 서버 간의 통신이 가능하도록 재구조화된 것이 XML이라고 할 수 있다.

 

이러한 XML은 다음과 같은 특징을 갖는다.

태그를 사용하여 데이터의 구조와 의미를 나타낸다.
데이터와 메타데이터를 분리하여 저장한다.
데이터의 형식을 자유롭게 정의할 수 있다. (String, Integer, Float, Date, Time, Boolean  등)
확장성이 뛰어나며, 새로운 태그를 정의하여 사용할 수 있다.
플랫폼과 언어에 독립적이며, 다양한 시스템 간의 데이터 교환에 사용된다.

 

AJAX는 JS를 기본 언어로 갖는 모든 라이브러리에서 사용할 수 있는 만큼, 라이브러리에 따라 사용하는 구조가 조금씩 다르다. 본인은 React 프론트엔드 개발자를 희망하기 때문에, React에서 useEffect를 활용한 AJAX 요청을 살펴보고자 한다.

사전 셋팅
1. 효율적인 코드 작성을 위해 axios 라이브러리를 사용했다.
2. create-react-app으로 react 프로젝트를 생성하고, 불필요한 파일을 정리했다.

 

React.js에서의 AJAX 주요 요청 예시!

import "./App.css";
import axios from "axios";
import { useEffect } from "react";

function App() {
  const [data, setData] = useState([]);

  // 현재 데이터에는 아래와 같은 데이터가 저장되어 있다고 가정한다.
  // POSTMAN으로 http://example.com/api/data에 GET 요청을 보내면 다음과 같은 응답이 전달된다.
  // "data" : [
  //   {
  //     "id": 1,
  //     "name": "brian",
  //   },
  //   {
  //     "id": 2,
  //     "name": "peter",
  //   },
  // ];

  // React에서는 코드 실행 중 발생하는 변화 외에 다른 변화를 뜻하는 Side Effect를 제어하기 위해 useEffect Hook을 사용하기에 이를 활용했다.
  useEffect(() => {
    axios
      .get("http://example.com/api/data") // get요청으로 원하는 데이터를 요청한다.
      .then((res) => {
        // res 변수에 data를 담고
        setData(res.data); // res 변수에 담긴 data 객체에 접근한 뒤 setData에 담아 상태를 업데이트한다.
      })
      .catch((err) => {
        alert(`올바르지 못한 요청입니다 내용 : ${err}`); // 만약,
      });
  }, []);

  useEffect(() => {
    axios
      .put("http://example.com/api/data", { id: 3, name: "Haseong" }) // put 요청으로 변경하고자 하는 데이터를 전달한다.
      .then((res) => setData(res.data)) // 업데이트 된 내용을 setdata에 담아 상태를 변경시켜준다.
      .catch((err) => alert(`올바르지 못한 요청입니다 내용 : ${err}`));
  }, []);

  useEffect(() => {
    axios
      .delete("http://example.com/api/data/3") // put 요청으로 삭제하고자 하는 데이터를 전달한다.
      .then((res) => setData(res.data)) // 정상적으로 처리되었을 경우, setdata에 담아 상태를 변경시켜준다.
      .catch((err) => alert(`올바르지 못한 요청입니다 내용 : ${err}`));
  }, []);

  // fetch를 활용하여 PATCH 메서드로 요청을 보내는 경우
  useEffect(() => {
    fetch("http://example.com/api/data/1", { // axios와 동일하게 주소를 입력한다.
      method: "PATCH",
      headers: {
        "Content-Type": "application/json", // JSON 타입으로 보냄을 명시한다.
      },
      body: JSON.stringify({ name: john }), // id가 1인 객체에 들어있는 name : "brian"이 name : "john"으로 대치된다.
    })
    .then(res => res.json())
    .then(data => setData(data))
    .catch(err => alert(`올바르지 못한 요청입니다 내용 : ${err}`))
  });
    // 위의 JSON.stringify는 JSON 문자열을 자바스크립트 객체로 변환시키기 위한 코드인데,
    // JSON 문자열과 자바스크립트 객체는 얼핏보기에는 비슷하지만 전혀 다른 모양을 갖고 있다.
    // JSON 문자열 : { "name": "John", "age": 30, "city": "New York" }
    // 자바스크립트 객체 : { name: 'John', age: 30, city: 'New York' }

  return (
    <>
      <div>Ajax를 연습해보자!</div>
      {data.map(
        (
          item // 업데이트 된 데이터를 매개변수 item에 할당하고,
        ) => (
          <div key={item.id}>{item.name}</div> // 데이터 중 원하는 내용을 div 내용으로 출력한다.
        )
      )}
    </>
  );
}

export default App;