Express.js 사용의 이유
아래와 같이 Node에서 제공하는 http 모듈 패키지를 사용해서 서버를 구현할 수 있다.
하지만 체계적으로 파일을 분리해서 관리하기에는 다소 어려움이 있다.
POST 방식의 처리와 GET 방식의 처리를 하기 위해서 req.method
로 조건분기 처리를 하고, 그 안에서도 req.url
을 통해서 요청받은 url을 구분해야 되기 때문에 조건처리하는 부분의 코드가 길어지게 되고, 코드의 가독성도 좋지 않다.
1 | const http = require('http'); |
이러한 이유로 인해 Node.js의 프레임워크인 Express.js를 사용해서 서버를 구현하는 것이다.
head와 body
body는 res.json 또는 res.send로 보내지는 부분이다. head는 이 body(요청에 대한 응답)에 대한 부가적인 정보를 담고 있다.
(예를들어, 응답의 날짜, 데이터 타입, 용량 등의 정보를 담고 있다.
)
Swagger API Documentation
Seagger 툴을 사용해서 API를 문서화할 수 있다.
[참고] : https://swagger.io/
REST API 방식
100% REST 방식을 지켜서 작성하기 어렵다. 어느정도 협상을 통해 REST 방식으로 API를 작성하도록 한다.
- get : 취득
- post : 생성
- put : 전체 수정(통째로 덮어쓰기)
- delete : 제거
- patch : 부분 수정
- options : 서버에 요청에 대한 확인
- head : header 정보 취득
MySQL8
(1) MySQL Community server 설치
(2) MySQL workbench 설치 (terminal 말고 시각화해서 내부 데이터베이스 확인)
sequelize와 mysql2 driver 설치 및 설정
1 | $ npm i sequelize sequelize-cli mysql2 |
mysql2 : node.js와 mysql을 연결해주는 드라이버
sequelize : 직접 query를 작성해주지 않아도 javascript를 sql로 변환해주는 라이브러리
1 | # 기본 sequelize 설정 |
설정 순서
npx sequelize init으로 초기화를 시켜주면, 프로젝트 내에
config, migrations, models, seeders
폴더가 자동생성된다.
(1) config/config.json
개발, 테스트, 배포 모드에 따라 사용되는 database를 다르게 설정할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23{
"development": {
"username": "root",
"password": "1q2w3e4r",
"database": "development-db",
"host": "127.0.0.1",
"dialect": "mysql"
},
"test": {
"username": "root",
"password": null,
"database": "test-db",
"host": "127.0.0.1",
"dialect": "mysql"
},
"production": {
"username": "root",
"password": null,
"database": "production-db",
"host": "127.0.0.1",
"dialect": "mysql"
}
}(2) models/index.js
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
29const Sequelize = require('sequelize');
// 별도로 env.NODE_ENV가 선언되어 있지 않으면 'development'로 초기화한다.
const env = process.env.NODE_ENV || 'development';
// config.json을 호출해서 [development]에 해당하는 설정부분 config 변수에 초기화한다.
const config = require('../config/config')[env];
const db = {};
// Sequelize는 Node.js와 mysql을 연결해주는 역할을 한다.
// Sequelize가 내부적으로 mysql2 driver를 사용하기 때문에 아래와 같이 연결에 필요한 정보를 인수로 넘겨서 Node.js와 mysql을 연결시켜주게 되는 것이다.
const sequelize = new Sequelize(
config.database,
config.username,
config.password,
config
);
// 이하 설정부분은 기존에 자동으로 생성된 설정부분
Object.keys(db).forEach((modelName) => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;(3) DB 테이블 생성 / Sequelize model 생성 (models/)
sequelize에서는 table을 model이라고 한다.
model이 다른 model과 관련이 되어 있는 경우, model의 associate 부분에 정의를 해준다.
우선적으로 독립적으로 분리할 수 있는 테이블들을 model로 정의를 해주고 나중에 관계를 엮을 부분을 associate에 정의하면 된다.독립적으로 분리된 상태의 sequelize model 작성
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
32
33module.exports = (sequelize, DataTypes) => {
// User : model name (mysql에서는 users로 자동변환되어 테이블이 생성된다. - 소문자로 변환되고 복수 이름으로 변환)
const User = sequelize.define(
'User',
// 첫 번째 객체의 정보는 테이블의 column 정보
{
// 기본적으로 id가 column이 생성된다.
email: {
// 데이터 타입에는 STRING, TEXT, BOOLEAN, INTEGER, FLOAT, DATETIME가 있다.
type: DataTypes.STRING(30),
allowNull: false, // 필수
unique: true
},
nickname: {
type: DataTypes.STRING(30),
allowNull: false
},
password: {
// PASSWORD는 암호화를 하게 되면 길이가 늘어나기 때문에 100
type: DataTypes.STRING(100),
allowNull: false
}
},
// 두번째 객체는 User model에 대한 setting 정보를 넣어준다.
{
charset: 'utf8',
collate: 'utf8_general_ci' //한글 저장
}
);
// model 간의 관계를 정의하는 부분
User.associate = (db) => {};
return User;
};위와같이 작성을 해주면, sequelize가 자동으로 MySQL에 테이블을 만들어준다.
Sequelize model 간의 관계 설정하기
1:N :
hasMany() / belongsTo()
- 설정한 부분에 model의 id column이 생성된다.- 한 명의 User가 여러 개의 게시글을 작성
N:N :
belongsToMany()
다대다(N:N)로 정의를 하게 되면, 두 개의 model을 mapping 시키는mapping table
이 새롭게 생성이 된다. mapping table의 이름은 자동으로 부여되지만, through 속성을 통해 지정을 할 수 있으며, as 속성을 통해서 어떤 정보를 담고 있는지 구분할 수 있다.- 하나의 Hash tag에는 여러 개의 게시글이 연관, 하나의 게시글에 여러 개의 Hash tag가 포함
- 사용자와 사용자 (팔로우)
- 사용자와 게시물의 좋아요 관
1:1 :
hasOne() / belongsTo()
사용자와 사용자 정보 관계
1
2
3db.User.hasOne(db.UserInfo);
db.UserInfo.belongsTo(db.User);
models/user.js
1
2
3
4
5
6
7
8User.associate = (db) => {
// User: Post = 1: N
db.User.hasMany(db.Post);
db.User.hasMany(db.Comment);
// 사용자 - 좋아요 (through를 통해 중간 테이블 이름 지정)
// post.getLikers 로 게시글 좋아요 누른 사람에 대한 정보를 가져올 수 있다.
db.User.belongsToMany(db.Post, { through: 'Like', as: 'Likers' });
};models/post.js
1
2
3
4
5
6
7
8
9
10
11Post.associate = (db) => {
db.Post.belongsTo(db.User);
// 다대다 관계 (N:N)
db.Post.belongsToMany(db.Hashtag);
db.Post.hasMany(db.Comment);
db.Post.hasMany(db.Image);
// 사용자 - 좋아요 (through를 통해 중간 테이블 이름 지정)
// 아래와같이 as로 지정해주면,
// post.getLikers 로 게시글 좋아요 누른 사람에 대한 정보를 가져올 수 있다.
db.Post.belongsToMany(db.User, { through: 'Like', as: 'Likers' });
};belongsTo와 hasMany의 역할
belongsTo로 associate 내에 선언을 해주게 되면, 해당 model의 column에 belongsTo로 선언된 model의 id column이 생성된다.
1
2
3
4Comment.associate = (db) => {
db.Comment.belongsTo(db.User); // UserId: {}
db.Comment.belongsTo(db.Post); // PostId: {}
};
database 생성하기
1 | $ npx sequelize db:create |