Express 개발 강좌, 프로젝트 구조 및 파일 구성 이해하기

1. 서론

Express.js는 Node.js를 위한 웹 프레임워크로, RESTful API를 쉽게 구축할 수 있도록 도와준다.
본 강좌에서는 Express로 백엔드 서버를 개발하기 위한 프로젝트 구조와 파일 구성을 깊이 있게 알아보겠다.
또한 최적의 개발 환경을 위한 기본적인 설정 방법과 예제를 제공할 예정이다.

2. Express.js란?

Express.js는 경량화된 Node.js 웹 어플리케이션 프레임워크로, 웹 서버 및 API 구축을
위한 다양한 기능들을 제공한다. 기본적으로 라우팅, 미들웨어 지원, HTTP 요청 및 응답 처리 등을
용이하게 할 수 있도록 지원한다. Express를 사용하면 더욱 효율적으로 웹 서버를 구축할 수 있다.

3. 프로젝트 구조 만들기

Express 프로젝트의 구조를 제대로 이해하면 코드 유지 보수와 확장성이 향상된다.
여기서는 일반적으로 사용하는 Express 프로젝트 구조를 설명하겠다.
아래의 구조는 기본적인 파일과 폴더로 구성되어 있다.

        
        /my-express-app
        ├── node_modules/
        ├── src/
        │   ├── controllers/
        │   ├── models/
        │   ├── routes/
        │   ├── middlewares/
        │   ├── config/
        │   └── app.js
        ├── .env
        ├── .gitignore
        ├── package.json
        └── README.md
        
        

3.1. root 디렉토리

모든 Express 프로젝트는 최상위 디렉터리에서 시작한다. 이 디렉터리에는
프로젝트의 메타데이터와 의존성을 정의하는 package.json 파일이 포함된다.
node_modules 폴더는 설치된 패키지를 포함하며,
.env 파일은 애플리케이션의 환경 변수 설정을 위한 파일이다.
.gitignore 파일은 Git에 포함하지 않을 파일들을 정의한다.

3.2. src 폴더

src 폴더는 애플리케이션의 실제 코드가 위치하는 곳이다.
이 폴더 내의 구성 요소들은 다음과 같다:

  • controllers/: 비즈니스 로직이 포함된 파일들이 위치한다.
    클라이언트의 요청을 처리하고, 필요한 데이터를 가져오며, 응답을 반환하는 역할을 한다.
  • models/: 데이터베이스와의 상호작용을 위한 모델들이다.
    일반적으로 ORM(Object Relational Mapping) 라이브러리와 함께 사용된다.
  • routes/: HTTP 요청을 특정 컨트롤러로 라우팅하는 역할을 한다.
    각 API 엔드포인트에 대한 경로를 정의한다.
  • middlewares/: 요청과 응답 사이에 실행되는 함수들로,
    인증, 로깅, 에러 처리 등을 위한 미들웨어를 포함한다.
  • config/: 애플리케이션의 설정 정보를 저장하는 폴더로,
    데이터베이스 연결 정보나 외부 서비스 API 키 등을 포함할 수 있다.
  • app.js: 애플리케이션을 초기화하고, 라우터를 설정하며,
    서버를 시작하는 등 핵심 기능을 구현하는 파일이다.

4. Express 애플리케이션 생성하기

이제 실제 Express 애플리케이션을 생성해 보겠다.
아래 단계에 따라 애플리케이션을 설정하고, 파일 구조를 구성할 것이다.

4.1. 프로젝트 초기화

        
        mkdir my-express-app
        cd my-express-app
        npm init -y
        
    

위 명령어를 통해 새로운 디렉토리를 생성하고, Node.js 프로젝트를 초기화한다.

4.2. Express 설치

        
        npm install express
        
    

Express 패키지를 설치한다.

4.3. 기본 서버 설정하기

src/app.js 파일을 생성하고 기본 서버 코드를 작성해 보자.

        
        const express = require('express');
        const app = express();
        const PORT = process.env.PORT || 3000;

        app.get('/', (req, res) => {
            res.send('Hello, Express!');
        });

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

4.4. 서버 실행

