๋ชฉ์ฐจ
๋ฐฑ์๋ ๊ฐ๋ฐ์ ์์ํ๋ ค๋ฉด ๊ฐ์ฅ ๋จผ์ ์ดํดํด์ผ ํ ๊ฒ์ด ๋ฐ๋ก ์น์ ๋์ ์๋ฆฌ์ ๋๋ค.
์ฐ๋ฆฌ๊ฐ ๋งค์ผ ์ฌ์ฉํ๋ ์น ์๋น์ค๊ฐ ์ด๋ป๊ฒ ์๋ํ๋์ง, ํด๋ผ์ด์ธํธ์ ์๋ฒ๊ฐ ์ด๋ป๊ฒ ์ํตํ๋์ง ์์์ผ ๊ฒฌ๊ณ ํ ๋ฐฑ์๋๋ฅผ ์ค๊ณํ ์ ์์ฃ .
์ด๋ฒ ๊ธ์์๋ ์น์ ๊ธฐ๋ณธ ๊ฐ๋ ๋ถํฐ HTTP, ๊ทธ๋ฆฌ๊ณ ํ๋ ์น ๊ฐ๋ฐ์ ํต์ฌ์ธ RESTful API๊น์ง ์ฐจ๊ทผ์ฐจ๊ทผ ์ ๋ฆฌํด๋ณด๊ฒ ์ต๋๋ค.
๐ ์น์ ์ด๋ป๊ฒ ์๋ํ ๊น?
์น(Web)์ World Wide Web์ ์ค์๋ง๋ก, ์ธํฐ๋ท์์์ ์ ๋ณด๋ฅผ ๊ณต์ ํ๊ธฐ ์ํ ์์คํ ์ ๋๋ค.
์น์ ํต์ฌ์ HTTP(HyperText Transfer Protocol)๋ผ๋ ํต์ ๊ท์ฝ์ ํตํด ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋๋ค๋ ์ ์ด์์.
์ฆ, ์ฐ๋ฆฌ๊ฐ ๋ธ๋ผ์ฐ์ ์์ ์น์ฌ์ดํธ๋ฅผ ๋ณผ ๋๋ง๋ค HTTP ์์ฒญ์ ๋ณด๋ด๊ณ ์๋ต์ ๋ฐ๋ ๊ณผ์ ์ ๋ฐ๋ณตํ๊ณ ์๋ ์ ์ ๋๋ค.
๐ ํด๋ผ์ด์ธํธ-์๋ฒ ๋ชจ๋ธ์ด๋?
์น์ ๊ธฐ๋ณธ์ ์ผ๋ก ํด๋ผ์ด์ธํธ-์๋ฒ ๊ตฌ์กฐ(Client-Server Model)๋ก ์๋ํฉ๋๋ค.
- ํด๋ผ์ด์ธํธ(Client): ์น ๋ธ๋ผ์ฐ์ ๋ ๋ชจ๋ฐ์ผ ์ฑ์ฒ๋ผ ์๋น์ค๋ฅผ ์์ฒญํ๋ ์ชฝ
- ์๋ฒ(Server): ์์ฒญ์ ๋ฐ๊ณ , ์ฒ๋ฆฌํ ํ ์๋ต์ ๋๋ ค์ฃผ๋ ์ชฝ
์ฌ์ฉ์๊ฐ ์น ๋ธ๋ผ์ฐ์ ์์ URL์ ์ ๋ ฅํ๋ฉด ํด๋ผ์ด์ธํธ๋ HTTP ์์ฒญ์ ์๋ฒ์ ๋ณด๋ด๊ณ , ์๋ฒ๋ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ(HTML, JSON ๋ฑ)๋ฅผ ์๋ตํฉ๋๋ค.
๐ฆ ๋น์ ํ์๋ฉด?
- ํด๋ผ์ด์ธํธ๋ ๋ ์คํ ๋์ ์๋
- ์๋ฒ๋ ์ฃผ๋ฐฉ์ ์ฃผ๋ฌธ์ ๋ฃ๊ณ ์๋ฆฌ๋ฅผ ๋ด์ด์ฃผ๋ ์ข ์ ์
- DB๋ ์ฌ๋ฃ๋ฅผ ๋ณด๊ดํ๋ ์ฐฝ๊ณ
๐ก HTTP ์์ฒญ/์๋ต ๊ตฌ์กฐ์ ๋ฉ์๋
HTTP๋ ํด๋ผ์ด์ธํธ์ ์๋ฒ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๊ธฐ ์ํ ๊ท์น์ ๋๋ค.
๋ชจ๋ HTTP ํต์ ์ ์์ฒญ(Request)๊ณผ ์๋ต(Response) ์์ผ๋ก ์ด๋ฃจ์ด์ ธ์.
HTTP ์์ฒญ ์์
POST /api/users HTTP/1.1
Host: example.com
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
{
"name": "๊น๊ฐ๋ฐ",
"email": "dev@example.com"
}
์์ฒญ ๊ตฌ์ฑ ์์
- ์์ฒญ ๋ผ์ธ: HTTP ๋ฉ์๋ + URL ๊ฒฝ๋ก + HTTP ๋ฒ์
- ํค๋: ์์ฒญ์ ๋ํ ์ถ๊ฐ ์ ๋ณด
- ๋ฐ๋: ์๋ฒ์ ์ ์กํ ๋ฐ์ดํฐ (GET ์์ฒญ์๋ ๋ณดํต ์์)
HTTP ์๋ต ๊ตฌ์กฐ
HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/users/123
{
"id": 123,
"name": "๊น๊ฐ๋ฐ",
"email": "dev@example.com",
"created_at": "2025-01-15T10:00:00Z"
}
์ฃผ์ HTTP ๋ฉ์๋
๋ฉ์๋ | ์ค๋ช |
GET | ๋ฐ์ดํฐ๋ฅผ ์กฐํํ ๋ ์ฌ์ฉ |
POST | ๋ฐ์ดํฐ๋ฅผ ์๋ก ์์ฑํ ๋ ์ฌ์ฉ |
PUT | ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ์์ ํ ๋ ์ฌ์ฉ |
PATCH | ์ผ๋ถ ๋ฐ์ดํฐ๋ฅผ ์์ ํ ๋ ์ฌ์ฉ |
DELETE | ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํ ๋ ์ฌ์ฉ |
๐ HTTP ์ํ์ฝ๋
์๋ฒ๋ ์๋ต๊ณผ ํจ๊ป HTTP ์ํ ์ฝ๋๋ฅผ ๋ณด๋ด ํด๋ผ์ด์ธํธ์๊ฒ ๊ฒฐ๊ณผ๋ฅผ ์๋ ค์ค๋๋ค.
200๋ฒ ๋๋ ์ฑ๊ณต, 400๋ฒ๋๋ ํด๋ผ์ด์ธํธ ์ค๋ฅ, 500๋ฒ๋๋ ์๋ฒ ์ค๋ฅ๋ฅผ ๋ํ๋ ๋๋ค.
์ฃผ์ ์ํ ์ฝ๋
์ํ ์ฝ๋ |
์๋ฏธ |
200 OK | ์์ฒญ์ด ์ฑ๊ณต์ ์ผ๋ก ์ฒ๋ฆฌ๋จ |
201 Created | ๋ฆฌ์์ค ์์ฑ ์ฑ๊ณต |
204 No Content | ์๋ต ๋ณธ๋ฌธ ์์ (์: ์ญ์ ์ฑ๊ณต) |
400 Bad Request | ์๋ชป๋ ์์ฒญ |
401 Unauthorized | ์ธ์ฆ ์คํจ |
403 Forbidden | ๊ถํ ์์ |
404 Not Found | ์กด์ฌํ์ง ์๋ ๋ฆฌ์์ค |
500 Internal Server Error | ์๋ฒ ๋ด๋ถ ์ค๋ฅ |
์ํ ์ฝ๋๋ง ์ ์ฝ์ด๋ ๋ฌธ์ ๋ฅผ ๋น ๋ฅด๊ฒ ํ์ ํ ์ ์์ด์!
๐ฏ RESTful API๋?
REST(Representational State Transfer)๋ ์น์ ๊ธฐ๋ณธ ์์น์ ๋ฐ๋ผ API๋ฅผ ์ค๊ณํ๋ ๋ฐฉ์์ ๋๋ค.
REST ์คํ์ผ์ ๋ฐ๋ฅด๋ API๋ฅผ RESTful API๋ผ๊ณ ๋ถ๋ฆ ๋๋ค.
REST ์ค๊ณ์ ํต์ฌ ์์น
1. ์์(Resource) ๊ธฐ๋ฐ
- URL์ ์์์ ํํํด์ผ ํจ
- ์: /users, /products/1, /posts/12/comments
2. HTTP ๋ฉ์๋๋ฅผ ํตํ ํ์ ํํ
- GET /users → ์ฌ์ฉ์ ๋ชฉ๋ก ์กฐํ
- POST /users → ์ฌ์ฉ์ ์์ฑ
- DELETE /users/1 → ์ฌ์ฉ์ ์ญ์
3. ๋ฌด์ํ์ฑ(Stateless)
- ์๋ฒ๋ ํด๋ผ์ด์ธํธ์ ์ํ๋ฅผ ์ ์ฅํ์ง ์์
- ๊ฐ ์์ฒญ์ ๋ ๋ฆฝ์ ์ด์ด์ผ ํจ
4. ํ์ค ์๋ต ํ์(JSON)
- ์๋ต์ ์ผ๊ด๋ ๊ตฌ์กฐ(JSON)๋ฅผ ๊ฐ๋๋ก ์ค๊ณ
๐ก RESTfulํ์ง ์์ ์
โ GET /createUser?id=1
โ POST /getUserList
โ GET /deleteUser?id=123
โญ POST /users
โญ GET /users
โญ DELETE /users/123
๐ API ๋ฌธ์ํ ๋ฐฉ๋ฒ
์ค์ ํ๋ก์ ํธ์์๋ ๊ฐ๋ฐ์ ๊ฐ์ ํ์ ์ ์ํด API๋ฅผ ๋ฌธ์ํํ๋ ๊ฒ์ด ๋งค์ฐ ์ค์ํฉ๋๋ค.
API ๋ช ์ธ๊ฐ ๋ช ํํ๋ฉด, ๊ฐ๋ฐ์๋ฟ ์๋๋ผ QA, ํ๋ก ํธ์๋, ๊ธฐํ์๋ ์ดํดํ๊ธฐ ์ฌ์์.
Swagger (OpenAPI)
- ๊ฐ์ฅ ๋๋ฆฌ ์ฌ์ฉ๋๋ ๋ฌธ์ํ ๋๊ตฌ
- ์ฝ๋์ ์ด๋ ธํ ์ด์ ์ ์ถ๊ฐํ๋ฉด ๋ฌธ์๊ฐ ์๋ ์์ฑ๋จ
- YAML ๋๋ JSON ๊ธฐ๋ฐ
paths:
/users:
get:
summary: Get user list
responses:
'200':
description: Success
Spring Rest Docs
- ํ ์คํธ ์ฝ๋ ๊ธฐ๋ฐ์ผ๋ก API ๋ฌธ์๋ฅผ ์์ฑ
- ํ ์คํธ๊ฐ ํต๊ณผํด์ผ๋ง ๋ฌธ์๊ฐ ๋ง๋ค์ด์ ธ ์ ๋ขฐ๋๊ฐ ๋์
- Spring ๊ธฐ๋ฐ ํ๋ก์ ํธ์์ ๋ง์ด ์ฌ์ฉ๋จ
mockMvc.perform(get("/users"))
.andDo(document("get-users",
responseFields(
fieldWithPath("[].id").description("์ฌ์ฉ์ ID"),
fieldWithPath("[].name").description("์ฌ์ฉ์ ์ด๋ฆ")
)
));
๐งก ๋ง๋ฌด๋ฆฌํ๋ฉฐ
์ด๋ฒ ๊ธ์์๋ ๋ฐฑ์๋ ๊ฐ๋ฐ์ ๊ธฐ์ด ์ค ๊ธฐ์ด์ธ ์น์ ๊ตฌ์กฐ์ HTTP์ ๋ํด ์์๋ณด์์ต๋๋ค.
โ๏ธ ํต์ฌ ํฌ์ธํธ ์ ๋ฆฌ
- ํด๋ผ์ด์ธํธ-์๋ฒ ๋ชจ๋ธ: ์์ฒญ๊ณผ ์๋ต์ ๊ธฐ๋ณธ ๊ตฌ์กฐ
- HTTP ๋ฉ์๋: ๊ฐ ๋ฉ์๋์ ๋ชฉ์ ์ ๋ง๋ ์ฌ์ฉ๋ฒ
- ์ํ์ฝ๋: ์ ์ ํ ์ํ์ฝ๋๋ก ๋ช ํํ ์๋ต ์ ๋ฌ
- RESTful API: ์ผ๊ด๋๊ณ ์์ธก ๊ฐ๋ฅํ API ์ค๊ณ ์์น
- API ๋ฌธ์ํ: ๊ฐ๋ฐ์ ์นํ์ ์ธ ๋ฌธ์ ์์ฑ์ ์ค์์ฑ
์ด ๊ฐ๋ ๋ค์ ์ ํํ ์ดํดํ๋ฉด, ์ค์ API๋ฅผ ์ค๊ณํ๊ฑฐ๋ ๋๋ฒ๊น ํ ๋ ํฐ ๋์์ด ๋ฉ๋๋ค.
๋ค์ ๊ธ์์๋ ์ค์ API๋ฅผ ๊ตฌํํ๋ฉฐ ์ด ๊ฐ๋ ๋ค์ด ์ด๋ป๊ฒ ํ์ฉ๋๋์ง ๊ตฌ์ฒด์ ์ผ๋ก ์ดํด๋ณผ ์์ ์ ๋๋ค.
๊ถ๊ธํ ์ ์ด๋ ์๊ฒฌ์ ๋๊ธ๋ก ๋จ๊ฒจ์ฃผ์ธ์! ๐
'๐ฅ๏ธ Backend' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๐ง ๋ฐฑ์๋ ๊ฐ๋ฐ์๋ฅผ ์ํ JPA ํต์ฌ ์ ๋ฆฌ (0) | 2025.05.30 |
---|---|
๐ฑ Spring ํต์ฌ ๊ฐ๋ ๋ง์คํฐํ๊ธฐ (0) | 2025.05.29 |
๐ ๏ธ ๋ฐฑ์๋ ๊ฐ๋ฐ ํ๊ฒฝ ์ค์ A to Z (0) | 2025.05.28 |
๐ป ๋ฐฑ์๋๋ ๋ฌด์์ธ๊ฐ? (0) | 2025.05.20 |