๐ ๊น์ํ ๋์ "๋ชจ๋ ๊ฐ๋ฐ์๋ฅผ ์ํ HTTP ์น ๊ธฐ๋ณธ ์ง์" ๊ฐ์ ๋ฃ๊ณ ์ ๋ฆฌ
๐ํด๋ผ์ด์ธํธ์์ ์๋ฒ๋ก ๋ฐ์ดํฐ ์ ์ก
ํด๋ผ์ด์ธํธ์์ ์๋ฒ๋ก ๋ฐ์ดํฐ ์ ๋ฌํ๋ ๋ฐฉ์์ ํฌ๊ฒ 2๊ฐ์ง ์ด๋ค.
1. ์ ๋ฌ๋ฐฉ์
- ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ฅผ ํตํ ๋ฐ์ดํฐ ์ ์ก
- GET
- ์ฃผ๋ก ์ ๋ ฌ ํํฐ(๊ฒ์์ด)
- ๋ฉ์์ง ๋ฐ๋๋ฅผ ํตํ ๋ฐ์ดํฐ ์ ์ก
- POST, PUT, PATCH
- ์ฃผ๋ก ํ์๊ฐ์ , ์ํ์ฃผ๋ฌธ, ๋ฆฌ์์ค ๋ฑ๋ก, ๋ฆฌ์์ค ๋ณ๊ฒฝ ๋ฑ
2. ์ํฉ
- ์ ์ ๋ฐ์ดํฐ ์กฐํ : ์ด๋ฏธ์ง, ์ ์ ํ
์คํธ ๋ฌธ์
- ์กฐํ๋ GET ์ฌ์ฉ
- ์ ์ ๋ฐ์ดํฐ๋ ์ผ๋ฐ์ ์ผ๋ก ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ ์ฌ์ฉ์์ด ๋ฆฌ์์ค ๊ฒฝ๋ก๋ง์ผ๋ก ์กฐํ ๊ฐ๋ฅ
- ๋์ ๋ฐ์ดํฐ ์กฐํ : ์ฃผ๋ก ๊ฒ์, ๊ฒ์ํ ๋ชฉ๋ก์์ ์ ๋ ฌ ํํฐ(๊ฒ์์ด)
- ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉ, ์ด๋ฅผ ์๋ฒ์์ key-value๋ก ๊บผ๋ด์ด ์ฌ์ฉ
- ์กฐํ ์กฐ๊ฑด์ ์ค์ฌ์ฃผ๋ ํํฐ, ์กฐํ ๊ฒฐ๊ณผ๋ฅผ ์ ๋ ฌํ๋ ์ ๋ ฌ ์กฐ๊ฑด์ ์ฃผ๋ก ์ฌ์ฉ
- ์กฐํ๋ GET
- GET์ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํด์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ
- HTML Form์ ํตํ ๋ฐ์ดํฐ ์ ์ก : ํ์๊ฐ์
, ์ํ์ฃผ๋ฌธ, ๋ฐ์ดํฐ ๋ณ๊ฒฝ
- HTML์ Form ํ๊ทธ๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๋ ๋ฐฉ์์ผ๋ก formํ๊ทธ์ submit์ ํ๊ฒ ๋๋ฉด ์น ๋ธ๋ผ์ฐ์ ์์ form์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ด HTTP ๋ฉ์์ง๋ฅผ ์์ฑํด์ค๋ค. (Type = application/x-www-form-urlencoded ์ฌ์ฉ)
- (์ url encoded ์ธ๊ฐ? url๋ก ์ฌ์ฉํ ์ ์๋ ๋ฌธ์๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ์ธ์ฝ๋ฉํด์ ๋๊ฒจ์ฃผ๊ธฐ ๋๋ฌธ)
<form action="/save" method="post">
<input type="text" name="username"/>
<input type="text" name="age"/>
<button type="submit">์ ์ก</button>
</form>
POST /save HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
username=kim&age=20
- form์์ method๋ฅผ get์ผ๋ก ์ง์ ํ๊ฒ ๋๋ฉด GET์ ๋ณดํต ๋ฉ์์ง ๋ฐ๋๋ฅผ ์ฌ์ฉํ์ง ์๊ธฐ์ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ๊ฟ์ HTTP ๋ฉ์์ง๋ฅผ ๋ง๋ ๋ค (GET์ ๋ฉ์์ง ๋ฐ๋๋ฅผ ์ง์ํ์ง ์๋ ๊ณณ๋ค์ด ์กด์ฌํ๋ค. ๊ทธ๋ฆฌ๊ณ GET์ ์กฐํ์ฉ)
GET /members?username=kim&age=20 HTTP/1.1
Host: localhost:8080
- multipart/form-data : ํ์ผ ์ ๋ก๋์ ๊ฐ์ ๋ฐ์ด๋๋ฆฌ ๋ฐ์ดํฐ ์ ์กํ ๋ ์ฌ์ฉํ๋ Content-Type
<form action="/save" method="post" enctype="multipart/form-data">
<input type="text" name="username"/>
<input type="text" name="age"/>
<input type="file" name="file1" />
<button type="submit">์ ์ก</button>
</form>
์น ๋ธ๋ผ์ฐ์ ๊ฐ ์์ฑํ HTTP ๋ฉ์์ง : boundary ๊ธฐ์ค์ผ๋ก ์๋ฆ (๋๋ค์ง์ )
multipart๋ผ๋ ์ด๋ฆ์ ์ด๋ฐ์์ผ๋ก ๋ค๋ฅธ ์ข ๋ฅ์ ์ฌ๋ฌ ํ์ผ๊ณผ form ๋ด์ฉ์ ํจ๊ป ์ ์ก์ด ๊ฐ๋ฅํด multipart์ด๋ค.
POST /save HTTP/1.1
Host: localhost:8080
Content-Type: multipart/form-data; boundary=---XXX
------XXX
Content-Disposition: form-data; name="username"
kim
------XXX
Content-Disposition: form-data; name="age"
20
------XXX
Content-Disposition: form-data; name="file1"; filename="intro.png"
Content-Type: image/png
109238a9o0p3eqwokjasd09ou3oirjwoe9u34ouidf... <= ์ด๋ฏธ์ง์ ๋ํ ๋ฐ์ดํธ ์ ๋ณด
------XXX--
+ ์ฐธ๊ณ : HTML Form์ GET๊ณผ POST๋ง ์ง์
- HTTP API๋ฅผ ํตํ ๋ฐ์ดํฐ ์ ์ก : ์๋ฒ to ์๋ฒ, ์ฑ ํด๋ผ์ด์ธํธ, ์น ํด๋ผ์ด์ธํธ(AJAX๋ฐฉ์)
- HTML Form์ ์ฐ์ง ์๊ณ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๋ ๊ฒฝ์ฐ ๋๋ถ๋ถ
- POST, PUT, PATCH : ๋ฉ์์ง ๋ฐ๋๋ฅผ ํตํด ๋ฐ์ดํฐ ์ ์ก
- GET : ์กฐํ, ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์ดํฐ ์ ๋ฌ
- Content-Type: application/json์ ์ฃผ๋ก ์ฌ์ฉํ๋ ๋ฐ ์ฌ์ค์ ํ์ค์ฒ๋ผ ์ฌ์ฉ
๐HTTP API ์ค๊ณ ์์
HTTP API๋ฅผ ํฌ๊ฒ ๋๊ฐ์ง๋ก ๋ถ๋ฅํ์ฌ ์ค๊ณํ ์ ์๋๋ฐ ํ๋๋ POST๊ธฐ๋ฐ์ ๋ฑ๋ก ๋ฐฉ์ "์ปฌ๋ ์ ", ๋ค๋ฅธ ํ๋๋ PUT๊ธฐ๋ฐ์ ๋ฑ๋ก๋ฐฉ์ "์คํ ์ด"๋ค. POST์ PUT์ ์ด์ฉํด ์๋ก์ด ์ ๋ณด๋ฅผ ์ ์ฅํ ๋ ์๋ก ๋ค๋ฅธ ํน์ง์ด ์๋๋ฐ ์ด๋ฅผ ์ ์ ๋ฆฌํด์ผํ๋ค.
* HTTP API - ์ปฌ๋ ์
- POST ๊ธฐ๋ฐ ๋ฑ๋ก์ผ๋ก ์ค๋ช
ํ์ ๋ชฉ๋ก ์กฐํ | /members | GET |
ํ์ ๋ฑ๋ก | /members | POST |
ํ์ ๋จ๊ฑด ์กฐํ | /members/{id} | GET |
ํ์ ์์ | /members/{id} | PATCH, PUT, POST |
ํ์ ์ญ์ | /members/{id} | DELETE |
- ํด๋ผ์ด์ธํธ๋ ๋ฑ๋ก๋ ๋ฆฌ์์ค URI๋ฅผ ๋ชจ๋ฅธ๋ค > ์๋ฒ๊ฐ ๋ฐ์ดํฐ ๋ฐ์ ์๋ก ๋ฑ๋ก๋ ๋ฆฌ์์ค URI๋ฅผ ์์ฑ (ex. /members/100)
- ์ด๋ฌํ ํ์์ ์ปฌ๋ ์ (Collection) ์ด๋ผ๊ณ ํ๋ค.
์๋ฒ๊ฐ ๊ด๋ฆฌํ๋ ๋ฆฌ์์ค ๋๋ ํ ๋ฆฌ๋ฅผ ๋งํ๋ฉฐ ์๋ฒ๊ฐ ๋ฆฌ์์ค URI๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํ๋ค. ์ฌ๊ธฐ์๋ /members๊ฐ ์ปฌ๋ ์ !
- ์ผ๋ฐ์ ์ผ๋ก ์ด ๋ฐฉ์์ ๋ง์ด ์ฌ์ฉ
* HTTP API - ์คํ ์ด
- PUT ๊ธฐ๋ฐ ๋ฑ๋ก์ผ๋ก ์ค๋ช
ํ์ผ ๋ชฉ๋ก ์กฐํ | /files | GET |
ํ์ผ ๋ฑ๋ก | /files/{filename} | PUT (์ ๋ก๋ํ ํ์ผ ์ด๋ฆ์ ์๊ณ ์๊ธฐ ๋๋ฌธ, ๋์ผํ ์ด๋ฆ ์์ผ๋ฉด ๋์ฒด ์์ผ๋ฉด ์์ฑ) |
ํ์ผ ๋จ๊ฑด ์กฐํ | /files/{filename} | GET |
ํ์ผ ์ญ์ | /files/{filename} | DELETE |
ํ์ผ ๋๋ ๋ฑ๋ก | /files | POST (๋ฑ๋ก์ PUT์ ์ฌ์ฉํ์ผ๋ฏ๋ก POST๋ ํ์์ ๋ฐ๋ผ ์์ ์ง์ ) |
- ํด๋ผ์ด์ธํธ๋ ๋ฑ๋ก๋ ๋ฆฌ์์ค URI๋ฅผ ์์์ผ ํ๋ค. > ํด๋ผ์ด์ธํธ๊ฐ ์ง์ ๋ฆฌ์์ค URI๋ฅผ ์ง์ ํด ๊ด๋ฆฌ
- ์ด๋ฌํ ํ์์ ์คํ ์ด(Store) ๋ผ๊ณ ํ๋ค.
ํด๋ผ์ด์ธํธ๊ฐ ๊ด๋ฆฌํ๋ ๋ฆฌ์์ค ์ ์ฅ์๋ฅผ ๋งํ๋ฉฐ ํด๋ผ์ด์ธํธ๊ฐ ๋ฆฌ์์ค URI๋ฅผ ์๊ณ ๊ด๋ฆฌ. ์ฌ๊ธฐ์๋ /files๊ฐ ์คํ ์ด!
* HTML FORM ์ฌ์ฉ
- HTML FORM์ GET, POST๋ง ์ง์ (AJAX ๊ฐ์ ๊ธฐ์ ์ ์ฌ์ฉํด ์ด๋ฐ ์ ์ฝ ํด๊ฒฐ ๊ฐ๋ฅ)
- ์ฌ๊ธฐ์๋ ์์ HTML + HTML FORM ์ด์ผ๊ธฐํ ๊ฒ์ผ๋ก GET๊ณผ POST๋ง ์ง์ํ๋ฏ๋ก ์ ์ฝ์ด ์๋ค.
ํ์ ๋ชฉ๋ก ์กฐํ | /members | GET |
ํ์ ๋ฑ๋ก ํผ | /members/new | GET (๋ฑ๋ก ํผ์ ์กฐํ, submit ํ๋ฉด ์๋ ํ์ ๋ฑ๋ก POST๋ก) |
ํ์ ๋ฑ๋ก | /members /members/new |
POST (๋๊ฐ์ง ์ ํ ๊ฐ๋ฅ, ์ปฌ๋ ์ ์ฒ๋ผ ๋ฆฌ์์ค ๊ธฐ์ค or ๋ฑ๋ก ํผ์ ๋ฐ๋ฅด๋) |
ํ์ ๋จ๊ฑด ์กฐํ | /members/{id} | GET |
ํ์ ์์ ํผ | /members/{id}/edit | GET (์์ ํผ ๋ฐ ๋ฐ์ดํฐ๋ฅผ ์กฐํ, submit ํ๋ฉด ์๋ ํ์ ์์ POST๋ก) |
ํ์ ์์ | /members/{id} /members/{id}/edit |
POST |
ํ์ ์ญ์ | /members/{id}/delete | POST (/members/{id} ๋ก POST๋ฅผ ์ฌ์ฉํ ์ ์์ผ๋ฉด ์ปจํธ๋กค URI๋ฅผ ์ฌ์ฉ) |
- ์ปจํธ๋กค URI
GET, POST๋ง ์ง์ํ๋ฏ๋ก ์ ์ฝ์ด ์์ด ์ด๊ฑธ ํด๊ฒฐํ๊ธฐ ์ํด, "๋์ฌ"๋ก ๋ ๋ฆฌ์์ค ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉ
POST์ /new, /edit, /delete ๊ฐ ์ปจํธ๋กค URI์ ํด๋นํ๋ค.
์ ์ฝ ํด๊ฒฐ ๋ฟ๋ง ์๋๋ผ HTTP ๋ฉ์๋๋ก ํด๊ฒฐํ๊ธฐ ์ ๋งคํ ๊ฒฝ์ฐ์๋ ์ฌ์ฉํ๋ค(HTTP API ํฌํจ).
์ต๋ํ ๋ฆฌ์์ค๊ฐ๋
์ ์ฌ์ฉํ๋ ๊ทธ๊ฒ ํ๋ค ๊ฒฝ์ฐ ๋์ฒด์ ๋ก ์ฌ์ฉ!
๐์ฐธ๊ณ ํ๋ฉด ์ข์ URI ์ค๊ณ ๊ฐ๋
* ๋ฌธ์ (document)
- ๋จ์ผ ๊ฐ๋ (ํ์ผ ํ๋, ๊ฐ์ฒด ์ธ์คํด์ค, ๋ฐ์ดํฐ๋ฒ ์ด์ค row)
- ex) /members/100, /files.star.jpg
* ์ปฌ๋ ์ (collection)
- ์๋ฒ๊ฐ ๊ด๋ฆฌํ๋ ๋ฆฌ์์ค ๋๋ ํ ๋ฆฌ
- ์๋ฒ๊ฐ ๋ฆฌ์์ค์ URI๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌ
- ex) /members
* ์คํ ์ด (store)
- ํด๋ผ์ด์ธํธ๊ฐ ๊ด๋ฆฌํ๋ ๋ฆฌ์์ค ์ ์ฅ์
- ํด๋ผ์ด์ธํธ๊ฐ ๋ฆฌ์์ค์ URI๋ฅผ ์๊ณ ๊ด๋ฆฌ
- ex) /files
* ์ปจํธ๋กค๋ฌ (controller), ์ปจํธ๋กค URI
- ๋ฌธ์, ์ปฌ๋ ์ , ์คํ ์ด๋ก ํด๊ฒฐํ๊ธฐ ์ด๋ ค์ด ์ถ๊ฐ ํ๋ก์ธ์ค ์คํ
- ๋์ฌ๋ฅผ ์ง์ ์ฌ์ฉ
- ex) /members/{id}/delete
REST API - URL Naming Conventions
In REST, having a strong and consistent REST resource naming strategy โ will prove one of the best design decisions in the long term.
restfulapi.net
'Computer Science > Web' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
HTTP ์น ์ง์ - HTTP ํค๋1 (์ผ๋ฐ ํค๋) (0) | 2023.03.12 |
---|---|
HTTP ์น ์ง์ - HTTP ์ํ์ฝ๋ ์๊ฐ (0) | 2023.03.08 |
HTTP ์น ์ง์ - HTTP API๋ฅผ ๋ง๋ค์ด๋ณด์ (0) | 2023.03.07 |
HTTP ์น ์ง์ - ๋ชจ๋ ๊ฒ์ด HTTP (0) | 2023.03.06 |
HTTP ์น ์ง์ - URI์ ์น ๋ธ๋ผ์ฐ์ ์์ฒญ ํ๋ฆ (0) | 2023.03.06 |