API 호출은 실제로 어떻게 작동할까요?: 버튼 클릭부터 서버 응답까지
요약
본 글은 프론트엔드에서 API 호출(`fetch()`)을 사용하는 것이 내부적으로 어떤 과정을 거치는지 상세히 설명합니다. 버튼 클릭부터 시작하여 브라우저가 HTTP 요청(GET/POST 등)을 생성하고, 백엔드가 이를 수신하여 데이터베이스 쿼리를 수행한 후, 최종적으로 JSON 형태로 응답이 돌아오는 전체 여정을 분석합니다.
핵심 포인트
- API 호출은 단순한 함수 호출이 아니라 복잡한 네트워크 통신 과정이다.
- 브라우저는 HTTP 메서드(GET, POST 등)를 사용하여 요청의 종류와 목적을 정의한다.
- 백엔드는 라우팅(`@app.get`)을 통해 특정 경로의 요청을 처리할 함수를 매칭시킨다.
- 데이터베이스는 백엔드의 요청에 따라 쿼리를 수행하고 결과를 JSON 형태로 변환하여 전달한다.
React, Next.js 또는 다른 프론트엔드 프레임워크를 사용해 본 적이 있다면, 아마도 다음과 같은 코드를 작성해 봤을 겁니다:
const response = await fetch("/api/users");
const data = await response.json();
간단해 보이죠?
하지만 저는 예전에 궁금했습니다:
fetch()를 호출한 후 실제로 무슨 일이 일어날까요?
요청은 어디로 갈까요?
제가 무엇을 원하는지 백엔드는 어떻게 알까요?
데이터베이스는 어디에 관련될까요?
그리고 응답은 어떻게 제 UI로 돌아올까요?
하나의 API 호출 전체 여정을 분석해 봅시다.
큰 그림 (The Big Picture)
버튼이 있다고 상상해 보세요:
<button onclick="getUsers()">
Get Users
</button>
사용자가 이 버튼을 클릭하면 흐름은 대략 다음과 같습니다:
Button Click
↓
Frontend JavaScript
...
끝입니다.
이제 각 단계에서 실제로 무슨 일이 일어나고 있는지 살펴보겠습니다.
1. 버튼 클릭 (The Button Click)
사용자 목록을 가져오고 싶다고 가정해 봅시다.
async function getUsers() {
const response = await fetch(
...
중요한 줄은 다음과 같습니다:
fetch("http://localhost:8000/api/users")
우리는 기본적으로 브라우저에게 이렇게 말하는 것입니다:
"이 API로 요청을 보내고, 돌아오는 모든 것을 나에게 줘."
2. 브라우저가 HTTP 요청을 전송 (The Browser Sends an HTTP Request)
단순한 fetch() 호출 뒤에서, 브라우저는 HTTP 요청을 생성합니다.
다음과 같은 형태입니다:
GET /api/users
GET은 HTTP 메서드입니다.
일반적인 메서드는 다음과 같습니다:
GET → 데이터를 가져옴 (Get data)
POST → 데이터를 생성함 (Create data)
PUT → 데이터를 대체함 (Replace data)
...
따라서:
GET /api/users
은 기본적으로 다음과 같은 의미입니다:
"사용자들을 나에게 줘."
3. 백엔드가 수신 (The Backend Receives It)
이제 우리의 백엔드가 FastAPI를 사용해 구축되었다고 상상해 봅시다.
from fastapi import FastAPI
app = FastAPI()
...
이 줄:
@app.get("/api/users")
은 기본적으로 백엔드에게 다음과 같이 말하는 것입니다:
"누군가
/api/users로 GET 요청을 보내면, 이 함수를 실행해."
따라서 우리의 요청:
GET /api/users
은 이 함수를 찾습니다:
def get_users():
# ...
4. 데이터베이스는요? (What About the Database?)
실제 애플리케이션에서는 당연히 사용자 정보를 하드코딩하지 않을 것입니다.
백엔드는 아마 데이터베이스에 쿼리할 것입니다.
예를 들어:
SELECT * FROM users;
데이터베이스는 다음과 같은 결과를 반환할 수 있습니다:
1 | Agrima
2 | Rahul
3 | Priya
이후 백엔드는 이를 보통 JSON 형태의 응답으로 변환합니다:
[
{
"id": 1,
...
이제 우리의 흐름은 다음과 같습니다:
Frontend
↓
API 요청
...
5. 응답이 돌아올 때 (The Response Comes Back)
백엔드는 HTTP 응답을 보냅니다.
예를 들어:
200 OK
Content-Type: application/json
다음과 함께요:
[
{
"id": 1,
...
여기서 프런트엔드가 데이터를 받게 됩니다.
기억나시죠?
const response = await fetch("/api/users");
이제 우리는 다음을 수행합니다:
const data = await response.json();
그리고 data는 다음과 같이 됩니다:
[
{ id: 1, name: "Agrima" },
{ id: 2, name: "Rahul" }
...
마침내 이를 UI에서 사용할 수 있게 되었습니다.
6. await는 실제로 무엇을 할까요?
이것은 제가 시작했을 때 혼란스러웠던 또 다른 부분이었습니다.
API 요청에는 시간이 걸립니다.
어쩌면:
50ms
200ms
1 second
JavaScript는 응답이 즉시 도착할 것이라고 가정할 수 없습니다.
그래서 우리는 다음을 사용합니다:
await fetch(...)
우리는 기본적으로 이렇게 말하는 것입니다:
"요청을 보내고, 이 함수를 계속하기 전에 응답을 기다려라."
이것이 API 호출이 일반적으로 async/await와 함께 작성되는 이유입니다.
7. API가 실패하면 어떻게 될까요?
문제가 생깁니다. 많이요.
어쩌면 서버가 다운되었을 수도 있습니다.
어쩌면 URL이 잘못되었을 수도 있습니다.
어쩌면 사용자가 인증되지 않았을 수도 있습니다.
어쩌면 백엔드가 충돌했을 수도 있습니다.
그러니 모든 것이 항상 작동할 것이라고 가정하고 API 호출을 작성하지 마세요.
기본 패턴은 다음과 같습니다:
async function getUsers() {
try {
...
자주 보게 될 몇 가지 상태 코드가 있습니다:
200 → 성공 (Success)
201 → 생성됨 (Created)
400 → 잘못된 요청 (Bad Request)
...
전체 흐름 (The Complete Flow)
그래서 그 작은 한 줄:
fetch("/api/users")
실제로는 훨씬 더 큰 프로세스를 트리거합니다:
사용자(USER)
│
↓
...
이것이 기본적으로 **요청-응답 주기 (request-response cycle)**입니다.
또 다른 실제 예시 (One More Real-World Example)
AI 노트 앱을 생각해 보세요.
당신은 다음과 같이 입력합니다:
"이 노트를 요약해 줘"
그리고 요약하기(Summarize) 버튼을 클릭합니다.
비하인드 스토리:
You가 "요약하기"를 클릭함
↓
Next.js 프론트엔드
...
당신은 버튼과 결과만 보게 됩니다.
하지만 그 밑에서는 여러 시스템들이 서로 대화하고 있습니다.
이것이 제가 API에 대해 가장 흥미롭다고 느끼는 부분입니다.
최종 요약
API 호출이란 단순히 다음과 같은 것이 아닙니다:
fetch("/api/users");
그것은 애플리케이션의 서로 다른 부분들 간의 대화입니다.
클라이언트 → 요청(Request) → 서버 → 처리(Process) → 응답(Response) → 클라이언트
이 흐름을 이해하게 되면, REST API, Axios, FastAPI, Express, 인증(authentication), CORS, 그리고 심지어 AI API 같은 것들이 훨씬 더 명확해지기 시작합니다.
따라서 다음에 다음과 같이 작성할 때:
await fetch(...)
당신은 그 한 줄의 코드 뒤에서 실제로 무슨 일이 일어나고 있는지 알게 될 것입니다. 🚀
만약 지금 API를 배우고 있다면, 이것을 시도해 보세요: 단지 세 개의 엔드포인트만을 가진 아주 작은 프론트엔드 + 백엔드를 구축하는 것입니다:
GET /users
POST /users
DELETE /users/:id
열 개의 API 튜토리얼을 읽는 것보다 이 세 개의 엔드포인트를 직접 만들어 보는 것이 더 많이 배울 수 있는 방법입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기