백엔드 심화 – Express.js를 활용한 RESTful API 구축

Express.js는 Node.js를 위한 빠르고 간결한 웹 프레임워크로, RESTful API를 구축하는 데 매우 유용합니다. 이번 포스팅에서는 "Express.js", "RESTful API 구축", "백엔드 심화"를 주제로, Express.js를 사용하여 RESTful API를 만드는 방법을 자세히 설명하겠습니다. 중급 개발자를 대상으로 하며, 예제를 통해 실습해 보겠습니다.


RESTful API란?


REST(Representational State Transfer)는 네트워크 상에서 자원을 정의하고 자원에 대한 주소를 지정하는 방법론입니다. RESTful API는 REST 아키텍처 스타일을 따르는 API를 의미합니다. HTTP 프로토콜을 사용하여 자원에 접근하고 조작할 수 있습니다.


REST의 기본 원칙


REST는 다음과 같은 기본 원칙을 따릅니다:


  1. 자원(Resource): 모든 것은 자원으로 간주됩니다. 예를 들어, 사용자, 제품, 주문 등이 자원입니다.
  2. 자원의 주소(Resource URL): 각 자원은 고유한 URL로 식별됩니다. 예: https://api.example.com/users/1
  3. 표현(Representation): 자원은 다양한 형식(JSON, XML 등)으로 표현될 수 있습니다.
  4. 상태 없음(Stateless): 각 요청은 독립적이며, 서버는 요청 간의 상태를 유지하지 않습니다.
  5. 표준 HTTP 메서드: RESTful API는 표준 HTTP 메서드를 사용하여 자원을 조작합니다. 예: GET, POST, PUT, DELETE

Express.js 소개


Express.js는 Node.js를 위한 빠르고 간결한 웹 프레임워크입니다. Express.js는 미들웨어와 라우팅 기능을 제공하여 복잡한 웹 애플리케이션을 쉽게 구축할 수 있습니다.


주요 기능


  • 미들웨어: 요청과 응답 객체를 처리하는 함수.
  • 라우팅: URL 경로에 따라 요청을 처리하는 방법을 정의.
  • 템플릿 엔진: 동적 HTML 파일을 렌더링.

프로젝트 설정


먼저 프로젝트 디렉토리를 설정하고 필요한 패키지를 설치합니다.


mkdir restful-api
cd restful-api
npm init -y
npm install express mongoose cors body-parser

프로젝트 구조


프로젝트의 기본 구조는 다음과 같습니다:


restful-api/
├── node_modules/
├── models/
│   └── user.js
├── routes/
│   └── users.js
├── app.js
└── package.json

Express.js로 RESTful API 구축


1. 기본 설정


app.js 파일을 만들고, Express.js 서버를 설정합니다.


const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const bodyParser = require('body-parser');

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

app.use(cors());
app.use(bodyParser.json());

mongoose.connect('mongodb://localhost:27017/restful-api', {
  useNewUrlParser: true,
  useUnifiedTopology: true
});

const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {
  console.log('MongoDB connected');
});

app.use('/users', require('./routes/users'));

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

2. 데이터베이스 모델 정의


models/user.js 파일을 만들고, 사용자 모델을 정의합니다.


const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
  name: String,
  email: String,
  age: Number
});

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

3. 라우터 설정


routes/users.js 파일을 만들고, 사용자 관련 라우트를 정의합니다.


const express = require('express');
const router = express.Router();
const User = require('../models/user');

