Vue.js + Express + MySQL로 Node API 서버 구성하기 Quick Start — Part 1
Vue.js + Express로 프론트엔드와 백엔드 통신 이해하기
들어가기에 앞서…
이번 시리즈에서는 Vue.js를 활용한 프론트엔드 처리 뿐 아니라 Express, MySQL을 함께 사용함으로써 API를 통한 데이터 연동 과정을 소개합니다. Vue.js 입문자도 쉽게 이해할 수 있도록 쉽게 구성했으며, 이 과정에서 참고한 글은 하단에 기재해놓았습니다.
시리즈는 3 파트로 연재될 예정입니다.
Part1. Vue.js + Express로 프론트엔드와 백엔드 통신 이해하기
Part2. Express + MySQL로 DB 연동하기
Part3. Mix All — 로그인/회원가입 기능 개발하기
이 글은 Part1으로, Vue.js + Express로 프론트엔드와 백엔드가 서로 어떻게 데이터를 주고받는지 이해할 수 있는 간단한 예제를 다룹니다.
Step1. 프론트엔드 개발 환경 세팅 (Vue.js)
실습을 위한 폴더를 하나 생성합니다. 이 글에서는 ‘movie’라고 해보겠습니다.
movie 폴더에서 다음 명령을 실행하여 Vue Cli 3.x 프로젝트 환경을 세팅합니다.
npm install -g yarn
npm install -g @vue/cli
vue create frontend // frontend 폴더 생성cd frontend
npm run serve //서버 실행
locahost:8080으로 접속하면 아래와 같은 화면을 확인할 수 있습니다.
Step2. 백엔드 개발환경 세팅 (Express)
이 과정 역시 ‘movie’ 폴더에서 진행합니다. 다음 명령을 실행하여 express 프레임워크를 설치합니다.
npm install -g express-generator
express --view=pug backend // backend 폴더 생성cd backend
npm install
npm start // 서버 실행
localhost:3000 으로 접속하면 아래와 같은 화면을 확인할 수 있습니다.
Step3. 백엔드와 연동
movie/frontend 폴더로 이동하여, vue.config.js를 생성한 뒤 아래와 같이 입력합니다.
module.exports = {
devServer: { ① api 요청이 있을때 어디에서 처리할지를 설정
proxy: {
'/api': {
target: 'http://localhost:3000/api',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
},
outputDir: '../backend/public', ② 배포 파일의 위치를 지정
}
배포 파일의 위치를 위와 같이 지정한 뒤, Express 서버는 종료한 상태로 frontend 폴더에서 npm run build
를 실행하면 다음과 같이 backend/public 폴더의 구조가 변경된 것을 확인할 수 있습니다.
그리고 나서 Express 서버를 실행시키면, localhost:3000의 페이지도 프론트엔드쪽과 동일하게 변경된 것을 확인할 수 있습니다.
Step3. 백엔드에서 프론트엔드로 보낼 데이터 마련하기
backend 폴더 하위에 movies.json이라는 이름으로 아래와 같이 데이터를 마련합니다. 네이버 영화에서 데이터를 가져와봤습니다.
[
{
"id": 1,
"name": "기생충",
"rate": "54.80%",
"director": "봉준호",
"actors": "송강호(기택), 이선균(박사장), 조여정(연교) 등",
"time": "131분",
"synopsis": "<strong>폐 끼치고 싶진 않았어요</strong><br>전원백수로 살 길 막막하지만 사이는 좋은 기택(송강호) 가족. <br>장남 기우(최우식)에게 명문대생 친구가 연결시켜 준 고액 과외 자리는 <br>모처럼 싹튼 고정수입의 희망이다. <br>온 가족의 도움과 기대 속에 박사장(이선균) 집으로 향하는 기우. <br>글로벌 IT기업 CEO인 박사장의 저택에 도착하자 <br>젊고 아름다운 사모님 연교(조여정)가 기우를 맞이한다.",
"poster": "https://movie-phinf.pstatic.net/20190528_36/1559024198386YVTEw_JPEG/movie_image.jpg?type=f125"
},
{
"id": 2,
"name": "알라딘",
"rate": "21.10%",
"director": "가이 리치",
"actors": "메나 마수드(알라딘), 윌 스미스(지니), 나오미 스콧(자스민) 등",
"time": "128분",
"synopsis": "머나먼 사막 속 신비의 아그라바 왕국의 시대. <br>좀도둑 ‘알라딘’은 마법사 ‘자파’의 의뢰로 마법 램프를 찾아 나섰다가 <br>주인에게 세 가지 소원을 들어주는 지니를 만나게 되고, <br>자스민 공주의 마음을 얻으려다 생각도 못했던 모험에 휘말리게 되는데…",
"poster": "https://movie-phinf.pstatic.net/20190524_104/1558663170174Q2mmw_JPEG/movie_image.jpg?type=f125"
},
... 중략]
이제 라우터를 설정합니다. backend/routes/ 하위에 movies.js를 생성한 뒤, 다음과 같이 입력합니다.
var express = require('express');
var router = express.Router();
var movies = require('../movies.json');router.get('/', function (req, res, next) {
res.send(movies)
});// 영화 상세 페이지를 위한 코드
router.get('/:id', function (req, res, next) {
var id = parseInt(req.params.id, 10)
var movie = movies.filter(function (movie) {
return movie.id === id
});
res.send(movie)
});module.exports = router;
backend/app.js에는 아래 내용을 추가합니다. 프론트엔드쪽에서 /api/movies 요청을 보내면, 위 코드에서 설정한 라우터를 통해 데이터를 처리합니다.
…
var moviesRouter = require('./routes/movies');
…
app.use('/api/movies', moviesRouter);
Step4. 프론트에 뿌려질 화면 제작
frontend/src/component로 이동하여 MovieIndexPage.vue를 생성하고 다음과 같이 입력합니다.
<template>
<div class="wrap">
<h1>5월 마지막주 영화 예매 순위</h1>
<ul class="movies">
<li v-for="movie in movies" class="item">
<span class="rank">{{movie.id}}</span>
<router-link :to="{ name: 'show', params: { id: movie.id }}">
<img v-bind:src="movie.poster" class="poster">
</router-link>
<div class="detail">
<strong class="tit">{{movie.name}}</strong>
<span class="rate">예매율 <span class="num">{{movie.rate}}</span></span>
<router-link :to="{ name: 'show', params: { id: movie.id }}" class="link">자세히보기</router-link>
</div>
</li>
</ul>
</div>
</template><script>
export default {
created () {
// 컴포넌트가 생성될 때, /api/movies에 요청을 보냅니다.
this.$http.get('/api/movies')
.then((response) => {
this.movies = response.data
})
},
data () {
return {
movies: []
}
}
}
</script>
상세 페이지로 MovieShowPage.vue를 생성하고 다음과 같이 입력합니다.
<template>
<div class="detail">
<h1>{{movie.name}}</h1>
<img v-bind:src="movie.poster" class="poster">
<section>
<h2>영화정보</h2>
<dl class="info">
<dt>감독</dt>
<dd>{{movie.director}}</dd>
<dt>출연</dt>
<dd>{{movie.actors}}</dd>
<dt>러닝타임</dt>
<dd>{{movie.time}}</dd>
</dl>
</section>
<section>
<h2>줄거리</h2>
<p v-html="movie.synopsis" class="synopsis"></p>
</section>
<router-link :to="{ name: 'index', params: { id: movie.id }}" class="link">돌아가기</router-link>
</div>
</template>
<script>
export default {
created: function () {
var id = this.$route.params.id;
this.$http.get('/api/movies/${id}')
.then((response) => {
this.movie = response.data[0]
})
},
data: function () {
return {
movie: {}
}
}
}
</script>
이제 라우터를 설정합니다. npm install vue-router --save
명령어로 Vue 라우터 패키지를 설치합니다.
fontend/src/routes/index.js를 생성하여, 다음과 같이 입력합니다.import Vue from 'vue'
import Router from 'vue-router'
import Index from '@/components/MovieIndexPage'
import Show from '@/components/MovieShowPage'Vue.use(Router)export const router = new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'index',
component: Index
},
{
path: '/:id',
name: 'show',
component: Show
}
]
})
라우터를 생성했으므로, frontend/src/app.vue에서는 <router-view>
요소를 넣어줍니다.
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
API 통신을 위해npm install axios --save
명령을 실행하여, axios 패키지를 설치합니다.
그리고 frontend/src/main.js를 다음과 같이 수정합니다.
import Vue from 'vue'
import App from './App.vue'
import {router} from './routes/index.js'
import axios from 'axios'Vue.config.productionTip = false
Vue.prototype.$http = axios;new Vue({
render: h => h(App),
router,
}).$mount('#app')
Step5. 마무리
Vue 서버를 실행하여, 정상 동작하는지 확인합니다.
npm run build
명령으로 빌드 실행 후, localhost:3000에서도 동일한 화면을 볼수 있다면 실습은 성공입니다.
이 과정으로 프론트엔드와 백엔드가 어떻게 데이터를 주고받는지 알 수 있었습니다. 다음 파트에서는 정적인 데이터가 아닌 Express + MySQL로 DB 연동을 통해 동적 데이터 다루는 법을 소개하겠습니다.
시리즈 정보
- Part1: Vue.js + Express로 프론트엔드와 백엔드 통신 이해하기
- Part2: Express + MySQL로 DB 연동하기
- Part3: Mix All — 로그인/회원가입 기능 개발하기