728x90

"늘 그랬듯이"

라는 생각은 개발자에게 치명적이다.

 

그 현상을 더 이상

해결해야될 문제로 보지않고

안주하게 만들어버린다.

 

나에게 server.js 스크립트는

그런 대상이다.

 

수 많은 MVP 모델을 만들면서

server.js를 어떻게 구조화할지는

크게 고민하지않앗다.

 

express가 너무나도 쉽게 서버를 만들어주기에

필요할때 route만 더 붙여준다던지

cors를 설정해준다던지 하면 끝이었다.

 

// server.js
const express = require('express');
const api_v1 = require('../api/v1');

const app = express();
const http = require('http').createServer(app);

app.use('/api/v1/', api_v1);
http.listen(process.env.PORT, () => {
  console.log('server is listening on', process.env.PORT);
});

 

간단하게는

이정도면 충분히 훌륭한 앱서버가 된다.

 

문제는

서버에서 담당하는 역할이 많아지면서

여러가지가 붙다보면

코드가 지저분해지고

더이상 보기 싫은 스크립트가 되어버린다.

 

// server.js
const express = require('express');
const { Server } = require('socket.io');
const api_v1 = require('../api/v1');
const config = require('./config/server');

const app = express();
const http = require('http').createServer(app);
const io = new Server(http, {});

app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(cookieParser());

app.use(function (req, res, next) {
  const allowedOrigins = config.allowedOrigin;
  const origin: any = req.headers.origin;
  if (allowedOrigins.indexOf(origin) > -1) {
    res.setHeader('Access-Control-Allow-Origin', origin);
  }
  res.header('Access-Control-Allow-Headers', 'Authorization, X-Requested-With, Content-Type, Accept');
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS,PATCH');
  res.header('Access-Control-Allow-Credentials', 'true');
  req.method === 'OPTIONS' ? res.sendStatus(200) : next();
});

app.use('/api/v1/', api_v1);

io.sockets.on('connection', (socket) => {
  console.log('socket is connected..!');
});

http.listen(process.env.PORT, () => {
  console.log('server is listening on', process.env.PORT);
});

 

이정도만 되어도 보기싫어지기 시작한다.

우리는 class로 스크립트를 새로 짜보도록 하자.

 

// server.js
const express = require('express');
const { Server, createServer } = require('http');
const { Server as ioServer } = require('socket.io');
const api_v1 = require('../api/v1');
const config = require('./config/server');

const app = express();
const http = require('http').createServer(app);
const io = new Server(http, {});

class Server {
  private app: express.Aplication;
  private server: Server;
  private io: ioServer;
  
  constructor() {
    this.createApp();
    this.createServer();
    this.sockets();
    this.configure();
    this.routes();
    this.listen();
  }
  
  private createServer = (): void => {
    this.server = createServer(this.app);
  }
  
  private createApp = (): void => {
    this.app = express();
  }
  
  private sockets = (): void => {
    this.io = new ioServer(this.server);
  }
  
  private routes = (): void => {
    app.use('/api/v1/', api_v1);
  }
  
  private configure = (): void => {
    app.use(express.urlencoded({ extended: true }));
    app.use(express.json());
    app.use(cookieParser());

    app.use(function (req, res, next) {
      const allowedOrigins = config.allowedOrigin;
      const origin: any = req.headers.origin;
      if (allowedOrigins.indexOf(origin) > -1) {
        res.setHeader('Access-Control-Allow-Origin', origin);
      }
      res.header('Access-Control-Allow-Headers', 'Authorization, X-Requested-With, Content-Type, Accept');
      res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS,PATCH');
      res.header('Access-Control-Allow-Credentials', 'true');
      req.method === 'OPTIONS' ? res.sendStatus(200) : next();
    });
  }
  
  private listen = (): void => {
    this.server.listen(process.env.PORT, () => {
      console.log('server is listening on', process.env.PORT);  
    });
    
    io.sockets.on('connection', (socket) => {
      console.log('socket is connected..!');
    });
  }
}

const App = new Server();

 

이렇게 정리해놓고 보니

목적에 맞는 코드끼리 분리되어

유지보수가 확실히 수월해진듯한 느낌이든다.

 

코드를 짤때는 내 코드를

함께 공유할 개발자도 배려하는 자세를 갖도록 해야겠다.

728x90
반응형