wa_ter_ve
[FE] ์น&์ฑ ์ฐํฉ ์คํฐ๋ ๋ณธ๋ฌธ
๐ ์ธ์ & ์ฟ ํค (Session & Cookies)
๐ ์ธ์ (Session)
: ์๋ฒ๊ฐ ์ผ์ ์๊ฐ ๋์์ ์ฌ์ฉ์ ์์ฒญ์ ํ๋์ ์ํ๋ก ๋ณด๊ณ , ํด๋น ์ํ๋ฅผ ์ ์ง ๋ฐ ์ถ์ ํ๋ ๋ฐฉ์.
(๋ฐฉ๋ฌธ์๊ฐ ์น ์๋ฒ์ ์ ์๋ ์ํ → ์ธ์
)
ํด๋ผ์ด์ธํธ์ IP ์ฃผ์๋ก ๊ฐ ํด๋ผ์ด์ธํธ ์๋ณ์ด ๋ถ๊ฐํ๊ธฐ์,
์๋ฒ์์๋ ํด๋ผ์ด์ธํธ๋ฅผ ์๋ณํ๋ ์ฉ๋๋ก session ID๋ฅผ ์ฌ์ฉ.
ํน์ง
- ๊ฐ ํด๋ผ์ด์ธํธ์ ๊ณ ์ ID๋ฅผ ๋ถ์ฌํด, ์๋ฒ๊ฐ ID๋ฅผ ํตํด ํด๋ผ์ด์ธํธ๋ฅผ ๊ตฌ๋ถํ ์ ์๋๋ก ๋์.
- ์๋ฒ๋ ๊ฐ ํด๋ผ์ด์ธํธ์ ์ ๋ณด๋ฅผ ์ ์ฅํ์ฌ, ๊ฐ ์์ฒญ๋ค์ ์ธ์ ์ ๋ณด๋ฅผ ์ ์ง.
- ์๋ฒ ๋ฉ๋ชจ๋ฆฌ์ ์ธ์ ์ ์ ์ฅํ๋ฏ๋ก ์๋ฒ ์ฉ๋์ ์ํฅ์ ๋ฐ์. ์ฌ์ฉ์ ์ฆ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์ฆ๊ฐ.
- ์ธ์ ์ ์๋ฒ ์ธก์์ ํด๋ผ์ด์ธํธ์ ๋ฐ์ดํฐ๋ฅผ ์ง์ ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์ ๋ณด์์ฑ ๋์.
- ์ธ์ ID๋ ์ฟ ํค๋ฅผ ํตํด ์๋ฒ์ ํด๋ผ์ด์ธํธ ๊ฐ ์ ๋ฌ๋จ.
โฌ๏ธโฌ๏ธโฌ๏ธ
๐ช ์ฟ ํค(Cookies)
ํด๋ผ์ด์ธํธ ์ธก์์ ๋ฐ์ดํฐ ์ ์ฅ์ ์ํด ์ฌ์ฉํ๋ ์์ ๋ฐ์ดํฐ ์กฐ๊ฐ. (์ธ์ ๊ด๋ฆฌ ๊ธฐ๋ฅ)
ํน์ง
- ์ฟ ํค๋ ํด๋ผ์ด์ธํธ ์ธก์ ์ ์ฅ๋จ.
- ์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ๋ฐ๋ ๊ฒฝ์ฐ๋ง๋ค, ํด๋น ํด๋ผ์ด์ธํธ์ ์ ์ฅ๋ ์ฟ ํค๋ฅผ ์ ์ก.
- ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์ ๋ฐ์ดํฐ ์์ฒญ ์, ๊ทธ ์ฟ ํค๋ฅผ ํฌํจํ์ฌ ์์ฒญ์ ์ ์ก.
- key-value ์์ ํํ๋ก ์ ์ฅ๋จ. (ex. session_id = abc123 )
- ์์ฒญ ์, ์๋ฒ~ํด๋ผ์ด์ธํธ ๊ฐ ์๋์ผ๋ก ์ ์ก๋จ.
๐ ๋์ ๊ณผ์
1. ์น ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ฒ์๊ฒ ์์ฒญ
2. ์๋ฒ๋ ์ session ID ์์ฑ ๋ฐ ์ฟ ํค ์์ฑ ํ, session ID๋ ์ฟ ํค์ ๋ด๊ธฐ๊ณ
3. ์ด ์ฟ ํค๋ http ์ํ ์ฝ๋์ ๋ด๊ฒจ ์น ๋ธ๋ผ์ฐ์ ์ ์ ์ก๋จ.
์๋ฒ๊ฐ ๋ณด๋ธ http ์ํ ์ฝ๋์ ์ฟ ํค๊ฐ ํฌํจ๋์ด ์์ผ๋ฉด,
์น๋ธ๋ผ์ฐ์ ๋ ํด๋น ์๋ฒ์ ์์ฒญ์ ๋ณด๋ผ ๋๋ง๋ค, ํด๋น ์ฟ ํค๋ฅผ request์ ํฌํจํจ.
๐ง HTTPOnly ์ฟ ํค - (Web)
HTTPOnly ์ค์ ์ด ๋์ด์๋ ์ฟ ํค๋ ํด๋ผ์ด์ธํธ์ธก(Javascript)์์ ์ ๊ทผ ๋ถ๊ฐ๋ฅํ์ฌ, ์ฟ ํค๋ฅผ ์์ ํ๊ฑฐ๋ ์กฐ์ํ ์ ์์.
์ฆ, ์ค์ง ์๋ฒ๋ง์ด ์ฟ ํค์ ์ ๊ทผ ๊ฐ๋ฅ.
→ XSS (Cross-Site Scripting) ๊ณต๊ฒฉ ๋ฐฉ์ง.
๊ณต๊ฒฉ์๊ฐ ์
์ฑ ์คํฌ๋ฆฝํธ๋ฅผ ์ด์ฉํด ์ฌ์ฉ์์ ์ฟ ํค๋ฅผ ํ์ทจํ๋ ๊ณต๊ฒฉ.
HttpOnly ์์ฑ์ด ์ค์ ๋ ์ฟ ํค๋ Javascript์์ ์ ๊ทผ ๋ถ๊ฐ๋ฅํ๋ฏ๋ก ํด๋น ๊ณต๊ฒฉ์ผ๋ก๋ถํฐ ์ธ์
์ฟ ํค๋ฅผ ๋ณดํธ ๊ฐ๋ฅ.
→ CSRF(Cross-Site Request Forgery) ๊ณต๊ฒฉ ๋ฐฉ์ง.
์ฌ์ฉ์๊ฐ ์ธ์ฆ๋ ์น ์ฌ์ดํธ ์ํ์์ ์ฌ์ฉ์์ ๊ถํ์ ๋์ฉํด ์๋ฒ์ ์์ฒญ์ ๋ณด๋ด๋ ๊ณต๊ฒฉ.
HTTP Only ์ค์ ์ ํตํด JavaScript์์ ์ฟ ํค๋ฅผ ์ฝ์ง ๋ชปํ๊ฒ ํ๋ฉด, CSRF ๊ณต๊ฒฉ์ ๋ณด๋ค ์ด๋ ต๊ฒ ๋ง๋ค ์ ์์.
์ฃผ๋ก ์ฟ ํค์ ํฌํจ๋ ์ธ์ฆ ์ ๋ณด๋ฅผ ์ด์ฉํ ๊ณต๊ฒฉ์ด๋ฏ๋ก, ๋ฐฉ์ด๋ฅผ ์ํด์๋ SameSite ์ฟ ํค ์์ฑ๋ ํจ๊ป ์ฌ์ฉ.
HttpOnly ์ฟ ํค ์ค์ ์์
- ↓ ์๋ฒ ์ธก ์ฝ๋ (Node.js)
const express = require('express'); const app = express(); app.get('/set-cookie', (req, res) => { res.cookie('session_id', 'abc123', { httpOnly: true, secure: true }); // httpOnly: true ์ค์ ์ ํตํด Javascript(ํด๋ผ์ด์ธํธ) ์ ๊ทผ ๋ถ๊ฐ๋ฅ ํ๋๋ก. // secure๋ HTTP ์ฐ๊ฒฐ์์๋ง ์ ์ก๋๋๋ก ํ์ฌ ๋ณด์ ๊ฐํ. res.send('Cookie has been set!'); }); app.listen(3000, () => { console.log('Server is running on port 3000'); });โ
SameSite ์ฟ ํค ์์ฑ
- HttpOnly์ SameSite ์์ฑ์ ์ค์ ํ๋ฉด, XSS์ CSRF ๊ณต๊ฒฉ์ ๋์์ ๋ฐฉ์ง ๊ฐ๋ฅ.
res.cookie('session_id', 'abc123', {
httpOnly: true,
secure: true,
sameSite: 'Strict' // -> SameSite ์์ฑ์ผ๋ก CSRF ๊ณต๊ฒฉ ๋ฐฉ์ง
});
๐ HTTP
: HTTP (Hypertext Transfer Protocol)
ํด๋ผ์ด์ธํธ - ์๋ฒ ๊ฐ ๋ฐ์ดํฐ ์ ์ก์ ์ํด ์ ์๋ ํ๋กํ ์ฝ.
์์ฒญ(request) & ์๋ต(response) ๋ฐฉ์์ ํตํด ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ.
๊ฐ ์๋ต๊ณผ ์์ฒญ์ header์ body๋ก ๊ตฌ์ฑ.
โท HTTP ์์ฒญ (Request)
ํด๋ผ์ด์ธํธ → ์๋ฒ
<HTTP Method> <URL> <HTTP Version>
<Headers>
<Body (Optional)>
- <HTTP Method> - ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญํ๋ ์์ ์ ๋ํด ์ ์. (GET, POST, PUT, DELETE ๋ฑ)
- <URL> - ์์ฒญํ๋ ๋ฆฌ์์ค ์ฃผ์. ์๋ฒ ์์ฒญ ์ฒ๋ฆฌ๋ฅผ ์ํด ๊ตฌ์ฒด์ ์ธ ์๋ํฌ์ธํธ ์ง์ .
- <Headers> - ๋ฉํ ์ ๋ณด ๋ฐ ์์ฒญ ์ํ๋ฅผ ์๋ฒ์๊ฒ ์๋ฆผ.
- <Body (Optional)> - ์๋ฒ์ ์ ์กํ ๋ฐ์ดํฐ ๋ด์ฉ. (Get ์์ฒญ์ body ์์ / POST&PUT ์์ฒญ์ body ํฌํจ ๊ฐ๋ฅ.)
HTTP ์์ฒญ ์์
- GET ์์ฒญ
GET /api/user?id=123 HTTP/1.1
Host: example.com
Accept: application/json
* /api/user?id=123: ์๋ฒ์ ์๋ํฌ์ธํธ ๋ฐ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ
* Accept: ํด๋ผ์ด์ธํธ๊ฐ ์๋ต ๋ฐ์ ๋ฐ์ดํฐ์ ์ ํ
- POST ์์ฒญ
POST /api/user HTTP/1.1
Host: example.com
Content-Type: application/json
Authorization: Bearer token_here
{
"name": "์์ธ",
"age": 23,
"city": "SEOUL"
}
* Content-Type: request body์ ๋ฐ์ดํฐ ํ์. (์ ์์์๋ JSON ํ์์ผ๋ก ์ ์)
* Authorization: ์ธ์ฆ ์ ๋ณด. (์ ์์์๋ ํ ํฐ์ ์ฌ์ฉํ ์ธ์ฆ)
* { ~~~ }: body๋ก ์๋ฒ์ ์ ์กํ ๋ฐ์ดํฐ ๋ด์ฉ. (์ฃผ๋ก JSON, XML, ํ ์คํธ์ ๊ฐ์ ํ์์ผ๋ก ์ ์ก.)
โท HTTP ์๋ต(Response)
์๋ฒ → ํด๋ผ์ด์ธํธ
<HTTP Version> <Status Code> <Status Message>
<Headers>
<Body (Optional)>
- <HTTP Version> - ์๋ต์ ์ด์ฉ๋๋ HTTP ๋ฒ์
- <Status Code> - ์ํ ์ฝ๋
- <Status Message> - ์ํ ์ฝ๋์ ๋ํ ๋ฉ์์ง
- <Headers> - ์๋ต์ ๋ํ ๋ฉํ ์ ๋ณด ํฌํจ. (ex. Content-Type, Content-Length, Set-Cookie )
- <Body (Optional)> - ์๋ฒ์ ์ ์กํ ๋ฐ์ดํฐ ๋ด์ฉ. (Get ์์ฒญ - ๋ฐ์ดํฐ ๋ฐํ / POST ์์ฒญ - ์ฑ๊ณต ๊ฒฐ๊ณผ ๋ฐํ)
HTTP ์๋ต ์์
- 200 OK ์๋ต
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 55
{
"name": "์์ธ",
"age": 23,
"city": "SEOUL"
}
* 200 OK: ์์ฒญ์ด ์ฑ๊ณต์ ์ผ๋ก ์ฒ๋ฆฌ๋จ.
- 404 Not Found ์๋ต
HTTP/1.1 404 Not Found
Content-Type: text/html
Content-Length: 138
<html>
<body>
<h1>404 Not Found</h1>
<p>The requested resource could not be found on this server.</p>
</body>
</html>
* 404 Not Found: ์์ฒญํ URL์ ์๋ฒ์์ ์ฐพ์ ์ ์์.
* Content-Type: ์๋ต ๋ฐ์ดํฐ ํ์ (์ ์์์์๋ HTML)
* Body: ์ค๋ฅ ๋ฉ์์ง ๋ฐ ๋ฐ์ดํฐ๊ฐ body์ ํฌํจ๋จ.
โ๏ธ
ํด๋ผ์ด์ธํธ๊ฐ GET ์์ฒญ์ ๋ณด๋ด๋ฉด, ์๋ฒ๋ ํด๋น ๋ฆฌ์์ค๋ฅผ ์กฐํํ์ฌ ์๋ต ๋ณธ๋ฌธ์ ๋ฐ์ดํฐ๋ฅผ ํฌํจํ์ฌ ๋ฐํํจ.
์๋ต ๋ณธ๋ฌธ์ ํฌํจ๋ ๋ฐ์ดํฐ๋ ์น ํ์ด์ง, JSON ๊ฐ์ฒด ๋ฑ์ผ๋ก ํํ.
๐ฎ HTTP ์ํ ์ฝ๋
์ํ ์ฝ๋(response status code) ?
: ํด๋ผ์ด์ธํธ์ ์๋ฒ ๊ฐ์ ํต์ ์ํ๋ฅผ ๋ํ๋ด๋ ํ์คํ๋ ์ฝ๋์ ๋ชจ์.
ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญ์ ๋ณด๋์ ๋ ์๋ต๋๋ ์ํ ์ฝ๋๋ฅผ ํตํด ์๋ฒ์๊ฒ ๋ณด๋ธ ์์ฒญ์ด ์ด๋ป๊ฒ ์ฒ๋ฆฌ๋์๋์ง ํ์
๊ฐ๋ฅ.
HTTP response ์ฒซ์ค์ ํ์.
(์์ ↓)
HTTP/1.1 200 OK
Date: Sun, 21 Apr 2013 15:12:46 GMT
Server: Apache
Connection: close
Content-Type: text/html; charset=ISO-8859-1
Content-length: 115
<html>
<head>
<title>
A Sample HTML file
</title>
</head>
<body>
The rest of the document goes here
</body>
</html>
๐ข HTTP/1.1
=> ํ๋กํ ์ฝ ๋ฒ์
๐ก 200 OK
=> ์ํ ์ฝ๋
1xx: ์ ๋ณด ์๋ต
2xx: ์ฑ๊ณต ์๋ต
3xx: redirection
4xx: ํด๋ผ์ด์ธํธ ์์ฒญ ์ค๋ฅ
5xx: ์๋ฒ ์ค๋ฅ
โค๏ธ 1XX - ์ ๋ณด ์๋ต
100 Continue
: request body ์ ์ก์ ๊ณ์ํด๋ ๋๋ค๋ ์๋ฏธ.
์๋ฒ๊ฐ request header์ metadata๋ฅผ ๋ฐ์ ์งํ, ๋์ฉ๋์ request body๋ฅผ ๋ฐ๊ธฐ ์ง์ ์ ๋ณด๋ด๋ ์๋ต ์ฝ๋.
๋ถ๋ด์ด ๋ ์ ์๋ ๋์ฉ๋์ request body๋ฅผ ๋ณด๋ด๊ณ ๋์๋ ๊ฑฐ๋ถ ๋นํ์ง ์๊ณ ๊ณ์ ์ ์กํด๋ ๋๋์ง ๋ฏธ๋ฆฌ ํ์ธ์ ๋ฐ๊ธฐ ์ํ ์ฉ๋์ ์๋ต ์ฝ๋.
101 Switching Protocol
: ํด๋ผ์ด์ธํธ๊ฐ ๋ณด๋ธ Upgrade ์์ฒญ ํค๋์ ๋ํ ์๋ต์ผ๋ก ๋ณด๋ด์ง๋ฉฐ,
์๋ฒ์์ ํ๋กํ ์ฝ์ ๋ณ๊ฒฝํ ์์ ์์ ํด๋ผ์ด์ธํธ์๊ฒ ์๋ฆผ.
(ex. HTTP ํ๋กํ ์ฝ์์ WebSockets ํ๋กํ ์ฝ๋ก ๋ณ๊ฒฝ)
102 Processing (deprecated)
: ์๋ฒ๊ฐ ์์ฒญ์ ์์ ํ๊ณ ์ด๋ฅผ ์ฒ๋ฆฌ๋ ํ๊ณ ์์ง๋ง,
์์ง ์ ๋๋ก ๋ ์๋ต์ ์๋ ค์ค ์ ์์์ ํด๋ผ์ด์ธํธ์ ์๋ฆผ.
103 Early Hints
: ์ฃผ๋ก Link ํค๋์ ํจ๊ป ์ฌ์ฉ๋๋ฉฐ
์๋ฒ๊ฐ ์๋ต์ ์ค๋นํ๋ ๋์, ์ฌ์ฉ์ ์์ด์ ํธ๊ฐ(user agent) ์ฌ์ ๋ก๋ฉ(preloading)์ ์์ํ ์ ์๋๋ก ํจ.
๐ 2XX - ์ฑ๊ณต ์๋ต
200 OK
: ์์ฒญ์ด ์ฑ๊ณต์ ์ผ๋ก ์ฒ๋ฆฌ๋จ.
response body์๋ ์์ฒญ๋ ๋ฐ์ดํฐ๊ฐ ์กด์ฌ.
201 Created
: POST request์ ์ํด ์๋ฒ์ ์ ๋ฆฌ์์ค๊ฐ ์์ฑ๋จ. (์ฃผ๋ก POST ๋๋ PUT ์์ฒญ ์๋ต)
์ ๋ฆฌ์์ค์ ๋ํ URL์ด response body์ ์กด์ฌ.
202 Accepted
: ์์ฒญ์ ์์ ํ์์ผ๋, ์์ง ์ฒ๋ฆฌ๊ฐ ์๋ฃ๋์ง ์์.
203 Non-authoritative Information
: ์ด ์๋ต์ ์์ฒญ๋ ์๋ฒ๊ฐ ์๋, ๋คํธ์ ํต์ ์ค๊ฐ์ ์บ์ ์ญํ ์ ํ๋ ๋๊ตฐ๊ฐ๊ฐ ๋ณด๋ธ ์๋ต.
๋ฐ๋ผ์ ์ด ์๋ต์ ์ต์ ๋ฒ์ ์ด ์๋ ์ ์์.
204 No Content
: ์์ฒญ์ด ์ฑ๊ณต์ ์ผ๋ก ์ฒ๋ฆฌ๋์์ผ๋, ์๋ต์ผ๋ก ๋ณด๋ผ ์๋ฃ ์์.
205 Reset Content
: ์์ฒญ์ด ์ฑ๊ณต์ ์ผ๋ก ์ฒ๋ฆฌ๋์์ผ๋, ์๋ต์ผ๋ก ๋ณด๋ผ ์๋ฃ ์์.
(์๋ก๊ณ ์นจ ๋ฑ์ ํตํด ์ ๋ด์ฉ์ ํ์ธํ๋ผ๊ณ ์๋ฆผ)
206 Partial Content
: ์๋ฒ๊ฐ GET ์์ฒญ์ ์ผ๋ถ๋ง ์ฑ๊ณต์ ์ผ๋ก ์ฒ๋ฆฌํจ.
response body์๋ ์์ฒญ๋ ์ผ๋ถ ์๋ฃ๋ง ์กด์ฌ.
(ํด๋ผ์ด์ธํธ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ด์ด๋ฐ๊ธฐ๋ฅผ ์๋ํ๋ฉด, ์๋ฒ๋ request header์ Range ํญ๋ชฉ์ ๋ช ์๋ ๋ถ๋ถ๋ถํฐ ์ ์ก.)
๐ 3XX - redirection
300 Multiple Choices
: ์์ฒญ์ด ์ฌ๋ฌ ์๋ต์ด ๊ฐ๋ฅํ ๊ฒฝ์ฐ, ํ๋๋ฅผ ๊ณจ๋ผ์ ๋ณด๋ด๋ผ๊ณ ํด๋ผ์ด์ธํธ์๊ฒ ์ ํ์ง๋ฅผ ๋ฐํ.
301 Moved Permanently
: ์์ฒญ๋ ์๋ฃ์ URL์ด ๋ณ๊ฒฝ๋์์์ ์๋ฆผ.
(๋ณ๊ฒฝ๋ URL์ response header์ Location ํญ๋ชฉ์ ์กด์ฌ.)
302 Moved Temporarily
: ์์ฒญ๋ ์๋ฃ์ URL์ด ์์๋ก ๋ณ๊ฒฝ๋์์์ ์๋ฆผ.
(์ URL์ response header์ Location ํญ๋ชฉ์ ์กด์ฌ.)
์ฌ์์ฒญ ์ ์๋์ URL๋ก ์์ฒญํด์ผ ํจ.
303 See Other
: ํด๋ผ์ด์ธํธ ์์ฒญ์ ๋ฐ๋ฅธ ์์ ์ ์ํด์ ๋ค๋ฅธ URL ํ์ํ ๋ ์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ์๊ฒ ์ ์ก.
(์ดํด๋ณผ URL์ response header์ Location ํญ๋ชฉ์ ์กด์ฌ.)
304 Not Modified
: ํด๋ผ์ด์ธํธ๊ฐ ๋ณด๋ธ ์์ฒญ์ request header ํญ๋ชฉ 'If-Modified-Since: ์๊ฐ' ์ด ์๋ ๊ฒฝ์ฐ, ๊ทธ ์๊ฐ ์ดํ๋ก ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ์๋ง ๋ฐ์ดํฐ๋ฅผ ์์ฒญ.
๋ณ๊ฒฝ๋์ง ์์์ผ๋ฉด ๋ฐ์ดํฐ๋ ๋ณด๋ผ ํ์์๊ณ , 304 Not Modified ์ํ ์ฝ๋๋ง ์ ์ก.
์ฃผ๋ก, ์บ์ ์ญํ ์ ํ๋ proxy๊ฐ ํด๋น ์์ฒญ์ ์ ์ก.
307 Temporary Redirect
: 302๊ณผ ๋์ผํ ์๋ฏธ (=์์ฒญ๋ ์๋ฃ์ URL์ด ์์๋ก ๋ณ๊ฒฝ๋์์์ ์๋ฆผ.)
+ ํด๋ผ์ด์ธํธ๊ฐ ๋ณด๋ธ HTTP ๋ฉ์๋๋ ๋ณ๊ฒฝ ๋ถ๊ฐ.
(302์ ๋ค๋ฅธ ์ : ๊ธฐ์กด์ HTTP ๋ฉ์๋ ์ ์งํ๋ฉฐ redirection)
308 Permanent Redirect
: 301๊ณผ ๋์ผํ ์๋ฏธ (=์์ฒญ๋ ์๋ฃ์ URL์ด ๋ณ๊ฒฝ๋์์์ ์๋ฆผ.)
+ HTTP ๋ฉ์๋๋ ๋ณ๊ฒฝ ๋ถ๊ฐ.
(301๊ณผ ๋ค๋ฅธ ์ : ๊ธฐ์กด์ HTTP ๋ฉ์๋ ์ ์งํ๋ฉฐ redirection)
๐ฉต 4XX - ํด๋ผ์ด์ธํธ ์์ฒญ ์ค๋ฅ
400 Bad Request
: HTTP request์ ์ค๋ฅ๊ฐ ์์ด์, ์๋ฒ๊ฐ ์ดํดํ ์ ์์.
401 Unauthorized
: ์ ๊ทผ ๊ถํ์ด ์๋ URL ์์ฒญ์ ๋ํ ์๋ต ์ฝ๋. (→ Authorization ์๋ฌ)
403 Forbidden
: ์ธ์ฆ(Authorization) ๋ฌธ์ ๊ฐ ์๋, ๋ค๋ฅธ ๋ฌธ์ ๋ก ์ ๊ทผ์ด ๊ธ์ง๋ ๊ฒฝ์ฐ์ ๋ํ ์๋ต ์ฝ๋. (→ Authentification ์๋ฌ)
ํด๋ผ์ด์ธํธ๊ฐ ์ธ์ฆ๋์ด๋, ์ ๊ทผ์ด ๊ธ์ง๋๋ ๊ฒฝ์ฐ.
(ex. ๋คํธ์ํฌ ํธ๋ํฝ ์ด๊ณผ, IP ์ฐจ๋จ, ํน์ ๋ฆฌ์์ค ์ ํ, ์ง์ญ ์ ํ ๋ฑ)
404 Not Found
: ์์ฒญ๋ URL์ ๋ํ ์๋ฃ๋ฅผ ์ฐพ์ ์ ์๋ค๋ ์๋ต ์ฝ๋.
405 Method Not Allowed
: ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญํ HTTP ๋ฉ์๋(POST, PUT, DELETE ๋ฑ)๊ฐ ์๋ฒ์์ ํ์ฉ๋์ง ์๋ ๊ฒฝ์ฐ ๋ฐํ.
์๋ฒ๊ฐ ํน์ ๋ฆฌ์์ค์ ๋ํด ํด๋น ๋ฉ์๋๋ฅผ ์ง์ํ์ง ์๋๋ค๋ ์๋ฏธ.
(ex. API ์๋ํฌ์ธํธ๊ฐ GET ์์ฒญ๋ง์ ํ์ฉํ๊ณ ์์ ๋, ํด๋ผ์ด์ธํธ๊ฐ POST ์์ฒญ์ ๋ณด๋ด๋ฉด ๋ํ๋๋ ์๋ต.)
406 Not Acceptable
: ํด๋ผ์ด์ธํธ ์์ฒญ ํค๋์ Accept ํญ๋ชฉ์ MIME ํ์ (application/json, text/html, application/xml ๋ฑ)์ ๋ํด,
์๋ฒ๊ฐ ๋ฐ์ดํฐ ์ ๊ณต์ด ๋ถ๊ฐ๋ฅํ ๊ฒฝ์ฐ ๋ฐํ.
(ex. ์๋ฒ๋ ์ค์ง JSON ํ์(application/json)๋ง์ ์ ๊ณตํ ์ ์๋๋ฐ, ํด๋ผ์ด์ธํธ๋ Accept: text/html์ ์๊ตฌํ ๊ฒฝ์ฐ )
408 Request Timeout
: ํด๋ผ์ด์ธํธ ์์ฒญ ์๋ฃ(๋ง์ง๋ง ๋น์ค)๊น์ง ๋๋ฌด ์ค๋๊ฑธ๋ ค์ ์๊ฐ ์ ํ์ ์ด๊ณผํ์์ ์๋ฆผ.
410 Gone
: ์์ฒญ๋ URL์ ๋ํ ์๋ฃ๊ฐ ์กด์ฌํ์ง ์์.
(์๋น์ค๊ฐ ์ข ๋ฃ๋์์ ๊ฒฝ์ฐ.)
411 Length Required
: ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญ ์, request header์ Content-length ํญ๋ชฉ์ ํฌํจํ์ง ์์, ์๋ฒ๊ฐ ์ฒ๋ฆฌ ๋ถ๊ฐ๋ฅํ ๊ฒฝ์ฐ.
413 Request Entity Too Large
: reqeust body๊ฐ ์๋ฒ๊ฐ ํ์ฉํ๋ ์ต๋ ํฌ๊ธฐ๋ฅผ ์ด๊ณผ.
(์ฉ๋์ด ํฐ ํ์ผ์ ์ ๋ก๋ ํ ๋ ๋ฐ์ํ๋ ์๋ฌ)
414 Request URI Tool Long
: URL์ด ๋๋ฌด ๊ธธ ๋ ๋ฐ์ํ๋ ์๋ฌ.
415 Unsupported Media Type
: ์๋ฒ๊ฐ ์ง์ํ์ง ์๋ ๋ฏธ๋์ด ํฌ๋งท์ ์์ฒญํ ๊ฒฝ์ฐ.
416 Requested Range Not Satisfiable
: ํด๋ผ์ด์ธํธ ์์ฒญ ํค๋์ Range ํ๋๊ฐ ์๋ฒ์ ๋ฆฌ์์ค ๋ฒ์๋ฅผ ๋ฒ์ด๋ ๊ฒฝ์ฐ.
*(Range header: ํด๋ผ์ด์ธํธ๊ฐ ํน์ ๋ฐ์ดํฐ ๋ถ๋ถ๋ง ๋ฐ๋๋ก ์์ฒญํ ๋ ์ฌ์ฉ๋จ)
417 Expection Failed
: ํด๋ผ์ด์ธํธ ์์ฒญ ํค๋์ Expect ํ๋๊ฐ ์๋ฒ์์ ์ฒ๋ฆฌ ๋ถ๊ฐ๋ฅ ๋๋ ์ง์๋์ง ์๋ ๊ฒฝ์ฐ.
*(Range header: ํน์ ์กฐ๊ฑด์ ๋ถํฉํ ๋๋ง ์๋ฒ๊ฐ ์์ฒญ์ ์ฒ๋ฆฌํ๋๋ก ํ ๋ ์ฌ์ฉ๋จ)
๐ 5XX - ์๋ฒ ์ค๋ฅ
500 Internal Server Error
: ์๋ฒ ๋ด๋ถ์ ์ ์ ์๋ ์๋ฌ.
502 Bad Gateway
: ํ๋ก์๋ ๊ฒ์ดํธ์จ์ด ์ญํ ์ ํ๋ ์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด,
๋ค๋ฅธ ์๋ฒ๋ก๋ถํฐ ์ ํจํ์ง ์๊ฑฐ๋ ์์ํ์ง ๋ชปํ ์๋ต์ ๋ฐ์์ ๊ฒฝ์ฐ.
*(Proxy/Gateway Server: ํด๋ผ์ด์ธํธ์ ์ค์ ๋ฆฌ์์ค๋ฅผ ์ ๊ณตํ๋ ์๋ฒ ์ฌ์ด์ ์์นํ์ฌ ์์ฒญ๊ณผ ์๋ต์ ์ค๊ณ.)
503 Service Unavailable
: ์๋ฒ๊ฐ ์ ์ ์๋ต ๋ถ๊ฐ๋ฅ.
504 Gateway Timeout
: ํ๋ก์๋ ๊ฒ์ดํธ์จ์ด ์๋ฒ๊ฐ ๋ฐฑ์๋ ์๋ฒ๋ก๋ถํฐ ์๋ต์ ๊ธฐ๋ค๋ฆฌ๋ ๋์,
์๊ฐ์ด ์ด๊ณผ๋์ด ํด๋น ์๋ฒ์์ ์์ฒญ์ ์ฒ๋ฆฌํ ์ ์๋ ๊ฒฝ์ฐ.
(ex. ๋คํธ์ํฌ ์ง์ฐ, ๋ฐฑ์๋ ์๋ฒ์ ๊ณผ๋ถํ, ์๋ฒ ๋ค์ด ๋ฑ)
505 HTTP Version Not Supproted
: ํด๋ผ์ด์ธํธ ์์ฒญ์ HTTP ๋ฒ์ ์ ์๋ฒ์์ ์ง์ํ์ง ์์.
511 Network Authentication Required
: ํด๋ผ์ด์ธํธ๊ฐ Network ์์ธ์ค๋ฅผ ์ป๊ธฐ ์ํ ์ธ์ฆ์ด ํ์.
(ex. KT WIFI ์ธ์ฆ์ด ํ์ํ ๊ฒฝ์ฐ)
โ๏ธ API ํต์
๐ญ API?
= Application Programming Interface
ํ๋กํ ์ฝ ์งํฉ์ ์ฌ์ฉํ์ฌ ๋ ์ํํธ์จ์ด ๊ตฌ์ฑ ์์๊ฐ ์๋ก ํต์ ํ ์ ์๊ฒ ํ๋ ๋ฉ์ปค๋์ฆ.
(ex. ๋ชจ๋ฐ์ผ ๋ ์จ์ฑ์ API๋ฅผ ํตํด, ๊ธฐ์์ฒญ์ ๋ฐ์ดํฐ ์์คํ
๊ณผ ์ฐ๊ฒฐ๋์ด ๋ ์จ ์ ๋ณด๋ฅผ ํ์.)
์ ์ฌ์ฉํ ๊น?
- ๊ฐ๋ฐ ๋ฐ ๊ด๋ฆฌ๊ฐ ํจ์จ์
ํด๋น ์๋น์ค๊ฐ ์ด๋ป๊ฒ ๊ตฌํ๋์๋์ง ์์ธํ ๋ชฐ๋ผ๋ ๊ฐ์ ธ์์ ์ฌ์ฉ์ด ๊ฐ๋ฅํจ.
๋ฐ๋ผ์, ์๊ฐ๊ณผ ๋น์ฉ์ ์ค์ฌ ๋์ฑ ํจ์จ์ ์ผ๋ก ๊ฐ๋ฐํ ์ ์๋๋ก ๋์์ค.
- ์ ์ฐ์ฑ ๋ฐ ํ์ฅ์ฑ
์ ๊ท ๊ฐ๋ฐ์ ํ์ฅ์ฑ์ด ์ข์. ํ์ฌ ์๋น์ค์ ์ฐ๊ณํ์ฌ ์๋ก์ด ์ฑ/์น์ ๊ฐ๋ฐ ๊ฐ๋ฅํ์ฌ,
๋์ฑ ๋ค์ํ๊ณ ์๋ก์ด ์๋น์ค๋ค์ ๊ฐ๋ฐํ ์ ์๋ ํ๊ฒฝ์ด ๊ตฌ์ถ๋จ.
๐ 'ํด๋ผ์ด์ธํธ - ์๋ฒ' ํต์
- API์ ๋ํด ์ดํดํ๊ธฐ ์ํด์๋
์ฐ๋ฆฌ๊ฐ ์น ๋๋ ์ฑ์ ์ด์ฉํ๋ ๊ฒฝ์ฐ์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๊ฐ ์ด๋ป๊ฒ ์ด๋ฃจ์ด์ง๋์ง,
ํด๋ผ์ด์ธํธ์ ์๋ฒ ๊ฐ์ ๋ฐ์ดํฐ ํต์ ์ด ์ด๋ค ๊ณผ์ ์ ๊ฑฐ์น๋์ง ์ดํดํด์ผํจ.
์๋ - ์น ๋ธ๋ผ์ฐ์ (ํด๋ผ์ด์ธํธ)
์๋ฒ - ๋ฐ๋ฆฌ์คํ
๋ฐ์ดํฐ๋ฒ ์ด์ค - ์ฐฝ๊ณ
๋ฐ์ดํฐ - ์๋
1. (์๋์ด ์ง์ ์๋๋ฅผ ๊ตฌํด ์ปคํผ๋ฅผ ๋ง๋ค์ง ์๊ณ ๋ฐ๋ฆฌ์คํ์๊ฒ ์ฃผ๋ฌธ.)
ํด๋ผ์ด์ธํธ๊ฐ ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ์ง์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๊ทผํ์ง ์๊ณ ์๋ฒ์๊ฒ ์์ฒญ.
2. (๋ฐ๋ฆฌ์คํ๋ ์ฃผ๋ฌธ๋ฐ์ ์๋๋ฅผ ์ด์ฉํด ์ปคํผ๋ฅผ ์ ์.)
์๋ฒ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ํด๋น ๋ฐ์ดํฐ๋ฅผ ์ฐพ์์ ๊บผ๋.
3. (์ ์ํ ์ปคํผ๋ฅผ ํด๋น ๋ฉ๋ด๋ฅผ ์ฃผ๋ฌธํ ์๋์๊ฒ ์ ๋ฌ.)
์๋ฒ๋ ํด๋ผ์ด์ธํธ์๊ฒ ์์ฒญ๋ฐ์ ํด๋น ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ.
โ API ์๋ ๋ฐฉ์ 4๊ฐ์ง ์ ํ
SOAP API
(Simple Object Access Protocol)
- ๋จ์ ๊ฐ์ฒด ์ ๊ทผ ํ๋กํ ์ฝ ์ฌ์ฉ.
- XML์ ์ฌ์ฉํ์ฌ ํด๋ผ์ด์ธํธ์ ์๋ฒ ๊ฐ ๋ฉ์์ง ๊ตํ.
- ์ฃผ๋ก HTTP, SMTP์ ๊ฐ์ ํ๋กํ ์ฝ์ ํตํด ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ.
- ์ ์ฐ์ฑ์ด ๋จ์ด์ง๋ฉฐ(์๊ฒฉํ ๊ท์น), ๋ณด์, ํธ๋์ญ์
์ฒ๋ฆฌ ๋ฑ ์ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ์ ์ง์.
- ๊ณผ๊ฑฐ์ ๋ง์ด ์ฌ์ฉ๋์์.
(ex. ๊ฐ๋ ฅํ ๋ณด์๊ณผ ํธ๋์ญ์
์ฒ๋ฆฌ ๊ธฐ๋ฅ์ ์๊ตฌํ๋ ๊ธฐ์
ํ๊ฒฝ์์ ์ฌ์ฉ.)
RPC API(Remote Procedure Call)
- ์๊ฒฉ ํ๋ก์์ ํธ์ถ์ด๋ผ๊ณ ํจ.
- ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์์ ์ ๊ณตํ๋ ํจ์/ํ๋ก์์ ํธ์ถ ์๋ฃ ์, ์๋ฒ๊ฐ ํด๋ฌ์ด์ธํธ์๊ฒ ์ถ๋ ฅ ์ ์ก.
- ์ง๊ด์ ์ด๊ณ ๊ฐ๋จํ ํธ์ถ ๋ฐฉ์์ด๋ฉฐ, ๋๊ธฐ์ ์ผ๋ก ๋์ํจ.
- ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์ด๋ ค์ ํจ์จ์ฑ์ด ๋จ์ด์ง ์ ์์.
(ex. ๋ถ์ฐ ์์คํ
์์ ์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ ์ธก์ผ๋ก ํน์ ์์
์ ์๊ฒฉ ํธ์ถํ๋ ๊ฒฝ์ฐ ์ฌ์ฉ.)
Websocket API
- JSON ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ์ต์ ์น API.
- ํด๋ผ์ด์ธํธ์ฑ๊ณผ ์๋ฒ ๊ฐ ์๋ฐฉํฅ ํต์ ์ง์.
- ์๋ฒ ์ฐ๊ฒฐ๋ ํด๋ผ์ด์ธํธ์ ์ฝ๋ฐฑ ๋ฉ์์ง๋ฅผ ์ ์ก ๊ฐ๋ฅํ์ฌ REST API ๋ณด๋ค ์๋์ ์ผ๋ก ํจ์จ์ .
REST API
(Representational State Transfer)
- REST๋ ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ ๋ฐ์ดํฐ์ ์ก์ธ์คํ๋ ๋ฐ ์ฌ์ฉํ ์ ์๋ GET, PUT, DELETE ๋ฑ์ ํจ์ ์งํฉ์ ์ ์.
- ํด๋ผ์ด์ธํธ์ ์๋ฒ๋ HTTP๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๊ตํ.
- REST API์ ์ฃผ๋ ํน์ง์ 'Stateless' → ์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ์ ์ํ๋ฅผ ์ ์ฅํ์ง ์์.
- ์๋ฒ์ ์๋ต์ ์น ํ์ด์ง์ ์ผ๋ฐ์ ์ธ ๊ทธ๋ํฝ ๋ ๋๋ง์ด ์๋ ์ผ๋ฐ ๋ฐ์ดํฐ.
→ ๊ฐ API ๋ฐฉ์์ ์ฐจ์ด์ ์์ฝ:
์ ํ | ํน์ง | ์ฅ์ | ๋จ์ | ์ฌ์ฉ ์์ |
SOAP API | XML์ ์ฌ์ฉ, ์๊ฒฉํ ๊ท๊ฒฉ | ๋ณด์, ํธ๋์ญ์ ์ฒ๋ฆฌ ์ง์ | ๋ฌด๊ฒ๊ณ ์ ์ฐ์ฑ์ด ๋จ์ด์ง | ๊ธฐ์ ํ๊ฒฝ, ๊ธ์ต ์์คํ |
RPC API | ์๋ฒ ํจ์ ํธ์ถ, ์๊ฒฉ ํ๋ก์์ ์ฒ๋ฆฌ | ๊ฐ๋จํ๊ณ ์ง๊ด์ | ๋คํธ์ํฌ ์ง์ฐ, ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ด๋ ค์ | ๋ถ์ฐ ์์คํ , gRPC |
WebSocket API | ์๋ฐฉํฅ ํต์ , ์ค์๊ฐ ๋ฐ์ดํฐ ํธ์ ๊ฐ๋ฅ | ์ค์๊ฐ ํต์ ํจ์จ์ , ์ด๋ฒคํธ ํธ์ ๊ฐ๋ฅ | ์๋ฒ์ ํด๋ผ์ด์ธํธ ๊ฐ ์ฐ๊ฒฐ ์ ์ง ํ์ | ์ฑํ ์ฑ, ์ค์๊ฐ ์ฃผ์ ๊ฑฐ๋ ์์คํ |
REST API | HTTP ๋ฉ์๋(GET, POST ๋ฑ), ๋ฌด์ํ์ฑ ๊ธฐ๋ฐ | ๊ฐ๋จํ๊ณ ์ ์ฐํจ, HTTP ํ๋กํ ์ฝ ์ฌ์ฉ | ์ค์๊ฐ ์ฒ๋ฆฌ ์ด๋ ค์ | ์น ์ ํ๋ฆฌ์ผ์ด์ , ๋ชจ๋ฐ์ผ ์ฑ ํต์ |
โ API ๋ณดํธ
1. ์ธ์ฆ ํ ํฐ
- ์ฌ์ฉ์์๊ฒ API ํธ์ถ์ ์ํํ ์ ์๋ ๊ถํ ๋ถ์ฌ์ ์ด์ฉ๋๋ ์์คํ
.
- ์ฌ์ฉ์๊ฐ ์์ ์ด ๋๊ตฌ์ธ์ง ํ์ธํ๊ณ ํด๋น ํน์ API ํธ์ถ์ ๋ํ ์ก์ธ์ค ๊ถํ์ด ์๋์ง ํ์ธ.
(ex. ์น ์๋ฒ์ ๋ก๊ทธ์ธ ์ ํด๋น ์น์ ํด๋ผ์ด์ธํธ๋ ๋ณด์ ์์ธ์ค๋ฅผ ์ํด ์ธ์ฆ ํ ํฐ์ ์ฌ์ฉ.)
2. API ํค
- API๋ฅผ ํธ์ถํ๋ ํ๋ก๊ทธ๋จ or ์ ํ๋ฆฌ์ผ์ด์
์ ํ์ธํ๋ ๊ธฐ๋ฅ ์ํ.
- ์ ํ๋ฆฌ์ผ์ด์
์ ์๋ณํ๊ณ ์ ํ๋ฆฌ์ผ์ด์
์ ํน์ API ํธ์ถ์ ์ํํ๋๋ฐ ํ์ํ ์ก์ธ์ค ๊ถํ์ด ์๋์ง ํ์ธ.
- ์ธ์ฆ ํ ํฐ์ ๋นํด ์๋์ ์ผ๋ก ์์ ์ฑ์ด ๋จ์ด์ง์ง๋ง, ์ฌ์ฉ๋์ ๋ํ ๋ฐ์ดํฐ ์์ง์ ์ํด API ๋ชจ๋ํฐ๋ง ํ์ฉ.
โ Open API
์นด์นด์ค
https://developers.kakao.com/product
๋ค์ด๋ฒ
https://developers.naver.com/products/intro/plan/plan.md
๊ตฌ๊ธ
https://console.cloud.google.com/apis/library?supportedpurview=project&pli=1&inv=1&invt=Abhysw
๐ญ CRUD?
- Create (POST) - ์๋ก์ด ๋ฐ์ดํฐ ์์ฑ ์ ์ฌ์ฉ. ์๋ฒ์ ๋ฐ์ดํฐ ์ ์ถ.
- (ex. ์ฌ์ฉ์๊ฐ ํ์๊ฐ์ ํผ์ ์ ์ถํ๋ ๊ฒฝ์ฐ, ํด๋น ๋ฐ์ดํฐ๋ฅผ ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์๊ฒ ์ ์กํ์ฌ ์๋ฒ๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ์์ .)
- Read (GET) - ๋ฐ์ดํฐ ์ฝ์ ๋ ์ฌ์ฉ. ์กฐํ ๊ธฐ๋ฅ๋ง. ์๋ฒ์์ ๋ฐ์ดํฐ ์์ ํ์ง ์์.
- (ex. ์ฌ์ฉ์ ํ๋กํ ์ ๋ณด ์กฐํ ์, ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์๊ฒ GET ์์ฒญ์ ๋ณด๋ด ํด๋น ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์กฐํ ๊ฐ๋ฅ.)
- Update (PATCH) - ๊ธฐ์กด์ ๋ฐ์ดํฐ๋ฅผ ์์ ์ ์ฌ์ฉ. ์ ์ฒด ๋ฐ์ดํฐ ๋ง๊ณ , ์ผ๋ถ ๋ฐ์ดํฐ ์์ ์ PATCH ์ฌ์ฉ.
- (ex. ์ฌ์ฉ์๊ฐ ์ด๋ฉ์ผ์ ์ ๋ฐ์ดํธ ํ ๋ ์๋ฒ์ PATCH ์์ฒญ์ ์ ์ก.)
- Delete (DELETE) - ๋ฐ์ดํฐ ์ญ์ ์ ์ฌ์ฉ.
- (ex. ์ฌ์ฉ์๊ฐ ํน์ ๊ฒ์๋ฌผ ์ญ์ ๋๋ ๊ณ์ ํํด๋ฅผ ํ๋ ๊ฒฝ์ฐ DELETE ์์ฒญ์ ์๋ฒ์ ์ ์ก.)
๐ HTTP ์๋ต ๋ฉ์๋ (HTTP request method)
GET | ์๋ฃ ์กฐํ ์์ฒญ |
POST | ์ ์๋ฃ ๋ฑ๋ก ์์ฒญ |
PATCH | ๊ธฐ์กด ์๋ฃ ์์ ์์ฒญ |
DELETE | ์๋ฃ ์ญ์ ์์ฒญ |
- ์ฃผ๋ก ์น ์๋ฒ์์๋ GET, POST ๋ฐฉ์ ์ฌ์ฉ๋จ.
- ์๋ฃ ์กฐํ ์์ฒญ์ผ ๊ฒฝ์ฐ GET ๋ฐฉ์์ผ๋ก ์์ฒญ.
- ์๋ฃ ๋ฑ๋ก, ์์ , ์ญ์ ์์ฒญ์ผ ๊ฒฝ์ฐ POST ๋ฐฉ์์ผ๋ก ์์ฒญ.
GET ์์ฒญ ex.
GET /index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 ...
* /index.html: ์์ฒญํ๋ ๋ฆฌ์์ค (ํ์ผ).
* Host: ์์ฒญํ๋ ์๋ฒ์ ๋๋ฉ์ธ (www.example.com)
* User-Agent: ์์ฒญ์ ๋ณด๋ด๋ ํด๋ผ์ด์ธํธ(๋ธ๋ผ์ฐ์ ) ์ ๋ณด
POST ์์ฒญ ex.
POST /register HTTP/1.1
Host: www.example.com
Content-Type: application/json
Content-Length: 123
{
"username": "Sooin",
"password": "123456789"
}
* /register: ์์ฒญํ๋ ๋ฆฌ์์ค (ํ์๊ฐ์
API)
* Content-Type: ์ ์กํ๋ ๋ฐ์ดํฐ ํ์
* Content-Length: ์ ์กํ ๋ฐ์ดํฐ์ ๊ธธ์ด
๐ API ํต์ ์์
๋ฌด๋ฃ api ์์ ์ ๊ณต ์ฌ์ดํธ
https://jsonplaceholder.typicode.com/
(Json ํ์ ๋ฐ์ดํฐ)
https://jsonplaceholder.typicode.com/posts
Json (JavaScript Object Notation)
: ํ
์คํธ ๊ธฐ๋ฐ์ ๋ฐ์ดํฐ ๊ตํ ํ์.
- ์ฃผ๋ก, ์น ์ ํ๋ฆฌ์ผ์ด์
์์ ๋ฐ์ดํฐ ์ ์ก ์ ์ฌ์ฉ๋จ.
- ๋ฐ์ดํฐ์ ๊ฐ๋
์ฑ ํฅ์์ ์ํด ๋ง๋ค์ด์ง ํ๊ธฐ๋ฒ. ๊ฐ์ฒด ํํ ์๋ฐ์คํฌ๋ฆฝํธ ํ๊ธฐ๋ฒ์ ๊ธฐ๋ฐ.
- Key : Value ํํ๋ก ์ด๋ฃจ์ด์ง.
{
// ํค : ๊ฐ
"name": "์์ธ",
"age": 23,
"city": "SEOUL",
"fruits" : ["orange", "grape", "peach"] // ๋ฐฐ์ด
}
์์
โ ํด๋ผ์ด์ธํธ→์๋ฒ JSON ์ ์ก (POST ์์ฒญ)
const data = { name: "์์ธ", age: 23 }; fetch('https://example.com/api', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }) .then(response => response.json()) .then(data => console.log(data));โ
โ ์๋ฒ→ํด๋ผ์ด์ธํธ JSON ๋ฐํ (GET ์์ฒญ)
fetch('https://example.com/api') .then(response => response.json()) .then(data => { console.log(data); // JSON ์๋ต ์์: { "name": "์์ธ", "age": 23 } });โ
* response.json() : ์๋ฒ ์๋ต body ๋ฐ์ดํฐ๋ฅผ JSON ํ์์ผ๋ก ๋ณํ.
* API ์ฃผ์(URL)๋ฅผ ํตํด API๋ฅผ ํธ์ถํ๋ฉด, ์๋ฒ๋ ์์ ๊ฐ์ Json ๋ฐ์ดํฐ๋ค์ ์ ๋ฌํด์ค.
โท axios ์ค์น (React)
yarn add axios
โท JSON ์๋ฒ ์ค์น (React)
์ค์น
yarn add json-server@0.17.4
์คํ
json-server --watch db.json
๐ axios
API ํธ์ถ ์์ฑ์์น
- ์ฃผ๋ก, ์ปดํฌ๋ํธ ํ์ผ ๋ด๋ถ ๋๋ ๋ณ๋์ ํ์ผ์ ์์ฑ
โ ์๋ก์ด ํ๋ก์ ํธ ๋ง๋ค๊ณ App.tsx ํ์ผ์ ์๋ ์์ ์ฝ๋ ์ค์ตํด๋ณด๊ธฐ
import { useState, useEffect } from 'react';
import axios from 'axios';
import './App.css';
function App() {
const [posts, setPosts] = useState([]);
const [newPost, setNewPost] = useState({ title: '', body: '', userId: 1 });
// GET ์์ฒญ
useEffect(() => { //useEffect๋ฅผ ํตํด ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ๋ ๋ ์๋์ผ๋ก GET ์์ฒญ ์คํ๋จ.
axios.get('https://jsonplaceholder.typicode.com/posts')
.then(response => {
console.log(response.data);
setPosts(response.data); // ๋ฐ์ดํฐ๋ฅผ ์ํ์ ์ ์ฅ
})
.catch(error => {
console.error('Error fetching data:', error);
});
}, []);
// POST ์์ฒญ
const handlePost = () => { //๋ฒํผ ํด๋ฆญ์ ๋ฅผ ํตํด ์ปดํฌ๋ํธ๊ฐ ๋ง์ดํธ๋ ๋ ์๋์ผ๋ก GET ์์ฒญ ์คํ๋จ.
axios.post('https://jsonplaceholder.typicode.com/posts', newPost)
// then/catch๋ฅผ ํตํ ์๋ต ์ฒ๋ฆฌ ํ์ธ
.then(response => {
console.log(response.data);
alert('Post created successfully');
}) // ์ฑ๊ณต
.catch(error => {
console.error('Error creating post:', error); // ์๋ฌ ํธ๋ค๋ง(์๋ฌ ๋ฉ์์ง ํ์)
}); // ์คํจ
};
return (
<div>
<h1>React Axios Example</h1>
<h2>Posts</h2>
<ul>
{posts.map((post: any) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
<h2>Create New Post</h2>
<input
type="text"
placeholder="Title"
value={newPost.title}
onChange={(e) => setNewPost({ ...newPost, title: e.target.value })}
/>
<textarea
placeholder="Body"
value={newPost.body}
onChange={(e) => setNewPost({ ...newPost, body: e.target.value })}
></textarea>
<button onClick={handlePost}>Create Post</button>
// ๋ฒํผ ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ POST ์์ฒญ์ผ๋ก ์๋ฒ๋ก ์ ์ก
</div>
);
}
export default App;
๐ก fetch
- fetch: ๋ธ๋ผ์ฐ์ ๋ด์ฅ ํจ์
๋คํธ์ํฌ ์์ฒญ ์ ์ฌ์ฉ.
import { useState, useEffect } from 'react';
function Posts() {
const [posts, setPosts] = useState([]); //posts: API๋ก ๋ฐ์ ๋ฐ์ดํฐ ์ ์ฅ
const [loading, setLoading] = useState(true); //loading: ๋ฐ์ดํฐ ๋ก๋ฉ ์ํ ์๋ฆผ
const [error, setError] = useState(null); //error: ์๋ฌ ๋ฐ์ ์, ํด๋น ๋ฉ์์ง ์ ์ฅ
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
setPosts(data); //loading์ด true๋ฉด ๋ก๋ฉ ๋ฉ์์ง ํ์
setLoading(false);
})
.catch(error => {
setError(error.message); //loading์ด false๋ฉด ์๋ฌ ๋ฉ์์ง ํ์
setLoading(false);
});
}, []); // ๋น ๋ฐฐ์ด์ ์ฌ์ฉํ์ฌ ์ฒ์ ๋ง์ดํธ๋ ๋๋ง ์คํ
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;
return (
<div>
<h1>Posts</h1>
<ul>
{posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
);
}
export default Posts;
↓ ↓ ↓ ↓
โ ๋น๋๊ธฐ ์ฒ๋ฆฌ
API ํธ์ถ์ async์ await์ ์ด์ฉํด ๋น๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ค๋ฉด ๊ฐ๋
์ฑ์ด ํฅ์๋์ด,
์ฝ๋๋ค์ด ์ด๋ค ์ญํ ์ ํ๋ ์ฝ๋์ธ์ง, ์ฝ๋์ ์คํ์์๋ฅผ ์ง๊ด์ ์ผ๋ก ํ์ธ ๊ฐ๋ฅ + ์๋ฌ ์ฒ๋ฆฌ๋ ์ฉ์ด.
useEffect(() => {
const fetchPosts = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
if (!response.ok) {
throw new Error('Network response was not ok');
}
const data = await response.json();
setPosts(data);
setLoading(false);
} catch (error) {
setError(error.message);
setLoading(false);
}
};
fetchPosts();
}, []);
๐ต http
const https = require('https');
https.get('https://jsonplaceholder.typicode.com/posts', (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log(JSON.parse(data));
});
}).on('error', (err) => {
console.error(err.message);
});
๐ฃ dio
import 'package:dio/dio.dart';
void main() async {
final dio = Dio();
// GET ์์ฒญ
try {
Response response = await dio.get('https://jsonplaceholder.typicode.com/posts');
print(response.data);
} catch (e) {
print('Error fetching data: $e');
}
// POST ์์ฒญ
try {
Response response = await dio.post(
'https://jsonplaceholder.typicode.com/posts',
data: {
'title': 'test',
'body': 'blahblah',
'userId': 1,
},
);
print('${response.data}');
} catch (e) {
print('Error posting data: $e');
}
}
๐ ์ ์ฉํ ์ฌ์ดํธ
npm
https://www.npmjs.com/search?q=express
headers๋ฅผ ์ฌ์ฉํด ์ค์ ํ ์ ์๋ ํค๋ ๋ชฉ๋ก.
https://fetch.spec.whatwg.org/#forbidden-header-name
๐ ์ฐธ๊ณ ์๋ฃ
https://dev-coco.tistory.com/98
https://aws.amazon.com/ko/what-is/api/
https://brunch.co.kr/@operator/65
https://gitbook-js.hyobb.com/section4/4-4
https://ko.javascript.info/fetch
'๊ณต๋ถ > GDG' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
React ํ๋ก์ ํธ ์์ฑ (0) | 2024.10.30 |
---|---|
Javascript 2 DOM (5) | 2024.10.07 |
GDG-WEB 2์ฃผ์ฐจ ๊ณผ์ (0) | 2024.10.01 |
Javascript 1-4 ์ฐ์ฐ์ (0) | 2024.09.30 |
Javascript 1-3 ์ ์ด๋ฌธ (0) | 2024.09.30 |