서버를 실행하기 위해 아래 명령어를 사용한다.

        
        node src/app.js
        
    

브라우저에서 http://localhost:3000에 접근하여 “Hello, Express!” 메시지를 확인할 수 있다.

5. 라우팅 구현하기

Express의 라우팅 기능을 사용하여 API 엔드포인트를 추가하겠다.
routes 폴더를 생성하고 userRoutes.js 파일을 만들어 사용자 관련 라우팅을 작성해 보자.

        
        // src/routes/userRoutes.js
        const express = require('express');
        const router = express.Router();

        // 사용자 목록 조회
        router.get('/users', (req, res) => {
            res.json([{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]);
        });

        // 사용자 추가
        router.post('/users', (req, res) => {
            // 사용자 추가 로직 구현
            res.status(201).json({ id: 3, name: req.body.name });
        });

        module.exports = router;
        
    

5.1. 라우터 연결하기

app.js 파일에서 userRoutes를 import 하고,
이를 Express 앱에 연결하자.

        
        const express = require('express');
        const app = express();
        const userRoutes = require('./routes/userRoutes');

        app.use(express.json()); // JSON 요청 본문 파싱
        app.use('/api', userRoutes); // '/api' 경로로 라우터 연결

        const PORT = process.env.PORT || 3000;

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

5.2. API 테스트하기

Postman 또는 curl을 사용하여 API를 테스트할 수 있다.
GET /api/users 요청을 보내면, 사용자 목록을 확인할 수 있을 것이다.

6. 비즈니스 로직 분리하기

비즈니스 로직을 컨트롤러로 분리하여 코드를 더 깔끔하고 유지보수하기 쉽게 만들자.
controllers 폴더를 생성하고 userController.js 파일을 추가하자.

        
        // src/controllers/userController.js
        exports.getUsers = (req, res) => {
            res.json([{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]);
        };

        exports.addUser = (req, res) => {
            res.status(201).json({ id: 3, name: req.body.name });
        };
        
    

6.1. 컨트롤러와 라우터 연결하기

userRoutes.js에서 라우터를 수정하여 컨트롤러를 사용한다.

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

        router.get('/users', userController.getUsers);
        router.post('/users', userController.addUser);

        module.exports = router;
        
    

7. 데이터베이스 연결하기

이제 MongoDB를 사용하여 데이터베이스와 연결하는 방법을 살펴보겠다.
mongoose 패키지를 설치하고, 간단한 게시판 예제를 구현해보자.

        
        npm install mongoose
        
    

7.1. 모델 정의하기

models 폴더를 생성하고 User.js 파일을 만들어
사용자 모델을 정의하자.

        
        // src/models/User.js
        const mongoose = require('mongoose');

        const userSchema = new mongoose.Schema({
            name: {
                type: String,
                required: true
            }
        });

        module.exports = mongoose.model('User', userSchema);
        
    

7.2. 데이터베이스 연결 설정하기

        
        const mongoose = require('mongoose');
        const express = require('express');
        const userRoutes = require('./routes/userRoutes');

        const app = express();
        mongoose.connect(process.env.MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true })
            .then(() => console.log('MongoDB Connected'))
            .catch(err => console.error('MongoDB connection error:', err));

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

7.3. 사용자 추가 기능 수정하기

사용자를 추가할 때 데이터베이스에 기록하도록 기능을 수정하자.

        
        // src/controllers/userController.js
        const User = require('../models/User');

        exports.addUser = async (req, res) => {
            try {
                const newUser = new User({ name: req.body.name });
                await newUser.save();
                res.status(201).json(newUser);
            } catch (error) {
                res.status(500).json({ message: error.message });
            }
        };
        
    

8. 결론

이번 강좌를 통해 Express.js 프로젝트의 구조와 파일 구성에 대해 알아보았다.
Express를 기반으로 한 백엔드 서버를 간단하게 구현해 보았고, 비즈니스 로직과 데이터베이스 연결을
통해 애플리케이션의 기능을 확장하는 방법을 배웠다.
이러한 기초 지식을 바탕으로 더 복잡한 웹 애플리케이션으로 발전시킬 수 있을 것이다.

추가 자료