본문 바로가기
개발/웹 개발

Day 24: 백엔드의 역할과 책임

1. 오늘의 학습 목표

학습 목표: 웹 서비스를 구성하는 가장 기본적인 구조인 클라이언트-서버 아키텍처를 이해합니다. 사용자의 눈에 보이지 않는 영역인 백엔드(서버)가 어떤 역할을 수행하며, 왜 필수적인지 그 책임을 명확히 설명할 수 있습니다.

 

핵심 요약: 지금까지 우리가 배운 프론트엔드가 웹의 '얼굴'이라면, 백엔드는 웹의 '두뇌와 창고'입니다. 백엔드는 웹 서비스의 핵심 로직, 데이터, 보안을 모두 책임집니다.


2. 핵심 개념 파헤치기

2.1. 클라이언트-서버 아키텍처란?

웹은 기본적으로 '요청'과 '응답'으로 동작합니다. 여기서 서비스를 요청하는 쪽클라이언트(Client), 요청을 받아 서비스를 제공하는 쪽을 서버(Server)라고 부르며, 이렇게 역할이 분리된 구조를 클라이언트-서버 아키텍처라고 합니다.

  • 클라이언트(Client): 우리가 지금까지 배운 HTML, CSS, JavaScript로 만들어진 웹 브라우저 화면이 바로 클라이언트입니다. 사용자와 직접 상호작용하며, 필요한 데이터나 기능이 있을 때 서버에 요청을 보냅니다
  • 서버(Server): 클라이언트의 요청을 받아 처리하는 컴퓨터 또는 프로그램입니다. 데이터베이스 조회, 비즈니스 로직 수행, 인증 처리 등 보이지 않는 곳에서 실제 작업을 수행하고 그 결과를 클라이언트에게 응답으로 보내줍니다.

2.2. 백엔드의 주요 책임

백엔드 서버는 아래와 같은 책임을 가집니다

  1. API 제공 : 클라이언트가 정해진 규칙(HTTP, REST API 등)에 따라 서버의 데이터나 기능에 접근할 수 있도록 통신 창구를 제공합니다
  2. 비즈니스 로직 처리 : 웹 서비스의 핵심적인 규칙과 절차를 처리합니다. 예를 들어, 쇼핑몰의 주문 처리, 게시판의 글 작성/수정/삭제 로직 등이 모두 여기에 해당합니다.
  3. 데이터베이스 관리 : 사용자의 정보, 게시글, 상품 목록 등 모든 데이터를 데이터베이스에 안전하게 저장, 조회, 수정, 삭제(CRUD)하는 역할을 합니다
  4. 인증 및 보안 : 사용자가 누구인지 확인(인증)하고, 각 사용자의 권한에 맞는 데이터와 기능에만 접근하도록 제어(인가)합니다. 또한 외부의 악의적인 공격으로부터 시스템을 보호합니다.

3. 코드로 배우기

3.1. 구현 목표

클라이언트가 서버에 데이터를 요청하고, 서버가 그에 응답하는 과정을 개념적인 코드로 표현하여 클라이언트와 서버의 역할을 명확히 구분합니다.

 

3.2. [1단계: 클라이언트의 요청 코드 (프론트엔드)]

브라우저에서 실행되는 JavaScript 코드입니다. fetch API를 사용해 서버의 /api/users/1 주소로 "1번 사용자 정보를 주세요"라고 요청을 보냅니다.

// Client-side (e.g., in a React component)

fetch('[https://api.example.com/api/users/1](https://api.example.com/api/users/1)')
  .then(response => response.json())
  .then(data => {
    console.log('서버로부터 받은 사용자 정보:', data);
    // 이 데이터를 사용해 화면에 프로필을 그린다.
  })
  .catch(error => console.error('요청 실패:', error));

 

3.3. [2단계: 서버의 응답 코드 (백엔드)]

서버에서 실행되는 코드입니다. (Node.js Express 프레임워크의 의사 코드) 클라이언트의 요청을 받아, 데이터베이스에서 1번 사용자를 찾아 JSON 형태로 응답합니다.

//Server-side (e.g., in a Node.js/Express server)

//'/api/users/1' 경로로 GET 요청이 들어왔을 때의 처리
app.get('/api/users/:id', (req, res) => {
  const userId = req.params.id;      //클라이언트가 요청한 id는 '1'

     //1. 데이터베이스에서 해당 id의 사용자를 찾는다
  const user = db.users.findById(userId);

   //2. 사용자를 찾았으면
  if (user) {
      //3. 사용자 정보를 JSON 형태로 응답한다
    res.json(user);
  } else {
     //4. 사용자가 없으면 404 에러를 응답한다
    res.status(404).send('User not found');
  }
});

4. 전체 코드 

 

//--- 역할 구분 ---

//[ 클라이언트 측 코드: 브라우저에서 실행 ]
//역할: 서버에 데이터를 요청하고, 받은 데이터를 화면에 표시한다.
function displayUserProfile() {
  fetch('[https://api.example.com/api/users/1](https://api.example.com/api/users/1)')
    .then(res => res.json())
    .then(user => {
      document.body.innerHTML = `<h1>${user.name}</h1><p>${user.email}</p>`;
    });
}


//[ 서버 측 코드: 서버 컴퓨터에서 실행 ]
//역할: 요청을 '처리'하고, 데이터베이스와 상호작용하며, 결과를 '응답'한다.
const express = require('express');
const app = express();

app.get('/api/users/:id', (req, res) => {
  const requestedUserId = req.params.id;
  
  //데이터베이스에서 사용자를 찾는 로직 (의사 코드)
  const userData = findUserInDatabase(requestedUserId);

  if (userData) {
    res.json(userData); // { id: 1, name: 'Alice', email: 'alice@example.com' }
  } else {
    res.status(404).json({ error: 'Not Found' });
  }
});

app.listen(3000);