참고)
https://www.daleseo.com/js-node-es-modules/
Node.js Restful CRUD API 구현하기
※ 참고한 블로그 글은 commonjs로 구현되어 있는데 나는 다른 프로젝트를 ES module로 하였기 때문에 연습을 위해서 바꾸었다.
[폴더 구조]
1. node.js 프로젝트 생성
- 프로젝트 폴더 만들기
- npm init을 하고 package.json 자동 생성하기
- package.json에 "type":"module" 추가
- postgreSQL과 Express와 Sequelize 관련 모듈 설치하기
npm install express sequelize pg pg-hstore body-parser cors --save
2. index.js와 mvc 패턴을 위한 파일 생성
- index.js
- app/routes/tutorial.routes.js
- app/config/db.config.js
- app/controllers/tutorial.controller.js
- app/models/index.js , app/models/tutorial.model.js
3. index.js
- app.listen위에 app.use를 모두 적어야 한다.
- db.sequelize.sync()의 위치는 상관은 없어보인다.
import express from "express";
import bodyParser from "body-parser";
import cors from "cors";
import db from "./app/models/index.js";
import tutorialRouter from "./app/routes/tutorial.routes.js"
const app = express();
db.sequelize.sync()
.then(() => {
console.log("DB Connection successful");
}).catch((err) => {
console.error(err);
})
var corOptions = {
origin: "http://localhost:8081",
};
app.use(cors(corOptions));
// parse requests of content-type - application/json
app.use(bodyParser.json());
// parse requests of content-type - application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
// simple route
app.get("/", (req, res) => {
res.json({ message: "Welcome to my application." });
});
app.use("/api/tutorials", tutorialRouter);
// set port, listen for requests
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Server is running on Port ${PORT}!`);
});
4. app/routes/tutorial.routes.js
- tutorial.controller.js 에서 export를 여러개로 나눠서 작성했기 때문에 import * as [별명] from '~~' 이렇게 작성하여 한번에 불러올 것이다.
import * as express from 'express';
const router = express.Router();
import * as tutorials from "../controllers/tutorial.controller.js";
// Create a new Tutorial
router.post("/", tutorials.create);
// Retrieve all Tutorial
router.get("/", tutorials.findAll);
// Retrieve all published Tutorial
router.get("/published", tutorials.findAllPublished);
// Retrieve a single Tutorial with id
router.get("/:id", tutorials.findOne);
// Update a Tutorial with id
router.post("/:id", tutorials.update);
// Delete a Tutorial with id
router.delete("/:id", tutorials.delete);
// Delete all Tutorial
router.delete("/", tutorials.deleteAll);
export default router;
5. app/config/db.config.js
- PostgreSQL Shell 등에서 새로운 DB를 만들고 정보를 아래에 적는다.
- dialect는 여러 데이터베이스 (MS-SQL, Oracle, MySQL,PostgreSQL 등) 간에 변경을 용이하게 해준다. 지금은 "postgres"로 설정한다.
export const HOST = ""; // 127.0.0.1
export const USER = ""; // postgres (기본)
export const PASSWORD = "";
export const DB = "";
export const dialect = "postgres"; // *
export const pool = {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
};
6. app/controllers/tutorial.controller.js
- import db from "../models/index.js"는 export default db;로 db라는 변수에 모아서 내보내기를 했기 때문에 import [별명] from '~~' 로 작성한다.
- exports.create --> export function create 로 ES module로 변경 (vscode에서 자동으로 해준다..)
import db from "../models/index.js";
const Tutorial = db.tutorials;
const Op = db.Sequelize.Op;
// Create and save a new tutorial
export function create(req, res) {
if (!req.body.title) {
res.status(400).send({
message: "Content can not be empty!",
});
return;
}
const tutorial = {
title: req.body.title,
description: req.body.description,
published: req.body.published ? req.body.published : false,
};
Tutorial.create(tutorial)
.then((data) => {
res.send(data);
})
.catch((err) => {
res.status(500).send({
message:
err.message || "Some error occurred while creating the tutorial.",
});
});
}
// Retrieve all Tutorials from the database.
export function findAll(req, res) {
const title = req.query.title;
var condition = title ? { title: { [Op.iLike]: `%${title}%` } } : null;
Tutorial.findAll({ where: condition })
.then((data) => {
res.send(data);
})
.catch((err) => {
res.status(500).send({
message:
err.message || "Some error occurred while retrieving tutorials.",
});
});
}
// Find a single Tutorial with an id
export function findOne(req, res) {
const id = req.params.id;
Tutorial.findByPk(id)
.then((data) => {
res.send(data);
})
.catch((err) => {
res.status(500).send({
message: "error retrieving Tutorial with id =" + id,
});
});
}
// Update a Tutorial by the id in the request
export function update(req, res) {
const id = req.params.id;
Tutorial.update(req.body, {
where: { id: id },
})
.then((num) => {
if (num == 1) {
res.send({
message: "Tutorial was updated successfully.",
});
} else {
res.send({
message: `Cannot update Tutorial with id=${id}. Maybe Tutorial was not found or req.body is empty!`,
});
}
})
.catch((err) => {
res.status(500).send({
message: "Error updating Tutorial with id= " + id,
});
});
}
// Delete a Tutorial with the specified id in the request
const _delete = (req, res) => {
const id = req.params.id;
Tutorial.destroy({
where: { id: id },
})
.then((num) => {
if (num == 1) {
res.send({
message: "Tutorial was deleted successfully!",
});
} else {
res.send({
message: `Cannot delete Tutorial with id =${id}. Maybe Tutorial was not found!`,
});
}
})
.catch((err) => {
res.status(500).send({
message: "Could not delete Tutorial with id = " + id,
});
});
};
export { _delete as delete };
// Delete all Tutorials from the database.
export function deleteAll(req, res) {
Tutorial.destroy({
where: {},
truncate: false,
})
.then((nums) => {
res.send({ message: `${nums} Tutorials were deleted successfully!` });
})
.catch((err) => {
res.status(500).send({
message:
err.message || "Some error occurred while removingall tutorials.",
});
});
}
// Find all published Tutorials
export function findAllPublished(req, res) {
Tutorial.findAll({ where: { published: true } })
.then((data) => {
res.send(data);
})
.catch((err) => {
res.status(500).send({
message:
err.message || "Some error occurred while retrieving tutorials.",
});
});
}
7. app/models/tutorial.model.js
- tutorial이라는 테이블 정의하기
export default (sequelize, Sequelize) => {
const Tutorial = sequelize.define("tutorial", {
title: {
type: Sequelize.STRING
},
description: {
type: Sequelize.STRING
},
published: {
type: Sequelize.BOOLEAN
}
});
return Tutorial
};
8. app/models/index.js
- db.config.js 에서 export를 여러개로 나눠서 작성했기 때문에 import * as [별명] from '~~' 이렇게 작성하여 한번에 불러올 것이다.
- const Sequelize = require('sequelize'); --> import { Sequelize } from 'sequelize';
- (alias) class Sequelize
import Sequelize
This is the main class, the entry point to sequelize. To use it, you just need to import sequelize:
const Sequelize = require('sequelize');
import * as dbConfig from '../config/db.config.js';
import { Sequelize } from 'sequelize';
import tutorialModel from './tutorial.model.js';
const sequelize = new Sequelize(dbConfig.DB, dbConfig.USER, dbConfig.PASSWORD, {
host: dbConfig.HOST,
dialect: dbConfig.dialect,
operatorsAliases: false,
pool: {
max: dbConfig.pool.max,
min: dbConfig.pool.min,
acquire: dbConfig.pool.acquire,
idle: dbConfig.pool.idle
}
});
const db = {Sequelize : Sequelize, sequelize : sequelize, tutorials : tutorialModel(sequelize, Sequelize)};
export default db;
9. 이제 서버 실행해보기
- 프로젝트 폴더 경로에서 node index.js 로 서버 실행
- 서버를 실행하면 만들어둔 데이터베이스에 tutorial table이 생성된다.
10. POSTMAN에서 Request해보기
- 오랜만에 사용해보는데 잘 안돼서 찾아보니 인터넷에서 요청을 보낼 수 없고 desktop app을 설치하여 요청을 보내야한다.
- 아래처럼 해본다.
- 성공하면 밑에 이렇게 뜬다.
- postgres shell에서도 확인해보면 똑같이 뜬다.
10. 끝이다.
'개발 > Node.js' 카테고리의 다른 글
데이터베이스 권한 : admin/moderator/user (0) | 2023.09.22 |
---|---|
ORM에 대하여 (0) | 2023.09.21 |
node 미들웨어 에러처리 (0) | 2023.09.15 |
Node 프레임워크 14가지 (0) | 2023.08.18 |
페이지네이션 (0) | 2023.08.04 |