// 모든 사용자 조회
router.get('/', async (req, res) => {
  try {
    const users = await User.find();
    res.json(users);
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
});

// 특정 사용자 조회
router.get('/:id', getUser, (req, res) => {
  res.json(res.user);
});

// 새로운 사용자 추가
router.post('/', async (req, res) => {
  const user = new User({
    name: req.body.name,
    email: req.body.email,
    age: req.body.age
  });
  try {
    const newUser = await user.save();
    res.status(201).json(newUser);
  } catch (err) {
    res.status(400).json({ message: err.message });
  }
});

// 사용자 수정
router.put('/:id', getUser, async (req, res) => {
  if (req.body.name != null) {
    res.user.name = req.body.name;
  }
  if (req.body.email != null) {
    res.user.email = req.body.email;
  }
  if (req.body.age != null) {
    res.user.age = req.body.age;
  }
  try {
    const updatedUser = await res.user.save();
    res.json(updatedUser);
  } catch (err) {
    res.status(400).json({ message: err.message });
  }
});

// 사용자 삭제
router.delete('/:id', getUser, async (req, res) => {
  try {
    await res.user.remove();
    res.json({ message: 'Deleted User' });
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
});

// 미들웨어: ID로 사용자 찾기
async function getUser(req, res, next) {
  let user;
  try {
    user = await User.findById(req.params.id);
    if (user == null) {
      return res.status(404).json({ message: 'Cannot find user' });
    }
  } catch (err) {
    return res.status(500).json({ message: err.message });
  }

  res.user = user;
  next();
}

module.exports = router;

RESTful API 테스트


Postman 설치 및 설정


Postman은 API를 테스트하는 데 매우 유용한 도구입니다. Postman 공식 웹사이트에서 Postman을 다운로드하고 설치합니다.


API 테스트 예제


  1. GET /users: 모든 사용자 조회
    curl -X GET http://localhost:5000/users
    

  2. GET /users/:id: 특정 사용자 조회
    curl -X GET http://localhost:5000/users/USER_ID
    

  3. POST /users: 새로운 사용자 추가
    curl -X POST -H "Content-Type: application/json" -d '{"name": "John Doe", "email": "john@example.com", "age": 25}' http://localhost:5000/users
    

  4. PUT /users/:id: 사용자 수정
    curl -X PUT -H "Content-Type: application/json" -d '{"name": "Jane Doe", "email": "jane@example.com", "age": 30}' http://localhost:5000/users/USER_ID
    

  5. DELETE /users/:id: 사용자 삭제
    curl -X DELETE http://localhost:5000/users/USER_ID
    

고급 기능


미들웨어


미들웨어는 요청과 응답 객체를 처리하는 함수입니다. 미들웨어는 라우트 핸들러 전에 실행되며, 요청을 가로채거나, 수정하거나, 추가 기능을 수행할 수 있습니다.


const express = require('express');
const app = express();

const myLogger = (req, res, next) => {
  console.log('LOGGED');
  next();
};

app.use(myLogger);

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

app.listen(3000);

환경 변수


환경 변수는 애플리케이션 설정을 관리하는 데 사용됩니다. dotenv 패키지를 사용하여 환경 변수를 설정할 수 있습니다.


npm install dotenv

require('dotenv').config();

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

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

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

.env 파일:


PORT=5000
MONGO_URI=mongodb://localhost:27017/restful-api

에러 처리


Express.js는 기본적으로 에러 처리 미들웨어를 제공합니다. 에러 처리 미들웨어를 사용하여 애플리케이션의 에러를 처리할 수 있습니다.


const express = require('express');
const app = express();

app.get('/', (req, res) => {
  throw new Error('Something went wrong!');
});

app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

app.listen(3000);

결론


Express.js는 RESTful API를 구축하는 데 매우 유용한 프레임워크입니다. 이번 포스팅에서는 Express.js를 사용하여 RESTful API를 구축하는 방법을 단계별로 설명하였습니다. 데이터베이스 모델 정의, 라우터 설정, 미들웨어 사용 등 다양한 기능을 통해 강력한 API를 구축할 수 있습니다. 이 포스팅이 RESTful API를 이해하고 구축하는 데 도움이 되길 바랍니다.

이 포스팅이 도움이 되셨다면, 질문이나 추가 정보가 필요하시면 언제든지 댓글로 남겨주세요.

다음 이전