Nuxt 를 배워보자

Vue 3 + Nuxt 3: Composition API를 활용한 서버 통신 예제

_Blue_Sky_ 2025. 2. 15. 21:11
728x90
728x90

Vue 3와 Nuxt 3에서 Composition API를 활용하여 서버와 데이터를 주고받는 방법을 살펴보겠습니다. 이 글에서는 ref()를 사용한 반응형 데이터 관리, setup()을 활용한 상태 공유, $fetch()를 이용한 서버 API 호출 방법을 설명하며, 예제 코드와 함께 상세한 설명을 제공합니다.

1. 프로젝트 구조 및 개요

이 예제에서는 setup()을 이용해 상태를 관리하며, ref()를 활용하여 반응형 데이터를 사용합니다. Nuxt 3의 $fetch()를 사용해 API 호출을 수행하고, 서버에서 클라이언트가 보낸 데이터를 받아 다시 응답하는 구조를 가집니다.


1. Vue 템플릿 코드 (컴포넌트에서 데이터 처리)

이제 Vue 템플릿과 JavaScript 코드가 어떻게 구성되어 있는지 살펴보겠습니다.

<!-- pages > server_loging.vue -->

<template>
    <div>
      <p>-</p>
      <p> {{ inMessage }}</p>
      <button @click="consoleLog(`밖에서 ..... Fetch Data1  `)">밖에서 ..... Fetch Data1</button>
      <button @click="test">밖에서 ..... Fetch Data2</button>
      <p>-</p>
      <p v-if="outMessage">Response: {{ outMessage }}</p>
      <p>파일 이름: {{ filename }}</p>
    </div>
</template>
  
<script setup>
    import { ref } from 'vue';
    import { outMessage, inMessage, consoleLog } from '@/components/server_log.js';

    const test = () => { 
        consoleLog(`밖에서 ..... test!!!!! `);        
    };

    // 현재 날짜와 시간을 yyyy-mm-dd hh:mm:ss 형식으로 포맷팅
    const formattedDate = new Date().toISOString().replace('T', ' ').substring(0, 19);

    // 파일 이름 추출
    const filename = ref('');    
    filename.value = import.meta.url.split('/').pop();

    console.log(`[${formattedDate}] ${filename.value} 로딩`); // 이건 터미널에서 출력됨 
</script>

 📌 설명

  • retMessage: 서버에서 받은 응답 데이터를 저장하는 ref 객체
  • inMessage: 사용자가 버튼을 클릭하면 업데이트되는 ref 객체
  • consoleLog(): 서버로 데이터를 전송하는 비동기 함수
  • test() 함수에서 consoleLog()를 호출하여 API를 실행

728x90

2. Composition API를 이용한 상태 관리 (server_log.js)

이제 server_log.js에서 ref()를 사용하여 데이터를 정의하고, $fetch()를 통해 서버 API를 호출하는 코드를 살펴보겠습니다. 

// components > server_log.js

import { ref } from 'vue';

export const outMessage = ref(null);
export const inMessage = ref(``);

export const consoleLog = async (customMsg) => {
    inMessage.value = customMsg || `[ 서버 로그 : ${new Date().toLocaleString()} ]`

    try {
        const response = await $fetch(`/api/server_log?message=${encodeURIComponent(inMessage.value)}`)
        outMessage.value = response.message
        console.log(outMessage.value)
    } catch (error) {
        console.error('데이터를 가져오는 중 오류 발생:', error)
    }
};
 

📌 설명

  • retMessage: 서버에서 받은 응답 데이터를 저장하는 ref 객체
  • inMessage: 사용자가 보낸 메시지를 저장하는 ref 객체
  • consoleLog() 함수:
    • customMsg를 받아 inMessage.value에 저장
    • $fetch()를 이용해 서버 API(/api/server_log)를 호출
    • 응답 데이터를 retMessage.value에 저장
    • console.log()를 이용해 서버 응답을 확인

3. 서버 핸들러 코드 (/api/server_log.js)

Nuxt 3에서는 defineEventHandler()를 사용하여 API 핸들러를 정의할 수 있습니다.

// server > api > server_log.js

export default defineEventHandler(async (event) => {
    
    const { message } = getQuery(event); // message 의 값을 받아 온다.
    
    // 현재 날짜와 시간을 yyyy-mm-dd hh:mm:ss 형식으로 포맷팅
    const formattedDate = new Date().toISOString().replace('T', ' ').substring(0, 19);
    
    console.log(`[${formattedDate}] ${message} `); // 서버측 콘솔에 로그가 출력된다.

    return { message: `[${formattedDate}] ${message}` };
});

📌 설명

  • getQuery(event): 클라이언트에서 보낸 message 값을 가져옴
  • console.log(): 서버 측에서 메시지를 출력
  • return { message: ... }: 클라이언트에게 응답 메시지를 반환

4. 실행 흐름

  1. 사용자가 버튼 클릭
    • "밖에서 ..... Fetch Data1" 버튼을 클릭하면 consoleLog('밖에서 ..... Fetch Data1')이 실행됨.
    • inMessage.value가 "밖에서 ..... Fetch Data1"로 업데이트됨.
    • $fetch()가 실행되며 서버로 데이터를 전송.
  2. 서버 API가 요청을 처리
    • server_log.js에서 getQuery(event)로 클라이언트에서 보낸 메시지를 수신.
    • 메시지를 콘솔에 출력하고 새로운 응답 메시지를 생성하여 반환.
  3. 클라이언트가 응답을 표시
    • 서버에서 받은 응답이 retMessage.value에 저장됨.
    • Vue 템플릿이 업데이트되며 "밖에서 ..... Response: ..." 메시지가 표시됨.

728x90

5. 개선 가능성

이 코드는 기본적인 데이터 흐름을 설명하기 위한 예제이므로 몇 가지 개선할 수 있는 부분이 있습니다.

1️⃣ try-catch에서 오류 메시지 처리 강화

try {
    const response = await $fetch(`/api/server_log?message=${encodeURIComponent(inMessage.value)}`);
    retMessage.value = response.message;
} catch (error) {
    retMessage.value = "서버 오류 발생!";
    console.error('데이터를 가져오는 중 오류 발생:', error);
}

2️⃣ computed()를 활용한 반응형 데이터

 
import { computed } from 'vue';

export const formattedMessage = computed(() => {
    return retMessage.value ? `📢 서버 응답: ${retMessage.value}` : "아직 응답 없음";
});

 


6. 결론

이 예제에서는 Vue 3와 Nuxt 3를 사용하여 클라이언트와 서버 간 데이터를 주고받는 방법을 살펴보았습니다. ref()를 사용하여 상태를 관리하고, $fetch()를 이용해 서버 API를 호출하며, defineEventHandler()로 서버에서 요청을 처리하는 구조를 이해할 수 있었습니다. 이를 통해 Vue 3의 Composition API와 Nuxt 3의 API 핸들링에 대한 기본 개념을 익힐 수 있었습니다.

 

728x90
728x90