본문 바로가기
Front/React.js

Next.js / React axios 호출 비교

by abstract.jiin 2025. 3. 18.

React, Vue.js 같은 순수 클라이언트 사이드 프레임워크

클라이언트(브라우저) → 백엔드 서버 (직접 호출)

React 애플리케이션은 브라우저에서 실행되고,
컴포넌트 내에서 Axios나 fetch를 사용해 직접 백엔드 API를 호출

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

function UserList() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    // 직접 백엔드 API 호출
    axios.get('https://api.backend-server.com/users')
      .then(response => {
        setUsers(response.data);
      })
      .catch(error => {
        console.error('Error fetching users:', error);
      });
  }, []);

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

Next.js 같은 서버 사이드 렌더링(SSR) 프레임워크

Next.js는 React 기반의 웹 프레임워크로, 서버 사이드 렌더링(SSR), 정적 사이트 생성(SSG), 클라이언트 사이드 렌더링(CSR) 등 다양한 렌더링 방식을 지원, React 애플리케이션 개발을 더 쉽고 효율적으로 만들어주는 기능 제공

클라이언트(브라우저) → 프론트엔드 서버 → 백엔드 서버

  • API 라우트 기능을 제공 : 프론트엔드 서버 내에서 백엔드 API를 호출 가능
  • 클라이언트에서 직접 백엔드 호출도 가능함. 단, SSR 장점을 활용하기 위해 서버 컴포넌트나 API 라우트 사용을 권장하고 있음
// pages/api/users.js (또는 app/api/users/route.js)
import axios from 'axios';

export default async function handler(req, res) {
  try {
    // Next.js 서버에서 백엔드 API 호출
    const response = await axios.get('https://backend-api.com/users');
    res.status(200).json(response.data);
  } catch (error) {
    res.status(500).json({ error: 'Failed to fetch users' });
  }
}

// 클라이언트 컴포넌트
function UserList() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    // Next.js API 라우트 호출 (프론트엔드 서버 경유)
    axios.get('/api/users')
      .then(response => {
        setUsers(response.data);
      });
  }, []);

  return (/* 렌더링 코드 */);
}

Next.js에서는 "프론트엔드 서버를 거치는지 여부"는 개발자의 구현 방식에 따라 달라짐

Next.js의 서버 기능을 활용하면 프론트엔드 서버가 중개자 역할을 할 수 있고, 클라이언트 컴포넌트에서는 백엔드를 직접 호출할 수도 있음


참고 사례 ****
https://dahna.tistory.com/60

+ 추가 사항

  • getServerSideProps나 API 라우트를 통해 프론트엔드 서버에서 백엔드 서버로 요청을 보내고 결과를 클라이언트에 전달
  • Next.js 13에서 더 간결한 사용 가능

getServerSideProps (Next가 제공 함수)

클라이언트 → Next.js 서버 → 백엔드 API → Next.js 서버 → 클라이언트

  • 코드

      // pages/users.js
      import axios from 'axios';
    
      export default function UsersPage({ users }) {
        return (
          <div>
            <h1>사용자 목록</h1>
            <ul>
              {users.map(user => (
                <li key={user.id}>{user.name}</li>
              ))}
            </ul>
          </div>
        );
      }
    
      export async function getServerSideProps() {
        try {
          // Next.js 서버에서 백엔드 API 호출
          const response = await axios.get('https://api.backend-server.com/users');
    
          // 백엔드에서 받은 데이터를 페이지 컴포넌트에 props로 전달
          return {
            props: {
              users: response.data
            }
          };
        } catch (error) {
          console.error('Error fetching users:', error);
          return {
            props: {
              users: []
            }
          };
        }
      }

API 라우트

클라이언트 → Next.js API 라우트 → 백엔드 API → Next.js API 라우트 → 클라이언트

  • 코드

      // pages/api/users.js
      import axios from 'axios';
    
      export default async function handler(req, res) {
        try {
          // 요청 메서드 확인 (선택적)
          if (req.method !== 'GET') {
            return res.status(405).json({ message: 'Method not allowed' });
          }
    
          // 클라이언트로부터 받은 쿼리 파라미터 활용 (선택적)
          const { limit } = req.query;
    
          // Next.js 서버에서 백엔드 API 호출
          const response = await axios.get(`https://api.backend-server.com/users?limit=${limit || 10}`, {
            // 백엔드 인증이 필요한 경우 헤더 추가
            headers: {
              'Authorization': `Bearer ${process.env.API_KEY}` // 환경 변수 사용
            }
          });
    
          // 응답 데이터 가공 (선택적)
          const processedData = response.data.map(user => ({
            id: user.id,
            name: user.name,
            // 민감한 정보 필터링
            email: user.email.replace(/(?<=.).(?=.*@)/g, '*')
          }));
    
          // 가공된 데이터를 클라이언트에 전송
          res.status(200).json(processedData);
        } catch (error) {
          console.error('Error fetching users:', error);
    
          // 에러 처리 및 클라이언트에 에러 응답
          res.status(error.response?.status || 500).json({
            message: error.response?.data?.message || 'Internal server error'
          });
        }
      }
    
      // 클라이언트 컴포넌트에서의 사용
      // function UsersComponent() {
      //   const [users, setUsers] = useState([]);
      //   useEffect(() => {
      //     axios.get('/api/users?limit=20')
      //       .then(response => setUsers(response.data));
      //   }, []);
      //   return (/* 렌더링 코드 */);
      // }

Next.js 13+ App Router

클라이언트 → Next.js 서버 → 백엔드 API → Next.js 서버 → 클라이언트

  • 코드

      // app/users/page.js
      import { fetchUsers } from '@/lib/api'; // 데이터 페칭 함수
    
      // 서버 컴포넌트 (기본값)
      export default async function UsersPage() {
        // 서버에서 직접 API 호출
        const users = await fetchUsers();
    
        return (
          <div>
            <h1>사용자 목록</h1>
            <ul>
              {users.map(user => (
                <li key={user.id}>{user.name}</li>
              ))}
            </ul>
          </div>
        );
      }
  • (예시 코드는 gpt로 생성했습니다 참고만 부탁드립니다)

++ 추가 사항

서버 사이드 렌더링: 서버에서 HTML을 완성해 보내주는 방식
클라이언트 사이드 렌더링: 브라우저가 직접 HTML을 조립하는 방식

https://www.youtube.com/watch?v=0QS09a-L9ac