1. API란 무엇인가
API(Application Programming Interface)는 애플리케이션을 프로그래밍할 때 복잡한 내부 구현을 숨기고 필요한 기능만 제공하는 도구다. console.log(), print()처럼 내부 동작을 몰라도 함수만 호출하면 된다.
어려운 것은 감추고 쉽게 상호작용할 수 있게 해주는 것이 인터페이스고, API는 그 개념을 애플리케이션 영역으로 가져온 것이다.
클라이언트-서버 통신에서의 API는 이 개념의 부분 집합이다. 서버가 어떻게 데이터를 처리하는지는 몰라도, 정해진 URL과 HTTP 메서드로 요청하면 약속된 응답이 돌아온다.
요청 흐름: 클라이언트(Browser/App) → HTTP 요청 → API Server(Express/Node.js) → 쿼리 → Database → 결과 → JSON 응답(200/400/500)
클라이언트는 API의 내부 구현을 알 필요 없이 약속된 요청만 보내면 된다.
2. REST API 설계 규칙
REST(Representational State Transfer)는 HTTP를 기반으로 한 웹 서비스 아키텍처 스타일이다. API Endpoint는 HTTP 메서드 + URL의 조합으로 정의된다.
URI 설계 규칙 6가지
- 동사 금지, 명사 사용 —
/users/login→POST /users - 하이픈 사용, 언더스코어 금지 —
/user-profile(O) //user_profile(X) - 복수 명사 사용 —
/users,/stores,/reviews - 단일 리소스는 ID로 —
/users/{userId} - 계층 관계는 URI에 표현 —
/stores/{storeId}/reviews - 소문자만 사용
| Bad 예시 | Good 예시 | 이유 |
|---|---|---|
/getUsers |
GET /users |
동사 사용 금지 |
/user/delete/1 |
DELETE /users/1 |
HTTP 메서드로 행위 표현 |
/Users |
/users |
소문자 사용 |
/user_list |
/users |
하이픈 사용, 복수형 |
/users/1/posts/2/comments/3 |
/posts/2/comments |
2단계 이하 권장 |
계층 관계 표현
/users/{userId}/posts— 특정 유저의 게시글/posts/{postId}/comments— 특정 게시글의 댓글
2단계 이상 중첩은 /comments/{commentId}처럼 독립 리소스로 분리한다.
HTTP 메서드와 CRUD 매핑
| 메서드 | CRUD | 예시 | 설명 |
|---|---|---|---|
| POST | Create | POST /users |
새 리소스 생성 |
| GET | Read | GET /users/{userId} |
리소스 조회 |
| PUT | Update (전체) | PUT /users/{userId} |
리소스 전체 교체 |
| PATCH | Update (일부) | PATCH /users/{userId}/nickname |
리소스 일부 수정 |
| DELETE | Delete | DELETE /users/{userId} |
리소스 삭제 |
주요 HTTP 상태 코드
| 코드 | 이름 | 의미 |
|---|---|---|
| 200 | OK | 요청 성공 |
| 201 | Created | 리소스 생성 성공 |
| 204 | No Content | 성공했지만 반환할 데이터 없음 (DELETE 등) |
| 400 | Bad Request | 잘못된 요청 (유효성 검사 실패 등) |
| 401 | Unauthorized | 인증 필요 (로그인하지 않음) |
| 403 | Forbidden | 인증은 됐지만 권한 없음 |
| 404 | Not Found | 리소스를 찾을 수 없음 |
| 409 | Conflict | 리소스 충돌 (이미 존재하는 이메일 등) |
| 500 | Internal Server Error | 서버 내부 오류 |
3. Path Variable vs Query String
두 방식 모두 클라이언트가 서버에 추가 정보를 전달하는 수단이지만, 용도가 다르다.
| 구분 | Path Variable | Query String |
|---|---|---|
| 형식 | /users/42 |
/users?region=seoul&limit=20 |
| 용도 | 특정 리소스를 식별할 때 사용 | 필터링, 정렬, 페이지네이션에 사용 |
| 없을 경우 | 404 오류 발생 | 없어도 요청 성공 |
| 예시 | 특정 유저, 특정 게시글 | 검색 조건, 목록 필터 |
특정 1개를 집어야 한다면 Path Variable, 조건을 걸어 여러 개를 추릴 때는 Query String을 선택한다.
4. Request Body와 Request Header
HTTP 요청에는 URL 외에 Body와 Header를 통해 추가 데이터를 전달할 수 있다.
Request Body
POST / PUT / PATCH 요청에서 전송하는 데이터다. JSON 형식이 일반적이며, Content-Type: application/json 헤더와 함께 사용한다.
{
"email": "user@example.com",
"password": "secret123"
}
Request Header
요청의 메타데이터를 담는다. 주요 헤더는 다음과 같다.
| 헤더 | 역할 |
|---|---|
Content-Type: application/json |
Body 데이터의 형식을 지정한다 |
Authorization: Bearer {token} |
인증 토큰을 서버에 전달한다 |
5. API 명세서 작성
API 명세서는 프론트엔드 개발자가 API를 사용하기 쉽도록 돕는 문서다. 백엔드와 프론트엔드가 협업하는 모든 프로젝트에서 필수적이다.
명세서 구성 요소
- Endpoint — HTTP 메서드 + URL
- Request — Body / Query String / Path Variable / Header
- Response — 성공 시 반환 데이터 구조 (JSON)
- Status Code — 200 OK / 201 Created / 400 Bad Request / 401 Unauthorized / 500 Internal Server Error
- Error Cases — 에러 코드와 메시지 목록
응답 형식 통일
팀 전체가 동일한 응답 구조를 사용하면 프론트엔드와의 협업이 쉬워진다.
{
"resultType": "SUCCESS",
"error": null,
"success": {
"id": 1,
"email": "test@example.com",
"name": "홍길동"
}
}
실패 응답은 다음과 같은 구조를 사용한다.
{
"resultType": "FAILURE",
"error": {
"errorCode": "U001",
"reason": "이미 존재하는 이메일이다.",
"data": null
},
"success": null
}
회원가입 API 명세 예시
| 항목 | 내용 |
|---|---|
| Endpoint | POST /api/v1/users/signup |
| Content-Type | application/json |
| Request Body | email: string password: string name: string |
| Response 200 | { "result": "success", "data": { "userId": 1 } } |
| Error Cases | E4001: 이미 가입된 이메일 E4002: 비밀번호 형식 오류 E5000: 서버 오류 |
API 버전 관리
/api/v1/...처럼 URL에 버전을 포함하면 v2를 출시할 때 기존 클라이언트가 v1을 계속 사용할 수 있어 하위 호환성을 유지할 수 있다.
6. Express 5 프로젝트 세팅
Node.js 22 LTS 설치 후 다음 순서로 프로젝트를 초기화한다.
패키지 설치
npm init -y
npm install express@^5.0.0
npm install --save-dev nodemon
Nodemon은 파일 변경을 감지하면 서버를 자동으로 재시작하는 도구이다. --watch src 옵션으로 특정 폴더만 감시할 수 있다.
{
"scripts": {
"dev": "nodemon --watch src src/index.js",
"start": "node src/index.js"
}
}
package.json 설정
package.json에 "type": "module"을 추가하면 .js 파일에서 import/export 문법을 사용할 수 있다. 이 설정 없이는 CommonJS 방식(require)을 사용해야 한다.
{
"type": "module",
"scripts": {
"dev": "nodemon --watch src src/index.js",
"start": "node src/index.js"
}
}
import express from 'express';
import dotenv from 'dotenv';
dotenv.config();
const app = express();
src/index.js
import express from 'express'
const app = express()
const PORT = process.env.PORT ?? 3000
app.use(express.json())
app.get('/', (req, res) => {
res.send('Hello World')
})
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`)
})
Express 5는 async 핸들러에서 발생한 오류를 자동으로 next(err)로 전달한다. try/catch 없이도 에러 미들웨어가 작동한다는 것이 Express 4와의 가장 큰 차이다.
핵심 키워드
REST (Representational State Transfer)
HTTP를 기반으로 한 웹 서비스 아키텍처 스타일이다. 자원(Resource), 행위(Verb), 표현(Representation)의 세 가지 요소로 구성된다.
API Endpoint
HTTP 메서드 + URL 조합으로 하나의 기능을 가리키는 주소다. POST /users와 GET /users는 URL이 같아도 서로 다른 Endpoint다.
Path Variable
URI 경로에 포함된 동적 값이다 (/users/{userId}). 특정 리소스를 식별하는 데 사용하며, 값이 없으면 404를 반환한다.
Query String
URL 뒤에 ?key=value 형태로 붙는 선택적 파라미터다. 필터링, 정렬, 페이지네이션에 사용하며 없어도 요청은 성공한다.
Request Body
POST / PUT / PATCH 요청 시 함께 보내는 데이터다. JSON 형식이 일반적이며 Content-Type: application/json 헤더와 함께 전송한다.
API 명세서
Endpoint, 요청/응답 구조, 상태 코드, 오류 케이스를 문서화한 것이다. 프론트엔드와 백엔드가 동시에 개발할 수 있도록 인터페이스를 미리 합의하는 역할을 한다.
'Study > Node.JS' 카테고리의 다른 글
| [Node.js / Express 5] Express API 개발 실습 (0) | 2026.04.01 |
|---|---|
| [Node.js / Express 5] Node.js 핵심 개념과 프로젝트 구조 (0) | 2026.04.01 |
| [Node.js / Express 5] 실전 SQL과 페이지네이션 (0) | 2026.03.25 |
| [Node.js / Express 5] SQL 기초 문법과 정규화 (0) | 2026.03.25 |
| [Node.js / Express 5] Database 설계 기초 (0) | 2026.03.25 |
