dev/nodejs

nodejs - controller/service로 분리, Callback function is not available with promise clients.

wlrn566 2023. 7. 23. 16:06

프로젝트를 위해 api를 만들던 중 route에서 요청과 응답, 비즈니스 로직까지 해버리니 보기가 너무 힘들어서

controller와 service로 나누어 보았다.

route -> controller -> service 의 흐름으로 된다.

 

route에서는 경로를 받고 controller에서 응답을 해준다. service는 DB에서 데이터를 가져와 다시 controller로 보내준다.

 

 

1.  app.js

유저에 관한 route를 등록해준다.

 

import express, { json, urlencoded } from 'express'; // express 모듈
const app = express();
const port = 3000; // 포트

import usersRouter from './routes/users.js';

app.use(json()); // body-parser
app.use(urlencoded({ extended: false })); // body-parser

app.use('/users', usersRouter);

app.listen(port, () => {
  console.log(`서버 가동! 포트: ${port}`)
}) // 실행

 

 

2.  route

경로의 요청을 받아서 controller로 넘겨준다.

 

import express from 'express';
import * as userController from '../controllers/user-controller.js';

const router = express.Router();

router.get('/', userController.getUserAll); // 유저 전체 조회

export default router;

 

 

3. controller

service를 호출하여 데이터를 받아서 응답해주는 곳이다.

 

import * as UserService from '../services/user-service.js';

export const getUserAll =  async function (req, res) {
  var result =  await UserService.getUserAll();     
  res.send(result);
};

 

 

4. service

DB와 연동하여 요청한 데이터를 반환하는 곳이다.

 

import mysql from 'mysql2';
import dotenv from 'dotenv';
dotenv.config();

const pool = mysql.createPool({
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_DATABASE,
  port: process.env.DB_PORT,
  connectionLimit: 10 // 커넥션 최대 개수
});

export const getUserAll = async function() {
  pool.getConnection((err, conn) => {
    conn.query('SELECT * from user', (error, rows, fields) => {
      if (error) throw error;
      console.log(rows[0]);
      return rows[0];
    });
    
    conn.release();
  });
};

 

 

이렇게 하니 service에서 데이터값은 로그가 잘 찍히는데 controller에서는 undefined가 계속 떳다.

로그를 여러군데 찍어보니 await를 걸어주어도 controller가 service를 기다려주지 않고 냅다 응답을 해버리고 있었다..;;

getConnection()부분에서 콜백이 잘 안되고 있는 것 같았다.. 콜백...

그리고 구글링을 열심히 하고 있는데 mysql2는 await를 지원하지 않고 콜백만 된다고 하는 글을 보았다.

 

mysql2/pomise를 사용해야 async/await를 사용할 수 있다.

 

 

5. service 수정

 

import mysql from 'mysql2/promise'; // mysql2/promise
import dotenv from 'dotenv';
dotenv.config();

const pool = mysql.createPool({
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_DATABASE,
  port: process.env.DB_PORT,
  connectionLimit: 10 // 커넥션 최대 개수
});

export const getUserAll = async function() {
  try {
    const conn = await pool.getConnection();
    const [ result ] = await conn.query("SELECT * FROM user");
    console.log(result);
    conn.release();
    
    return result;

  } catch (err) {
    return err;
  }
};

 

 

 

 

 

 


 

Callback function is not available with promise clients.

await getConnection() 안에 콜백을 넣으면 이런 오류가 떳다. 내부에 콜백 함수를 넣으면 안된다.