개발노트/Spring

[Spring Boot + Vue.js 시리즈 2편] STS4와 Vue.js 연동하기

dev-mylee 2025. 2. 14. 10:29

이전 글에서 JSP와 Vue.js의 차이점을 알아보았다.

이번에는 실제로 Spring Boot(STS4)와 Vue.js를 어떻게 연동하는지 알아보자.

 

1. 프로젝트 구조

기본적인 프로젝트 구조는 다음과 같다:

project/
├── backend/ (Spring Boot)
│   ├── src/
│   │   ├── main/
│   │   │   ├── java/
│   │   │   └── resources/
│   └── pom.xml
└── frontend/ (Vue.js)
    ├── src/
    │   ├── components/
    │   ├── views/
    │   ├── api/
    │   └── store/
    └── package.json

 

 

 

2. Spring Boot 설정

2.1. CORS 설정

@Configuration
public class WebConfig implements WebMvcConfigurer {
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOrigins("http://localhost:8080")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowCredentials(true);
    }
}

 

 

2.2. REST API 컨트롤러

@RestController
@RequestMapping("/api/board")
public class BoardController {
    
    @Autowired
    private BoardService boardService;
    
    @GetMapping("/{id}")
    public ResponseEntity<BoardDTO> getBoard(@PathVariable Long id) {
        BoardDTO board = boardService.getBoard(id);
        return ResponseEntity.ok(board);
    }
    
    @PostMapping
    public ResponseEntity<BoardDTO> createBoard(@RequestBody BoardDTO board) {
        BoardDTO created = boardService.createBoard(board);
        return ResponseEntity.ok(created);
    }
}

 

 

3. Vue.js 설정

3.1. API 설정

// api/index.js
import axios from 'axios'

const instance = axios.create({
    baseURL: 'http://localhost:8081',
    headers: {
        'Content-Type': 'application/json'
    }
})

export const boardApi = {
    getBoard: (id) => instance.get(`/api/board/${id}`),
    createBoard: (data) => instance.post('/api/board', data),
    updateBoard: (id, data) => instance.put(`/api/board/${id}`, data),
    deleteBoard: (id) => instance.delete(`/api/board/${id}`)
}

 

 

3.2. Vue 컴포넌트 예시

<template>
  <div class="board-detail">
    <h2>{{ board.title }}</h2>
    <div class="board-info">
      <span>작성자: {{ board.writer }}</span>
      <span>작성일: {{ formatDate(board.regDate) }}</span>
    </div>
    <div class="board-content">
      {{ board.content }}
    </div>
    <div class="button-group">
      <button @click="goToList">목록</button>
      <button v-if="isAuthor" @click="goToEdit">수정</button>
      <button v-if="isAuthor" @click="deleteBoard">삭제</button>
    </div>
  </div>
</template>

<script>
import { boardApi } from '@/api'

export default {
  data() {
    return {
      board: {},
      isAuthor: false
    }
  },
  async created() {
    await this.fetchBoard()
  },
  methods: {
    async fetchBoard() {
      try {
        const response = await boardApi.getBoard(this.$route.params.id)
        this.board = response.data
        this.isAuthor = this.checkIsAuthor()
      } catch (error) {
        console.error('게시글 조회 실패:', error)
      }
    },
    checkIsAuthor() {
      return this.board.userNo === this.$store.state.user.no
    },
    formatDate(date) {
      return new Date(date).toLocaleDateString()
    }
  }
}
</script>

 

 

 

4. 주요 설정 포인트

  1. 포트 설정
    • Spring Boot: 8081 포트 (기본 8080에서 변경)
    • Vue.js: 8080 포트 (개발 서버)
  2. CORS 설정
    • 개발 환경에서는 다른 출처의 요청을 허용해야 함
    • 프로덕션 환경에서는 실제 도메인으로 설정
  3. API 요청 처리
    • axios 인스턴스 생성
    • 공통 설정 (baseURL, headers 등)
    • API 모듈화

 

 

5. 배포 고려사항

  1. 빌드 설정
    • Vue.js: npm run build로 정적 파일 생성
    • 생성된 파일을 Spring Boot의 static 폴더로 복사
  2. 환경 변수
    • 개발/운영 환경에 따른 API 주소 설정
    • Spring Boot의 profile 설정

아직 실제 프로젝트에 적용해보진 않았지만, 공부하면서 테스트해본 결과 Spring Boot와 Vue.js의 연동이 생각보다 깔끔하게 이루어진다는 걸 확인했다. 다음에는 실제 프로젝트 적용 시 발생하는 이슈들을 정리해볼 예정이다.