"๊ทธ๋ฐ REST API๋ก ๊ด์ฐฎ์๊ฐ"๋ฅผ ์ฐธ๊ณ ํ์ฌ ์ ๋ฆฌํ ๋ด์ฉ์ ๋๋ค.
REST๋?
- REpresentational State Transfer์ ์ฝ์์ ๋๋ค.
- ์น ์๋น์ค ์ํคํ ์ฒ์ ์คํ์ผ ์ค ํ๋๋ก, ๋คํธ์ํฌ๋ฅผ ํตํด ํด๋ผ์ด์ธํธ์ ์๋ฒ๊ฐ ์ํธ์์ฉํ๋ ๋ฐฉ์์ ์ ์ํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
- ์ธํฐ๋ท์์ ์ด๋ป๊ฒ ์ ๋ณด๋ฅผ ๊ณต์ ํ ๊ฒ์ธ์ง์ ๋ํ ํด๋ต์ผ๋ก 1991๋ ์น(Web)์ด ๋ฑ์ฅํ์ต๋๋ค.
- ์น์ HTML์ด๋ผ๋ ํ์์ผ๋ก ์ ๋ณด๋ฅผ ํํํ๊ณ , ์ ๋ณด๋ค์ ๋ํ ์๋ณ์๋ก URI๋ฅผ ์ ํํ๊ณ , HTTP๋ผ๋ ํ๋กํ ์ฝ๋ก ์ ๋ณด๋ฅผ ์ ์กํฉ๋๋ค.
- 2000๋ Roy T. Fielding์ ๊ธฐ์กด์ ์น์ ๋ง๊ฐํธ๋ฆฌ์ง ์๊ณ HTTP๋ฅผ ๊ฐ์ ํ ์ ์์์ง์ ๋ํ ๋ ผ๋ฌธ์ ๋ฐํํ๊ณ , ์ด๊ฒ์ด REST ์์ต๋๋ค.
REST API๋?
- REST API๋ REST ์ํคํ ์ฒ๋ฅผ ๋ฐ๋ฅด๋ API๋ก, RESTful API๋ผ๊ณ ๋ ํฉ๋๋ค.
- ํ๋ง๋๋ก ์๋ฒ์ ์์์ ์ ์ํ๊ณ ์์์ ๋ํ ์ฃผ์๋ฅผ ์ง์ ํ๋ ๋ฐฉ๋ฒ์ด๋ผ๊ณ ํ ์ ์๊ฒ ์ต๋๋ค.
- ์๋ฐํ ๋งํ์๋ฉด, Roy T. Fielding์ด ์ ์ํ REST ์ค๊ณ ์์น์ ๋ชจ๋ ์ง์ผ์ผ๋ง REST๋ฅผ ๋ฐ๋ฅธ๋ค๊ณ ๋ณผ ์ ์์ต๋๋ค.
REST ์ค๊ณ ์์น 6๊ฐ์ง
1. Client-Server
- ๋คํธ์ํฌ๊ฐ ํด๋ผ์ด์ธํธ์ ์๋ฒ๋ก ๊ตฌ์ฑ๋์ด์ผ ํ๋ฉฐ, ์๋ก ์์ ํ ๋ ๋ฆฝ์ ์ด์ด์ผ ํฉ๋๋ค.
- ํด๋ผ์ด์ธํธ๋ ์์ฒญ ๋ฆฌ์์ค์ URI๋ง ์๋ฉด ๋๊ณ , ์๋ฒ๋ HTTP๋ฅผ ํตํด ์์ฒญ๋ ๋ฆฌ์์ค๋ฅผ ์ ๋ฌ๋ง ํ๋ฉด ๋ฉ๋๋ค.
- ์ด๋ฒคํธ ๊ธฐ๋ฐ ์ํคํ ์ฒ๋ REST๊ฐ ์๋๋๋ค.
2. Stateless
- ํด๋ผ์ด์ธํธ์ ์๋ฒ๊ฐ ์ํ๋ฅผ ๊ฐ์ง๊ณ ์์ง ์์ผ๋ฉฐ ์๋ก์ ์ํ๋ฅผ ์ถ์ ํ์ง ์์ต๋๋ค.
- ๊ฐ ์์ฒญ์ ๋ ๋ฆฝ์ ์ผ๋ก ์ฒ๋ฆฌ๋๋ฉฐ, ์๋ฒ๋ ์ด์ ์์ฒญ์ ์ปจํ ์คํธ๋ฅผ ์ ์ฅํ์ง ์์ต๋๋ค.
3. Cacheability
- ์๋ฒ ์๋ต์ ์บ์ฑ ๊ฐ๋ฅ ์ฌ๋ถ๋ฅผ ํ์ํด์ผ ํฉ๋๋ค.
- ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ๋ก๋ถํฐ ์์ ํ ์ด์ ์๋ต์ ์ ์ฅํ์ฌ ํด๋น ๋ฐ์ดํฐ๊ฐ ๋ค์ ํ์ํ ๋ ์บ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ํ๋ ๊ฒ์ ๋๋ค.
4. Layered System
- ํด๋ผ์ด์ธํธ์ ์๋ฒ ์ธ์๋ ์ฌ๋ฌ ์ค๊ฐ์๊ฐ ์์ ์ ์์ต๋๋ค.
- ๊ทธ๋ฌ๋ ํด๋ผ์ด์ธํธ, ์๋ฒ๊ฐ ์ต์ข ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ ํต์ ํ๋์ง ์ค๊ฐ์์ ํต์ ํ๋์ง ์ ์ ์๋๋ก ์ค๊ณํด์ผ ํฉ๋๋ค.
5. Uniform Interface
- ํด๋ผ์ด์ธํธ์ ์๋ฒ๊ฐ ์ผ๊ด๋ ๋ฐฉ์์ผ๋ก ํต์ ํด์ผ ํ๋ฉฐ, ์ด๋ก์จ ์ ์ฒด ์์คํ ์ ๋ง๊ฐ๋จ๋ฆฌ์ง ์๊ณ ๊ฐ ๋ถ๋ถ์ ๋ณ๊ฒฝํ ์ ์์ด์ผ ํฉ๋๋ค.
- Uniform Interface ์์น์ Identification of resources, Manipulation of resources through representations, self-descriptive messages, Hypermedia as the engine of application state(HATEOAS)์ 4๊ฐ์ง ์ ์ฝ ์กฐ๊ฑด์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
6. Code-On-Demand(optional)
- ์ผ๋ฐ์ ์ผ๋ก ์ ์ ๋ฆฌ์์ค๋ฅผ ์ ์กํ์ง๋ง, ๊ฒฝ์ฐ์ ๋ฐ๋ผ ์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ์์ ์คํ์ํฌ ์ ์๋ ๋ก์ง์ ์ ์กํ ์ ์์ต๋๋ค.
- ์๋ฅผ ๋ค๋ฉด, HTML <script> ํ๊ทธ์์ Javascript ํ์ผ์ ๊ฐ์ ธ์ ์คํํ๋ ๊ฒ์ ๋๋ค.
Uniform Interface
REST API๋ฅผ ์ค๊ณํ ๋ ๊ฐ์ฅ ์์น๋๋ก ์ง์ผ์ง๊ธฐ ์ด๋ ค์ด ๊ตฌ์ฑ ์์์ ๋๋ค.
Uniform Interface ์์น์๋ 4๊ฐ์ง ์ ์ฝ ์กฐ๊ฑด์ด ์์ต๋๋ค.
1. Identification of resources
- ์์ฒญ๋ ๋ฆฌ์์ค๋ URI๋ก ์๋ณ ๊ฐ๋ฅํด์ผ ํฉ๋๋ค.
- ํด๋ผ์ด์ธํธ๋ ์๋ฒ์ ์ ์ฅ๋ ๋ฆฌ์์ค๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด URI์ HTTP GET ์์ฒญ์ ๋ณด๋ผ ์ ์์ต๋๋ค.
2. Manipulation of resources through representations
- ์ ์กํ ํํ์ ํตํด ํด๋ผ์ด์ธํธ๊ฐ ๋ฆฌ์์ค๋ฅผ ์กฐ์ํ ์ ์์ด์ผ ํฉ๋๋ค.
- HTTP ๋ฉ์๋(GET, POST, PUT, DELETE)๋ฅผ ํตํด ๋ฆฌ์์ค๋ฅผ ์ด๋ป๊ฒ ์กฐ์ํ ๊ฒ์ธ์ง ํํํ ์ ์์ต๋๋ค.
3. Self-descriptive messages
- ๊ฐ ๋ฉ์์ง๋ ํด๋ผ์ด์ธํธ์ ์๋ฒ๊ฐ ์์ฒญ ๋ฐ ์๋ต์ ์ดํดํ๋ ๋ฐ ํ์ํ ๋ชจ๋ ์ ๋ณด๋ฅผ ํฌํจํด์ผ ํฉ๋๋ค.
- ์๋ฅผ ๋ค๋ฉด ์๋์ ๊ฐ์ HTTP ์๋ต์ ์ ์ ํ HTTP ๋ฉ์๋, ์ํ์ฝ๋๋ฅผ ์ฌ์ฉํด์ ๋ฆฌ์์ค๋ฅผ ์์ฑํ๋ค๋ ๊ฒ์ ์ ์ ์๊ณ , Content-Type ํค๋๋ฅผ ํฌํจํ์ฌ JSON ํ์์ ๋ฐ์ดํฐ๋ผ๋ ๊ฒ์ ์๋ ค์ค๋๋ค.
HTTP/1.1 201 Created
Host: www.example.com
Content-Type: application/json
{
"id": 123,
"username": "johndoe",
"email": "johndoe@example.com",
"created_at": "2023-08-02T12:34:56Z"
}
4. Hypermedia as the engine of application state (HATEOAS)
- ํด๋ผ์ด์ธํธ๋ ์๋ฒ๊ฐ ์ ๊ณตํ๋ ํ์ดํผ๋งํฌ๋ฅผ ํตํด ์ ํ๋ฆฌ์ผ์ด์ ์ํ๋ฅผ ์ ์ดํฉ๋๋ค.
- ์๋ฒ๋ ํด๋ผ์ด์ธํธ์๊ฒ ๊ฐ๋ฅํ ๋ค์ ์์ ์ ๋ํ ๋งํฌ๋ฅผ ์ ๊ณตํ์ฌ, ํด๋ผ์ด์ธํธ๊ฐ ์์คํ ์ ํ์ํ๊ณ ์ฌ์ฉํ ์ ์๋๋ก ํฉ๋๋ค.
- ์๋ฅผ ๋ค๋ฉด ์๋์ ๊ฐ์ HTTP ์๋ต์ Link ํค๋๋ฅผ ํตํด ์ฐ๊ฒฐ๋ ๋ค๋ฅธ ๋ฆฌ์์ค์ ๋งํฌ๋ฅผ ์๋ ค์ฃผ๊ณ ์์ต๋๋ค.
HTTP/1.1 200 OK
Content-Type: application/json
Link: </articles/1>; rel="previous", </articles/2>; rel="next";
{
"title": "์ฒซ ๋ฒ์งธ ๊ฒ์๊ธ",
"content": "๋ณธ๋ฌธ"
}
์ Uniform Interface๋ฅผ ์ง์ผ์ผ ํ ๊น?
- ์๋ฒ์ ํด๋ผ์ด์ธํธ์ ๋ ๋ฆฝ์ ์งํ, ์ฆ ์๋ฒ์ ๊ธฐ๋ฅ์ด ๋ณ๊ฒฝ๋์ด๋ ํด๋ผ์ด์ธํธ๋ฅผ ๋ณ๊ฒฝํ ํ์๊ฐ ์๋๋ก ํ๊ธฐ ์ํจ์ ๋๋ค.
- REST๋ฅผ ์งํจ ๋ํ์ ์ธ ์ฌ๋ก๊ฐ ์น์
๋๋ค.
- ์น ํ์ด์ง๋ฅผ ๋ณ๊ฒฝํ๋ค๊ณ ์น ๋ธ๋ผ์ฐ์ ๋ฅผ ๋ณ๊ฒฝํ ํ์๋ ์๊ณ , ๋ฐ๋๋ก ์น ๋ธ๋ผ์ฐ์ ๋ฅผ ๋ณ๊ฒฝํ๋ค๊ณ ์น ํ์ด์ง๋ฅผ ๋ณ๊ฒฝํ ํ์๊ฐ ์์ต๋๋ค.
- HTML, HTTP ๋ช ์ธ๊ฐ ๋ฐ๋์ด๋ ์น์ ์ ๋์ํฉ๋๋ค.
๋ชจ๋ ์ ์ฝ ์กฐ๊ฑด์ ์ง์ผ์ REST API๋ฅผ ์ค๊ณํด์ผ ํ ๊น?
- Roy T. Fielding์ ์์คํ ์ ์ฒด๋ฅผ ํต์ ํ ์ ์๊ฑฐ๋, ํด๋ผ์ด์ธํธ์ ์๋ฒ์ ๋ ๋ฆฝ์ ์งํ(= ์๋ก์ ๋ณ๊ฒฝ์ด ์ํฅ์ ์ฃผ์ง ์์)์ ๊ด์ฌ์ด ์๋ค๋ฉด REST์ ๋ฐ์ง๋๋ผ ์๊ฐ์ ๋ญ๋นํ์ง ๋ง๋ผ๊ณ ํฉ๋๋ค. (๋์ ๊ทธ๋ฌ๋ฉด ์๋ฐํ ๋งํ๋ฉด REST๋ ์๋๋ผ๊ณ ํ๋ค์ ๐ )
- ์ ๋ฆฌํ์๋ฉด, REST๋ฅผ ์์น๋๋ก ๋ฐ๋ฅผ ๊ฒ์ธ์ง๋ API๋ฅผ ์ค๊ณํ๋ ์ฌ๋๋ค์ด ์ค์ค๋ก ํ๋จํด์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค.
์ผ๋ฐ์ ์ธ REST API ์ค๊ณ ๋ฐฉ๋ฒ
Roy T. Fielding์ด ๋งํ๋ ์์น๋๋ก์ REST API๋ ์๋๊ฒ ์ง๋ง, REST API ์ค๊ณ์ Best Practice๋ฅผ ์ ๋ฆฌํด๋ณด๊ณ ์ ํฉ๋๋ค.
ํต์ฌ์ HTTP ๋ฉ์๋์ URI๋ฅผ ์กฐํฉํด์ ๋ฆฌ์์ค๋ฅผ ์์ฒญํ๋ ์ผ๊ด๋ ์๋ ํฌ์ธํธ๋ฅผ ์ ์ํด์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค.
1. HTTP ๋ฉ์๋
์๋ฒ ๋ฆฌ์์ค์ ๋ํด ์ด๋ค ๋์์ ํํ๋์ง๋ฅผ ์๋ฏธํฉ๋๋ค.
GET
- ์๋ฒ์ ๋ฆฌ์์ค๋ฅผ ์์ฒญํ๋ ๋์์ ์๋ฏธํฉ๋๋ค.
- ์์ฒญ ๋ณธ๋ฌธ์ ์ฌ์ฉํ์ง ์๊ณ , Path Variable ์ด๋ Query String ์ ์ฌ์ฉํ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค.
- ๋ช
์ธ์ GET ์์ฒญ์ ๋ณธ๋ฌธ์ ๋ด์ผ๋ฉด ์ ๋๋ค๊ณ ๋์ด ์๋ ๊ฒ์ ์๋์ง๋ง, HTTP Client ๊ตฌํ์ฒด์ ๋ฐ๋ผ ์ ์ก์ด ์ ๋ ์๋ ์์ต๋๋ค. [์ฐธ๊ณ ]
- Path Variable vs Query String
- ์ด๋ค ๋ฆฌ์์ค๋ฅผ ์๋ณํ๊ณ ์ถ์ ๋๋ Path Variable์ ์ฌ์ฉํฉ๋๋ค.
GET /expenses/3427 - ๋ฆฌ์์ค์ ๋ํด ๊ฒ์, ์ ๋ ฌ, ํํฐ๋ง, ํ์ด์ง๋ค์ด์
์ ํ๊ณ ์ถ์ ๋๋ Query String์ ์ฌ์ฉํฉ๋๋ค.
GET /expenses?start-date=2024-08-01&end-date=2024-08-03
- ์ด๋ค ๋ฆฌ์์ค๋ฅผ ์๋ณํ๊ณ ์ถ์ ๋๋ Path Variable์ ์ฌ์ฉํฉ๋๋ค.
- Path Variable vs Query String
POST
- ์๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ ๋ ์ฌ์ฉํ๋๋ฐ, ๊ทธ ์ค์์๋ ๋ฆฌ์์ค ์์ฑ์ ์์ฒญํ๋ ๋์์ผ๋ก ์ฃผ๋ก ์ฌ์ฉํฉ๋๋ค.
- ์์ฒญ ๋ณธ๋ฌธ์ ์์ฑํ ๋ฆฌ์์ค์ ๋ฐ์ดํฐ๋ฅผ ๋ด์์ ๋ณด๋ ๋๋ค.
- ๋ฉฑ๋ฑ์ฑ์ ๊ฐ์ง์ง ์์ต๋๋ค. ์ฆ, ์ฌ๋ฌ ๋ฒ์ ์์ฒญ์ ์๋ฒ ๋ฆฌ์์ค์ ๊ฐ๊ฐ ๋ค๋ฅธ ์ํฅ์ ๋ฏธ์นฉ๋๋ค.
PUT
- ์๋ฒ ๋ฆฌ์์ค๋ฅผ ๊ธฐ์กด์ ์์ผ๋ฉด ์์ฑํ๊ณ , ์์ผ๋ฉด ์นํํ๋ ๋์์ ์๋ฏธํฉ๋๋ค. (๋ฎ์ด์ฐ๊ธฐ ๊ฐ๋ )
- ์์ฒญ ๋ณธ๋ฌธ์ ์นํํ ๋ฐ์ดํฐ๋ฅผ ๋ด์์ ๋ณด๋ ๋๋ค.
- ๋ฉฑ๋ฑ์ฑ์ ๊ฐ์ง๋๋ค. ์ฆ, ์ฌ๋ฌ ๋ฒ ์์ฒญ์ ๋ณด๋ด๋ ๊ฐ์ ํจ๊ณผ๋ฅผ ๋ณด์ ๋๋ค.
PATCH
- ์๋ฒ ๋ฆฌ์์ค์ ์ผ๋ถ๋ง ์์ ํ๋ ๋์์ ์๋ฏธํฉ๋๋ค.
- ์์ฒญ ๋ณธ๋ฌธ์ ์นํํ ๋ฐ์ดํฐ๋ฅผ ๋ด์์ ๋ณด๋ ๋๋ค.
- ๋ฉฑ๋ฑ์ฑ์ ๊ฐ์ง์ง ์์ต๋๋ค. ์ฆ, ์ฌ๋ฌ ๋ฒ์ ์์ฒญ์ ์๋ฒ ๋ฆฌ์์ค์ ๊ฐ๊ฐ ๋ค๋ฅธ ์ํฅ์ ๋ฏธ์นฉ๋๋ค.
- ํ์ง๋ง PATCH๋ฅผ PUT๊ณผ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์ฌ์ฉํ๋๋ก ์ค๊ณํ๋ค๋ฉด ๋ฉฑ๋ฑ์ฑ์ ๊ฐ์ง๊ฒ ํ ์๋ ์์ต๋๋ค. [์ฐธ๊ณ ]
DELETE
- ์๋ฒ ๋ฆฌ์์ค๋ฅผ ์ญ์ ํ๋ ๋์์ ์๋ฏธํฉ๋๋ค.
- GET๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ์์ฒญ์ ๋ณธ๋ฌธ์ ๋ด์ผ๋ฉด ์ ๋๋ค๊ณ ๋์ด ์๋ ๊ฒ์ ์๋์ง๋ง, HTTP Client ๊ตฌํ์ฒด์ ๋ฐ๋ผ ์ ์ก์ด ์ ๋ ์๋ ์์ต๋๋ค.
2. ๋ฆฌ์์ค
๋์ฌ ๋ณด๋ค ๋ช ์ฌ
- URI์๋ ๋ช ์ฌํ์ ๋ฆฌ์์ค๋ฅผ ํฌํจํ๊ณ ๋ฆฌ์์ค์ ๋ํ ํ์๋ฅผ ํํํ์ง ์๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ด๋ฏธ HTTP ๋ฉ์๋๋ก ํํํ ์ ์์ผ๋๊น์!
๋จ์ ๋ณด๋ค ๋ณต์
- ๊ฐ๋ณ ๋ฆฌ์์ค์ ๋ฆฌ์์ค์ ์งํฉ์ ๊ตฌ๋ถํ๊ธฐ ์ํด ๋ณต์ํ์ ๊ถ์ฅํฉ๋๋ค.
๋ฐ์ค(_)๋ณด๋ค๋ ํ์ดํ(-)
- ๊ฐ๋ ์ฑ์ ์ํด ๋ฐ์ค ๋ณด๋ค๋ ํ์ดํ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
๊ณ์ธต ๊ด๊ณ๋ฅผ ๋ํ๋ผ ๋๋ ์ฌ๋์(/)
- ์ฌ๋์๋ฅผ ์ฌ์ฉํ์ฌ ๋ฆฌ์์ค์ ๊ณ์ธต ๊ด๊ณ๋ฅผ ํํํฉ๋๋ค.
GET /users/123/playlists
3. ๊ฒ์ / ์ ๋ ฌ / ํํฐ๋ง / ํ์ด์ง๋ค์ด์
๋ณดํต GET ๋ฉ์๋ URI์ Query String์ ์ฌ์ฉํด ํํํฉ๋๋ค.
- ๊ฒ์ : GET /expenses?search=์ผํ
- ์ ๋ ฌ : GET /expenses?sort=amount_asc
- ํํฐ๋ง : GET /expenses?category=food&start_date=2024-08-01&end_date=2024-08-03
- ํ์ด์ง๋ค์ด์ : GET /expenses?page=1&limit=10
๋์ ์๊ฐ
REST ์์น ์ค Uniform Interface๋ฅผ ์์ฃผ ์ฒ ์ ํ ์ง์ผ์ ์ค๊ณํ๊ธฐ๋ ์ด๋ ต๋ค๊ณ ๋ณด์์ต๋๋ค.
๋น ๋ฅด๊ฒ ๊ฐ๋ฐํด์ผ ํ๋ ์ํฉ์์๋ ๋ชจ๋ ์์น์ ์ค์ํ๋ ๊ฒ ๊ณผ์ฐ ์ค์ฉ์ ์ผ๊น ์ถ๊ธฐ๋ ํ๊ณ ์.
์ผ๋ฐ์ ์ผ๋ก ์๋ ค์ง REST API ๋์์ธ ๊ฐ์ด๋์กฐ์ฐจ๋ ์งํค๊ธฐ ์ด๋ ค์ด ๊ฒฝ์ฐ๋ ์ข ์ข ๋ณด์ ๋๋ค.
๊ฒฐ๊ตญ์ ํ์ค์ ๋ฐ๋ฅด๋ ค๋ ๋ ธ๋ ฅ๊ณผ ๋์์, ํ์๋ฅผ ํตํด ์ผ๊ด๋๊ณ ์์ธก ๊ฐ๋ฅํ ์ค๊ณ๋ฅผ ํ๋ ๊ฒ์ด ์ค์ํ๋ค๋ ์๊ฐ์ด ๋ค์์ต๋๋ค. [์ฐธ๊ณ ]
์ฐธ๊ณ
- https://www.ibm.com/kr-ko/topics/rest-apis
- https://codewords.recurse.com/issues/five/what-restful-actually-means
- https://roy.gbiv.com/untangled/
- https://restfulapi.net/
- https://wayhome25.github.io/etc/2017/11/26/restful-api-designing-guidelines/
- https://restfulapi.net/resource-naming/
'Dev > ์ค๊ณ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์๋ฌ์ฝ๋ ์ค๊ณ ๋ฒค์น๋งํน & NestJS์์ ์๋ฌ ์๋ต ์ปค์คํ ๋ฐฉ๋ฒ (0) | 2024.08.01 |
---|