pgms

[4주차] - [9기] 타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js) 10회차 - 19

Ejah 2026. 1. 29. 19:36

회원과 채널의 관계를 기반으로 API 설계 → 예외 처리 → 테스트까지 진행했다.

 

Router 분리로 구조 정리하기

 

처음에는 모든 API를 app.js에 작성했지만,
기능이 늘어나면 코드 관리가 어려워진다.

그래서 라우터(router)를 분리한다.

 

app.js

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

app.use(express.json());

const channelRouter = require('./routes/channel');
app.use('/channels', channelRouter);

app.listen(1234, () => {
  console.log('Server running on port 1234');
});

/channels 로 시작하는 요청은 모두 channel.js가 처리한다.

 

rename & 모듈 연결, use URL 이해

라우터 파일에서는 URL의 나머지 경로만 작성한다.

const express = require('express');
const router = express.Router();

router.get('/', (req, res) => {
  res.json({ message: '채널 목록 조회' });
});

module.exports = router;
  • 실제 요청 URL: /channels
  • app.use('/channels', router) 덕분에 경로가 합쳐진다

 use()는 공통 URL + 라우터 연결 역할을 한다.

 

회원마다 채널을 가지는 ERD 개념

이번 강의의 핵심 데이터 구조는 다음과 같다.

  • 회원(Member) 1명 → 채널(Channel) 여러 개
  • 채널은 반드시 회원 ID를 가진다

DB 없이 실습에서는 Map 객체로 이를 구현했다.

 

const members = new Map();
const channels = new Map();

 

채널 생성 API 설계 & 테스트

 

채널 생성 API

router.post('/', (req, res) => {
  const { memberId, channelName } = req.body;

  if (!memberId || !channelName) {
    return res.status(400).json({
      message: 'memberId와 channelName이 필요합니다'
    });
  }

  channels.set(channelName, memberId);

  res.status(201).json({
    message: '채널 생성 완료',
    channelName
  });
});

 

요청 예시

POST /channels
{
  "memberId": 1,
  "channelName": "dev-channel"
}

API 설계는 데이터 구조를 그대로 반영해야 한다는 점이 중요하다.

 

회원 채널 조회 & ID 없을 때 예외 처리

회원 ID를 기준으로 채널을 조회한다.

router.get('/:memberId', (req, res) => {
  const memberId = Number(req.params.memberId);

  if (!memberId) {
    return res.status(400).json({
      message: '유효하지 않은 memberId입니다'
    });
  }

  const result = [];

  for (let [channel, ownerId] of channels) {
    if (ownerId === memberId) {
      result.push(channel);
    }
  }

  res.json({
    memberId,
    channels: result
  });
});

존재하지 않는 ID 요청에 대한 처리는 필수다.

 

ID 없을 때 예외 처리 if문 고도화

기존에는 단순히 조건만 체크했지만,
이제는 의도를 분명하게 작성한다.

if (!req.params.memberId) {
  return res.status(400).json({
    message: 'memberId 파라미터가 없습니다'
  });
}

if (result.length === 0) {
  return res.status(404).json({
    message: '해당 회원의 채널이 존재하지 않습니다'
  });
}
  • 요청 오류 → 400
  • 데이터 없음 → 404

상태 코드로 의미를 명확히 전달하는 것이 핵심이다.

 

백엔드 기초 마무리 정리

이번 강의를 통해 배운 핵심은 다음과 같다.

  • 라우터 분리로 구조적인 서버 설계
  • 회원–채널 관계를 고려한 데이터 구조
  • API 설계와 테스트의 중요성
  • 예외 처리를 통한 안정적인 서버 구현

 

express 구조 요약 정리

 

Express는 Node.js 기반의 경량 웹 프레임워크로,
HTTP 요청(Request)과 응답(Response)을 구조적으로 처리할 수 있도록 도와준다.

 

Express 전체 흐름 한눈에 보기

Client
  ↓ (HTTP 요청)
app.js (엔트리 포인트)
  ↓
Middleware
  ↓
Router
  ↓
Controller(Handler)
  ↓
Response

요청은 위에서 아래로 흐르고, 응답은 다시 클라이언트로 돌아간다.

 

app.js (엔트리 포인트)

app.js는 Express 서버의 시작점이다.

역할

  • Express 앱 생성
  • 미들웨어 등록
  • 라우터 연결
  • 서버 실행

예시

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

app.use(express.json());

app.listen(1234, () => {
  console.log('Server running');
});

 

Middleware (미들웨어)

미들웨어는 요청과 응답 사이에서 동작하는 함수다.

역할

  • 요청 데이터 가공
  • 인증/권한 처리
  • 로그 기록
  • 에러 처리

예시

app.use(express.json());

 req → middleware → 다음 처리 구조로 실행된다.

 

Router (라우터)

라우터는 URL별 요청을 분리해서 관리한다.

역할

  • URL 구조 정리
  • 기능별 파일 분리
  • 코드 가독성 향상

예시

const router = express.Router();

router.get('/', (req, res) => {
  res.send('채널 목록');
});

module.exports = router;

 

app.js에서 연결

app.use('/channels', router);

 실제 URL: /channels

 

Request (req) 객체

클라이언트의 요청 정보를 담고 있다.

주요 속성

  • req.params : URL 파라미터
  • req.query : 쿼리 스트링
  • req.body : 요청 바디

예시

router.get('/:id', (req, res) => {
  console.log(req.params.id);
});

Response (res) 객체

서버가 클라이언트에게 응답할 때 사용한다.

주요 메서드

  • res.send() : 문자열 / JSON 응답
  • res.json() : JSON 응답
  • res.status() : 상태 코드 설정

예시

res.status(200).json({ message: '성공' });

Handler (Controller 역할)

라우터에 연결된 실제 로직 처리 함수다.

역할

  • 데이터 처리
  • 비즈니스 로직 실행
  • 응답 반환
router.post('/', (req, res) => {
  // 로직 처리
  res.json({ message: '생성 완료' });
});

 

에러 처리 구조

에러는 미들웨어 형태로 처리한다.

app.use((err, req, res, next) => {
  res.status(500).json({
    message: err.message
  });
});

모든 라우터 이후에 위치해야 한다.

 

Express는 미들웨어 → 라우터 → 핸들러 흐름으로
요청을 처리하는 구조를 가진 웹 프레임워크다.

 

요약 핵심 키워드

  • 엔트리 포인트: app.js
  • 흐름: Request → Middleware → Router → Handler → Response
  • 목적: 구조화 + 유지보수성