API와 서버와의 통신, JSON 서버나 Mock API로 데이터 연동

현대 웹 개발에서 클라이언트와 서버 간의 통신은 매우 중요한 부분입니다. 특히, 리액트(React)와 같은 프론트엔드 라이브러리를 사용할 때, API를 통한 데이터 요청과 처리는 매우 일반적인 작업이 됩니다. 이 글에서는 리액트를 사용하여 JSON 서버나 Mock API와 통신하는 방법을 깊이 있게 다루겠습니다.

1. API란 무엇인가?

API(응용 프로그램 프로그래밍 인터페이스, Application Programming Interface)는 소프트웨어 응용 프로그램 간의 통신을 위한 인터페이스입니다. API를 통해 서로 다른 시스템이 데이터를 주고받거나 기능을 호출하여 상호작용할 수 있습니다. 웹에서 사용하는 API는 일반적으로 REST(Representational State Transfer) 방식 또는 GraphQL 방식으로 생성됩니다.

2. JSON 서버란?

JSON 서버는 REST API를 쉽게 생성할 수 있도록 도와주는 도구입니다. 단순한 JSON 파일을 기반으로 RESTful API를 제공하며, 데이터를 CRUD(Create, Read, Update, Delete) 방식으로 관리할 수 있습니다. 이를 통해 프론트엔드 개발자는 쉽게 API와 상호작용할 수 있습니다.

2.1 JSON 서버 설치하기

JSON 서버는 Node.js에서 실행되므로, 먼저 Node.js가 설치되어 있어야 합니다. 그 후 다음 명령어를 통해 JSON 서버를 설치할 수 있습니다:

npm install -g json-server

2.2 JSON 파일 만들기

아래와 같은 형식의 db.json 파일을 생성합니다. 이 파일은 API에서 사용할 데이터의 저장소 역할을 합니다.

{
        "posts": [
            { "id": 1, "title": "첫 번째 포스트", "author": "홍길동" },
            { "id": 2, "title": "두 번째 포스트", "author": "김수빈" }
        ],
        "comments": [
            { "id": 1, "postId": 1, "body": "안녕하세요!" },
            { "id": 2, "postId": 2, "body": "좋은 하루 되세요!" }
        ]
    }

2.3 JSON 서버 실행하기

JSON 서버를 실행하려면 다음 명령어를 입력합니다:

json-server --watch db.json

이 명령어를 통해 로컬 서버가 시작되며, 기본적으로 http://localhost:3000에서 API에 접근할 수 있게 됩니다.

3. 리액트에서 API에 fetch하기

이제 JSON 서버가 실행 중이므로, 리액트 애플리케이션에서 API와 통신하는 방법을 살펴보겠습니다. 리액트 컴포넌트에서 데이터를 가져오기 위해 fetch API를 사용할 수 있습니다.

3.1 리액트 컴포넌트 생성하기

아래는 API로부터 데이터를 받아와서 표시하는 간단한 리액트 컴포넌트입니다:

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

    const Posts = () => {
        const [posts, setPosts] = useState([]);
        const [loading, setLoading] = useState(true);

        useEffect(() => {
            fetch('http://localhost:3000/posts')
                .then(response => response.json())
                .then(data => {
                    setPosts(data);
                    setLoading(false);
                })
                .catch(error => console.error('API 호출 중 오류 발생:', error));
        }, []);

        if (loading) {
            return 
로딩 중...
; } return (

게시글 목록

    {posts.map(post => (
  • {post.title} - {post.author}
  • ))}
); }; export default Posts;

3.2 설명

위의 컴포넌트는 useEffect 훅을 사용하여 컴포넌트가 마운트될 때 API를 호출합니다. fetch 함수를 사용하여 http://localhost:3000/posts URL에서 데이터를 가져오고, 받은 데이터는 setPosts를 통해 상태에 저장합니다. 로딩 상태는 loading 변수를 통해 관리되며, 데이터가 로딩 중일 때 로딩 메시지를 보여주고, 데이터가 모두 로드되면 리스트를 출력합니다.

4. Mock API 사용하기

실제 API를 사용하기 전에 Mock API를 사용하는 것은 매우 유용합니다. Mock API는 실제 서버와 유사한 방식으로 작동하지만, 즉시 구현할 수 있는 APIs입니다. Postman, Mocky, MirageJS와 같은 도구가 있습니다.

4.1 MirageJS 예제

MirageJS는 프론트엔드 개발자들이 테스트와 개발을 위한 API를 설정하는 데 유용합니다. Mirage를 사용하여 API를 설정하는 방법을 살펴보겠습니다.

import { createServer } from 'miragejs';

    createServer({
        routes() {
            this.namespace = 'api';

            this.get('/posts', () => {
                return [
                    { id: 1, title: "Mock API 게시글 1", author: "이순신" },
                    { id: 2, title: "Mock API 게시글 2", author: "박지성" }
                ];
            });
        }
    });

위 코드를 애플리케이션의 엔트리 파일에 추가하면, MirageJS가 설정한 Mock API가 http://localhost:3000/api/posts 경로에서 요청을 받을 수 있습니다. 이제 이전에 작성한 Posts 컴포넌트에서 URL을 변경해주면 Mock API와 통신할 수 있습니다.

4.2 실제 예제와의 비교

MirageJS와 같은 Mock API 기술을 사용하면, 서버가 준비되지 않았더라도 테스트를 할 수 있다는 장점이 있습니다. 또한, Mock API를 사용하면 상호작용과 상태 관리를 더 유연하게 처리할 수 있어 프론트엔드 개발 속도를 높일 수 있습니다.

5. 데이터 업데이트와 삭제

CRUD 작업은 API에서의 기본적인 데이터 처리 방식입니다. 앞에서 작성한 리액트 컴포넌트에서 데이터를 업데이트하고 삭제하는 방법을 알아보겠습니다.

5.1 데이터 업데이트

아래의 코드는 특정 게시글을 업데이트하는 방법을 보여줍니다. fetch 함수에서 PUT 요청을 사용하여 데이터 업데이트 작업을 수행합니다.

const updatePost = (postId, updatedContent) => {
        fetch(`http://localhost:3000/posts/${postId}`, {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(updatedContent)
        })
        .then(response => response.json())
        .then(updatedPost => {
            // 상태 업데이트 로직
        })
        .catch(error => console.error('게시글 업데이트 오류:', error));
    };

5.2 데이터 삭제

삭제 작업은 DELETE 메소드를 사용하여 수행할 수 있습니다. 아래는 특정 게시글을 삭제하는 예시입니다:

const deletePost = (postId) => {
        fetch(`http://localhost:3000/posts/${postId}`, {
            method: 'DELETE'
        })
        .then(() => {
            // 상태 업데이트 로직
        })
        .catch(error => console.error('게시글 삭제 오류:', error));
    };

6. 결론

리액트에서 API와의 통신을 통해 다양한 데이터를 처리하는 방법을 알아보았습니다. JSON 서버와 같은 진입 장벽이 낮은 도구를 사용하면 개발 초기 단계에서 빠르게 프로토타입을 생성할 수 있으며, Mock API를 통해 실제 API가 개발되기 전에도 유용한 테스트를 진행할 수 있습니다. 이러한 기법들은 프론트엔드 개발의 효율성을 크게 향상시킬 것입니다.

추가 학습자료

이 글이 리액트 및 API의 이해에 도움이 되었기를 바라며, 향후 또 다른 주제로 더욱 심도 깊은 내용을 다룰 수 있기를 기대합니다.