프로그래밍(Web)/Javascript(TS,Node)

[바미] Node-Express 간단한 REST API 예제

Bami 2024. 8. 1. 22:07
728x90
반응형

프로젝트 디렉토리 생성

mkdir REST-study
cd REST-study
npm init -y

 

그 이후 사용할 패키지들을 설치해줍니다. (이번 예제에서는 ORM을 사용하지 않는 예제입니다.)

npm install express mysql2

 

우리가 만들 프로젝트 디렉토리 구조는 아래와 같습니다.

REST-study/
│
├── conn/
│   └── db.js
│
├── controllers/
│   └── userController.js
│
├── routers/
│   └── userRouter.js
│
├── services/
│   └── userService.js
│
├── app.js
└── package.json

 

먼저 conn/db.js 파일에서 MySQL2를 사용하여 MariaDB 연결을 설정해줍시다.

아래와 같이 자신의 DB 설정에 맞게 설정해줍니다.

const mysql = require('mysql2/promise');

const pool = mysql.createPool({
  host: 'localhost', // MariaDB 서버 주소
  user: 'root', // MariaDB 사용자 이름
  password: 'password', // MariaDB 비밀번호
  database: 'testdb', // 사용할 데이터베이스 이름
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0
});

module.exports = pool;

Service Layer 생성

비즈니스 로직과 DB 쿼리를 처리하기 위해 services/userService.js를 만들어줍니다.

const pool = require('../conn/db');

async function getAllUsers() {
    const connection = await pool.getConnection();
    try {
        const [rows] = await connection.query('SELECT * FROM users');
        return rows;
    } catch (error) {
        throw error;
    } finally {
        connection.release(); // 연결 해제
    }
}

async function getUserById(id) {
    const connection = await pool.getConnection();
    try {
        const [rows] = await connection.query('SELECT * FROM users WHERE id = ?', [id]);
        return rows[0];
    } catch (error) {
        throw error;
    } finally {
        connection.release();
    }
}

async function createUser(user) {
    const connection = await pool.getConnection();
    try {
        await connection.beginTransaction();
        const { name, email } = user;
        const [result] = await connection.query('INSERT INTO users (name, email) VALUES (?, ?)', [name, email]);
        await connection.commit();
        return result.insertId;
    } catch (error) {
        await connection.rollback();
        throw error;
    } finally {
        connection.release();
    }
}

async function updateUser(id, user) {
    const connection = await pool.getConnection();
    try {
        await connection.beginTransaction();
        const { name, email } = user;
        const [result] = await connection.query('UPDATE users SET name = ?, email = ? WHERE id = ?', [name, email, id]);
        await connection.commit();
        return result.affectedRows;
    } catch (error) {
        await connection.rollback();
        throw error;
    } finally {
        connection.release();
    }
}

async function deleteUser(id) {
    const connection = await pool.getConnection();
    try {
        await connection.beginTransaction();
        const [result] = await connection.query('DELETE FROM users WHERE id = ?', [id]);
        await connection.commit();
        return result.affectedRows;
    } catch (error) {
        await connection.rollback();
        throw error;
    } finally {
        connection.release();
    }
}

module.exports = {
    getAllUsers,
    getUserById,
    createUser,
    updateUser,
    deleteUser,
};

Controller Layer

HTTP 요청을 처리하고, Service 레이어를 호출하기 위해 controllers/userController.js를 생성해줍니다.

const userService = require('../services/userService');

async function getAllUsers(req, res) {
  try {
    const users = await userService.getAllUsers();
    res.json(users);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
}

async function getUserById(req, res) {
  try {
    const user = await userService.getUserById(req.params.id);
    if (user) {
      res.json(user);
    } else {
      res.status(404).json({ message: 'User not found' });
    }
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
}

async function createUser(req, res) {
  try {
    const userId = await userService.createUser(req.body);
    res.status(201).json({ id: userId });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
}

async function updateUser(req, res) {
  try {
    const rowsAffected = await userService.updateUser(req.params.id, req.body);
    if (rowsAffected > 0) {
      res.json({ message: 'User updated successfully' });
    } else {
      res.status(404).json({ message: 'User not found' });
    }
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
}

async function deleteUser(req, res) {
  try {
    const rowsAffected = await userService.deleteUser(req.params.id);
    if (rowsAffected > 0) {
      res.json({ message: 'User deleted successfully' });
    } else {
      res.status(404).json({ message: 'User not found' });
    }
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
}

module.exports = {
  getAllUsers,
  getUserById,
  createUser,
  updateUser,
  deleteUser,
};

Router Layer

URL 경로와 Controller를 연결하기 위해 routers/userRouter.js를 생성해줍니다.

const express = require('express');
const userController = require('../controllers/userController');

const router = express.Router();

router.get('/users', userController.getAllUsers);
router.get('/users/:id', userController.getUserById);
router.post('/users', userController.createUser);
router.put('/users/:id', userController.updateUser);
router.delete('/users/:id', userController.deleteUser);

module.exports = router;

메인 앱 파일

Express 서버를 설정하고 라우터를 연결해줄 app.js를 생성해봅시다.

const express = require('express');
const userRouter = require('./routers/userRouter');

const app = express();
const port = 3000;

app.use(express.json());
app.use('/api', userRouter);

app.listen(port, () => {
  console.log(`Server running on http://localhost:${port}`);
});

 

이후 서버를 실행하기 전에 MariaDB에 필요한 테이블을 생성해줍니다.

CREATE DATABASE testdb;

USE testdb;

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL
);

 

 

서버를 실행하면 끝입니다.

node app.js

 

createUser에서 사용하는 데이터는 아래와 같습니다.

{
    "name": "John Doe",
    "email": "john.doe@example.com"
}

 

 

 

 

 

728x90
반응형