일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- usemutation custom hook
- inferred type error
- dynamic metadata
- type reference cannot be named error
- node.js(express) + ws(websocket) + react
- 코드잇 스프린트 FE 1기
- pure functions
- 스프린트 여정 마침
- css module classNames
- 오블완
- useref 타입
- 이미지 업로드 과정
- CSS module 장점
- 리액트로 채팅 기능 구현하기
- next.js
- useimperativehandle 사용법
- components as formulas
- express로 채팅 기능 구현하기
- useimperativehandle 사용할때
- express react
- app.listen
- 프리렌더링
- 리스티웨이브
- 티스토리챌린지
- 회고
- 특정 dom node만 노출시키고 싶을 때
- 리액트 19 useref
- http.createserver
- trigger additional callbacks
- React
- Today
- Total
Life is connecting the dots .
React + Node.js + Express + MySQL 연동해서 사용해보기 본문
React + Node.js + Express + MySQL 연동해서 사용해보기
soyeori 2024. 10. 9. 10:57프론트엔드는 React, Next.js를 사용하고, 백엔드는 node.js, express, DB는 mysql을 사용하여 연동하는 과정을 기록해 본다.
node.js(express)를 공부한 이유는 프론트엔드 토이 프로젝트를 할 때 간단하게나마 백엔드 서버를 구축해서 모두 만들어보고 싶어서이다.
1. 폴더구조
프론트엔드와 백엔드를 한 번에 세팅해 본 적이 없어서 폴더구조에 고민이 많았다. 결론은
(1) 한 폴더에 한 번에 만들어서 서버를 한 번만 띄우는 방법과
(2) 백엔드와 프런트엔드 폴더를 각각 두어 서버를 각각 띄우는 방법으로 좁혀졌는데
최종 (2) 번을 선택해서 만들었다. 그 이유는 각 폴더 안에서 서버를 띄우는 것이 익숙하면서 개발하기에도 편했고, 에러가 발생했을 때도 빨리 확인할 수 있다고 판단했다.
폴더 구조
project
├── frontend
│ ├── README.md
│ ├── node_modules
│ ├── package-lock.json
│ ├── package.json
│ └── src
└── server
├── config
├── node_modules
├── package-lock.json
├── package.json
└── server.js
백엔드 기본 설치 항목 (express, nodemon 설치)
express를 사용하기 위해 백엔드 폴더(/server)에서 다음 명령어를 실행하여 설치해 주면 아주 기본적인 세팅은 끝난다.
- npm init // package.json 파일 생성
- npm install express // express 설치
- npm install nodemon --save-dev
이제 커맨드라인에 nodemon 명령어를 사용하여 서버 파일을 실행시킬 수 있다. 이를 npm run dev 명령어로 실행시키고자 scripts를 수정해 주었다.
express 하나만 설치했는데 package-lock.json에 많은 package들이 설치되는 이유
express를 설치하면 package.json파일에는 express 하나만 잘 설치된 것을 확인할 수 있는데, package-lock.json 파일이 별도로 추가되고 내가 설치하지 않은 다양한 패키지들이 설치된 것을 확인할 수 있다. package-lock.json 역할은 만약 다른 사용자가 해당 프로젝트를 설치하는 경우 express 버전뿐만 아니라 express를 실행하기 위한 의존성 패키지들의 버전도 동일하게 맞추기 위함이다.
node_modules/express 설치 항목을 보면, express를 설치할 때 무수히 많은 dependencies를 설치했는데, 이 항목들을 따라가다 보면 하나의 패키지를 설치할 때 추가로 무엇이 필요해서 설치되었는지를 알 수 있다. (express를 설치할 때 accepts를 추가로 설치, accepts를 설치할 때 mime-types를 추가로 설치...)
2. 리액트와 노드 연결하기
백엔드 폴더에 server.js 파일을 생성하고, 본격적으로 express를 사용하기 위한 코드를 작성한다. 아래는 기본적으로 express를 사용할 수 있는 예제이다. 처음 사용해 보았을 때 아래 흐름대로 express를 사용하는구나를 익혔고, 각 항목에 대해 세부적인 부분은 docs를 참고해서 확장해 나가면 될 것 같다.
(1) express, 필요한 모듈 호출 및 포트 설정
(2) app.use() 함수를 사용하여 미들웨어 함수 호출
(3) 라우팅은 엔드포인트(URI)가 클라이언트 요청에 응답하는 방식으로 app객체의 메소드(HTTP메소드에 해당)를 사용해서 정의
(4) 지정된 호스트 및 포트에서 연결을 바인딩하고 수신
// 1. 필요한 모듈 호출
const express = require('express')
// Binds and listens for connections on the specified host and port.
const app = express()
const port = 3001
// 2. Bind application-level middleware.
// app.use(...);
// 3. Routing
// GET method route
app.get('/', (req, res) => {
res.send('Hello World!')
})
// POST method route
app.post('/api/signup', (req, res) => {
...
})
// 4. Binds and listens for connections on the specified host and port.
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
프론트엔드에서는 express로 만든 라우팅 엔드포인트로 API를 호출한다.
3. DB(MySQL) 연동하기
데이터를 DB에 저장하기 위해 MySQL을 선택하여 mysql 설치(brew install mysql) 및 워크벤치 설치 및 백엔드 폴더에 mysql2 라이브러리도 설치(npm install mysql2) 해 주고, mysql을 실행한다.
- mysql 서버 실행: brew services start mysql
- 종료: brew services stop mysql
- 접속: mysql -u root -p
- 종료: exit
이후 워크벤치에서 쿼리문으로 데이터베이스와 테이블을 미리 만들어 주었다.
Connection 만들기
mysql을 사용할 때 connection을 만들어줘야 하는데 기본적으로 하나씩(one-by-one) 커넥션을 만들 수 있다. 하지만 커넥션을 맺고 끊고 하면 자원을 많이 낭비할 수 있기 때문에 커넥션 풀(pool)을 만들어서 연결을 재사용할 수 있도록 유지하는 방법을 적용했다.
// server/config/db.js
const mysql = require("mysql2");
const db = mysql.createPool({
connectionLimit: 10,
host: "localhost", // DB의 ip주소
user: "...", // 사용자 이름 (*mysql에 접속한 후, SELECT user, host FROM mysql.user; 로 확인)
password: "...", // 비밀번호
port: 3306, // 포트번호
database: "...", // DB이름
});
module.exports = db;
DB사용하기
db 연결을 완료하면 express 라우팅을 할 때 데이터 베이스 연결, 쿼리 실행, 응답 반환 관련 코드를 작성해 준다. 커넥션 풀을 사용해서 pool.getConnection() -> connection.query() -> connection.release() 흐름대로 작성한다. (참고로, pool.query()를 사용하면 자동으로 연결을 관리해 준다.)
4. 전체 코드
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const db = require("./config/db"); // db connection
const app = express();
// middleware
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const port = 3001; // react의 포트번호와 다르게 하기 위해
// routing
app.post("/api/signup", (req, res) => {
const { id, name, age, password } = req.body;
db.getConnection((err, connection) => {
if (err) {
console.log("DB connection error: ", err);
res.status(500).send("DB connection error");
return;
}
console.log("DB 연결 완료");
connection.query(
"insert into users (id, name, age, password) values (?,?,?,?);",
[id, name, age, password],
(error, result) => {
connection.release(); // connection을 pool에 반환
if (error) {
console.dir("쿼리 실행 에러: ", error);
res.status(500).send("DB connection error");
return;
}
if (result) {
console.log("result: ", result);
// 쿼리 성공하면 리스폰스 보내고, 응답 종료
res.json({
...
});
}
}
);
});
});
// listens for connections
app.listen(port, () => {
console.log("서버가 3001번 포트에서 실행중");
});
회원가입 기능을 위한 API를 만들어 보았다. 포트 번호가 다른 데서 발생하는 cors 에러를 해결하기 위한 cors 모듈 및 json 파싱을 위한 body-parser 모듈도 추가로 설치해 주었다. 해당 API를 프론트엔드에서 baseUrl("http://localhost:3001") + endpoind("/api/signup")로 fetch해와서 사용한다. 지금은 사용 방법을 익히기 위해 아주 간단하게 작성해 본 코드로 추후 프로젝트를 통해 에러 핸들링, 보안 처리, 응답 케이스 등을 다룰 계획이다.
'Programming > Node.js(express)' 카테고리의 다른 글
Node.js(express) + ws(WebSocket) + React로 채팅 기능 만들기 (+. app.listen vs http.createServer) (0) | 2024.10.17 |
---|