| ํ๋ก์ ํธ ํ ๋ ๋ง๋ค Postman์ผ๋ก ํ
์คํธํ ๋ ๋ก๊ทธ์ธํ๊ณ Authorization ํ์ํ api๋ง๋ค ํ๋ํ๋ access token ๊ฐ ๊ธ์ด ๋ฃ๋ ๊ฒ ๋๋ฌด๋๋ฌด ๊ท์ฐฎ์์ ์ฐพ์๋ณด๋ค๊ฐ ์๊ฒ๋๋ค Swagger ์ฌ์ฉํ ๊ฑฐ๋ผ๋ฉด ์๊ด์๊ธด ํ์ง๋ง ์ง์ ์ ํ๋ก์ ํธ์์๋ Swagger๋ฅผ ์ฌ์ฉํ์ง ์๊ธฐ๋ก ๊ฒฐ์ ํ์๊ธฐ ๋๋ฌธ์ ์ด์ฉ ์ ์์๋ค |
0. Swagger๋ฅผ ์ฌ์ฉํ์ง ์์ ์ด์
[1] ๋ฐํ์ ํ๊ฒฝ์ ์ค์ผ (Dependency & Security)
: Swagger๋ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์คํ ์ค(Runtime)์ผ ๋ ํจ๊ป ๊ตฌ๋๋จ
- ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์นจํฌ: Swagger ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํ๋ก์ ํธ์ ์์กด์ฑ์ ํฌํจ๋์ด ์ค์ ์๋ฒ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ ํ๊ณ ๊ตฌ๋ ํ๊ฒฝ์ ์ํฅ์ ์ค
- ๋ณด์ ์ทจ์ฝ์ : ์ค์ ์ค์๋ก ์ด์(Production) ํ๊ฒฝ์์ Swagger UI๊ฐ ๋ ธ์ถ๋ ๊ฒฝ์ฐ, API ๊ตฌ์กฐ๋ ๋ฌผ๋ก ํ ์คํธ ํธ์ถ ๊ธฐ๋ฅ์ ํตํด ์ค๋ฐ์ดํฐ๊ฐ ์ ์ถ๋๊ฑฐ๋ ์กฐ์๋ ์ํ์ด ์์
- ๋ฐ๋ฉด RestDocs๋: ๋น๋ ์์ ์ ๋ฌธ์(์ ์ ํ์ผ)๋ฅผ ๋ง๋ค๊ณ ๋น ์ง. ์ค์ ์๋ฒ๊ฐ ๋์๊ฐ ๋๋ ๋ฌธ์ํ ๊ด๋ จ ์ฝ๋๊ฐ ์์ ๋์ํ์ง ์์ผ๋ฏ๋ก ๋ฐํ์ ํ๊ฒฝ์ด ์์ํ๊ฒ ์ ์ง๋จ
[2] ํ ์คํธ ๋ฐ์ดํฐ์ ์ค๋ฐ์ดํฐ์ ํผ์ฌ
: Swagger์ ๊ฐ์ฅ ํฐ ์ฅ์ ์ธ 'Try it out' ๊ธฐ๋ฅ์ด ์ญ์ค์ ์ผ๋ก ๋ฐ์ดํฐ ์ค์ผ์ ์์ธ์ด ๋จ
- ๊ฐ๋ฐ์๊ฐ ๋ฌธ์๋ฅผ ๋ณด๋ค๊ฐ ๋ฌด์ฌ์ฝ 'Execute' ๋ฒํผ์ ๋๋ฌ ์ด์ DB๋ ๊ณต์ฉ ๊ฐ๋ฐ DB์ ํ ์คํธ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์๋ฃ๊ฒ ๋ ์๋ ์์
- RestDocs: RestDocs๋ ๊ธฐ๋ณธ์ ์ผ๋ก '์ฝ๊ธฐ ์ ์ฉ' ๋ฌธ์๋ผ์ ๋ฐ์ดํฐ๋ฅผ ์ง์ ๋ ๋ ค๋ณผ ์ ์๊ธฐ ๋๋ฌธ์, ๋ฌธ์ ํ์ธ ๊ณผ์ ์์ ์ค์๋ก DB ์ํ๋ฅผ ๋ณ๊ฒฝํ ๋ฆฌ์คํฌ๊ฐ ์์ฒ ์ฐจ๋จ๋จ
[3] ๋น์ฆ๋์ค ๋ก์ง์ ๊ฐ๋ ์ฑ ์ ํด
- ํด๋ฆฐ ์ฝ๋ ๊ด์ ์์ ์ปจํธ๋กค๋ฌ๋ ๋น์ฆ๋์ค ํ๋ฆ์ ๋ณด์ฌ์ค์ผ ํ๋๋ฐ Swagger๋ฅผ ์ฐ๋ฉด ์ฝ๋์ 70~80%๊ฐ ๋ฌธ์์ฉ ์ค์ ๊ฐ์ผ๋ก ์ฑ์์ง
- @ApiOperation, @ApiResponse ๋ฑ ๋ก์ง๊ณผ ์๊ด์๋ ์ฝ๋๊ฐ ์ค์ ๋น์ฆ๋์ค ์ฝ๋๋ณด๋ค ๊ธธ์ด์ง๋ ๊ฒฝ์ฐ๊ฐ ๋ง์
- ์ง์ง ์ค์ํ ๋ก์ง(Validation, Service Call ๋ฑ)์ด ๋ฌธ์์ฉ ์ฝ๋์ ํ๋ฌปํ ๋ฒ๋ ค, ์ ์ง๋ณด์ ์ ๊ฐ๋ ์ฑ์ด ๋จ์ด์ง๊ณ ๋ฒ๊ทธ๋ฅผ ์ฐพ๊ธฐ ์ด๋ ค์์ง
[4] ๋ฌธ์์ ์ ๋ขฐ๋ (ํ ์คํธ ํต๊ณผ ํ์)
: ๋ฌธ์์ ์ค์ API๊ฐ ๋ฐ๋ก ๋ ธ๋ ํ์์ ๋ฐฉ์งํ ์ ์์
- Swagger: ์ฝ๋๋ฅผ ์์ ํ๊ณ ์ด๋ ธํ ์ด์ ์ ์ ๋ฐ์ดํธํ์ง ์์๋ ์๋ฒ๋ ์ ๋์๊ฐ. ์์ ๋๊ฒ์ ๋ํ ํ์ธ์ด ์๋์
- RestDocs: API ํ ์คํธ๊ฐ ์ฑ๊ณตํด์ผ๋ง ๋ฌธ์๊ฐ ์์ฑ๋จ. ๊ธฐ๋ฅ์ด ๋ฐ๋์๋๋ฐ ํ ์คํธ๋ฅผ ์์ ํ์ง ์์ผ๋ฉด ๋น๋ ์์ฒด๊ฐ ์คํจํ๋ฏ๋ก, ๋ฌธ์๋ ํญ์ ์ต์ ์ํ์ ์ ํ์ฑ์ ๋ณด์ฅ๋ฐ์
๊ทผ๋ฐ ์ด๋ ๊ฒ ํด๋๊ณ ์ ์ Spring Rest Docs๋ ์์ง ๋ชป ์จ๋ดค๋คใ ใ ใ ใ ํ๋ก ํธ์๋ ์๋ ํ๋ก์ ํธ๋ผ์ ํฐ ๋ฌธ์ ๋ ์์์ง๋ง
1. ์ ์ฉ๋ฐฉ๋ฒ
Postman Scripts
- Postman์ Scripts(๋๋ Tests) ํญ์ ์ฝ๋๋ฅผ ์์ฑํ๋ฉด, API ์๋ต์ด ์ฌ ๋ ํน์ ๊ฐ์ ์ถ์ถํด Postman์ ์ ์ญ ๋ณ์(Globals)์ ์๋์ผ๋ก ์ ์ฅํ ์ ์์.
CASE A: Access Token๋ง ๋ฐ๋ ๊ฒฝ์ฐ
์๋ฒ ์๋ต JSON์ ํค๊ฐ์ด access_token์ธ ๊ฒฝ์ฐ์.
// 1. ์๋ต ์ฑ๊ณต ์ฌ๋ถ ํ์ธ
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
// 2. JSON ๋ฐ์ดํฐ ํ์ฑ
const jsonData = pm.response.json();
// 3. ํ ํฐ ์ถ์ถ ๋ฐ ์ ์ญ ๋ณ์ ์ ์ฅ
// ์๋ฒ ์๋ต ํค๊ฐ access_token์ธ์ง accessToken์ธ์ง ํ์ธ ํ์
const token = jsonData.access_token || jsonData.accessToken;
if (token) {
pm.globals.set("access_token", token);
console.log("โ
Access Token ์ ์ฅ ์๋ฃ");
}
CASE B: Refresh Token๊น์ง ํจ๊ป ๋ฐ๋ ๊ฒฝ์ฐ
๋ ํ ํฐ์ ๋ชจ๋ ์ ์ฅํ์ฌ ๋์ค์ ํ ํฐ ์ฌ๋ฐ๊ธ API์์๋ ํ์ฉํ ์ ์์.
const jsonData = pm.response.json();
// Access Token ์ ์ฅ
const accessToken = jsonData.access_token || jsonData.accessToken;
if (accessToken) {
pm.globals.set("access_token", accessToken);
}
// Refresh Token ์ ์ฅ
const refreshToken = jsonData.refresh_token || jsonData.refreshToken;
if (refreshToken) {
pm.globals.set("refresh_token", refreshToken);
console.log("โ
Access & Refresh Token ๋ชจ๋ ์ ์ฅ ์๋ฃ");
}
3. ์ ์ฒด ์ ์ฉ ๊ณผ์
- ๋ก๊ทธ์ธ API ์ค์ : ๋ก๊ทธ์ธ(๋๋ ํ ํฐ ๋ฐ๊ธ) API์ Scripts ํญ์ ์ ์ฝ๋๋ฅผ ๋ถ์ฌ๋ฃ๊ณ ์ ์ฅํจ
- API ์คํ: Send ๋ฒํผ์ ๋๋ฌ ๋ก๊ทธ์ธ ์์ฒญ์ ๋ณด๋. ํ๋จ Console ์ฐฝ์ "์ ์ฅ ์๋ฃ" ๋ก๊ทธ๊ฐ ๋จ๋์ง ํ์ธํจ
- ๋ณ์ ํ์ธ: ์ค๋ฅธ์ชฝ ์๋จ ๊ฐ๋ก์ ์ฌ๋ฌ๊ฐ(variables) ์์ด์ฝ์ ํด๋ฆญํด Globals ํญ๋ชฉ์ ํ ํฐ ๊ฐ์ด ์ ๋ค์ด์๋์ง ํ์ธํจ.
- ๋ค๋ฅธ API์์ ์ฌ์ฉ:
- ํ ํฐ์ด ํ์ํ API์ Authorization ํญ์ผ๋ก ์ด๋ํจ.
- Auth Type์ Bearer Token์ผ๋ก ์ ํํจ.
- Token ํ๋์ ์ง์ ์ ๋ ฅ ๋์ {{access_token}}์ ์ ๋ ฅํจ. (๊ธ์ ์์ด ์ฃผํฉ์์ผ๋ก ๋ณํด์ผ ์ ์์)
4. ์๋ต ๊ตฌ์กฐ๊ฐ ๋ฐ๋ ๋ ๋์ฒ๋ฒ (Troubleshooting)
๋ง์ฝ ์๋ฒ ๊ฐ๋ฐ์๊ฐ ์๋ต JSON ๊ตฌ์กฐ๋ฅผ ๋ฐ๊พธ๋ฉด ์ฝ๋์ ์ถ์ถ ๊ฒฝ๋ก๋ฅผ ์์ ํด์ผ ํจ.
- ํค ์ด๋ฆ์ด ๋ฐ๋ ๊ฒฝ์ฐ:
- jsonData.access_token → jsonData.data.token ๋ฑ์ผ๋ก ๊ฒฝ๋ก๋ฅผ ์์ ํจ.
- ๋ณ์๊ฐ ๋นจ๊ฐ์์ผ๋ก ๋จ๋ ๊ฒฝ์ฐ:
- pm.globals.set("์ด๋ฆ", ...)์์ ์ค์ ํ ์ด๋ฆ๊ณผ {{์ด๋ฆ}}์ ์ ์ ์ด๋ฆ์ด ๋์๋ฌธ์๊น์ง ์ผ์นํ๋์ง ํ์ธํจ.
- ๊ฐ์ด ์ ์กํ๋ ๊ฒฝ์ฐ:
- Postman ์ข์ธก ํ๋จ Console์ ์ด์ด ์๋ฌ ๋ฉ์์ง๋ฅผ ํ์ธํ๊ณ , pm.response.json()์ผ๋ก ๋ค์ด์ค๋ ์ค์ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ํ์ ํจ.
6. ๊ฒฐ๋ก
์ด ์ค์ ์ ๋ง์น๋ฉด ๋ก๊ทธ์ธ API ํธ์ถ ํ ๋ฒ์ผ๋ก ๋ชจ๋ ํ ์คํธ ์ค๋น๊ฐ ๋๋จ!
7. ์ถ๊ฐ๋ก ํด๋ณผ ๊ฒ
๊ทผ๋ฐ ํ์ ๊ถํ์ด ๋ค๋ฅธ api๋ค์ ์ฌ ๋ก๊ทธ์ธ ์์ด ์ด์ด์ ํ ์คํธํ๊ณ ์ถ์ ๋ (์๋ฅผ ๋ค๋ฉด, customer๋ก ์ฃผ๋ฌธ์ ์์ฑํ๊ณ , ์งํ์ master๊ฐ ๋ชจ๋ customer์ ๋ํ ์ ์ฒด ์ฃผ๋ฌธ์ ํ์ธํ๋ ๊ฒฝ์ฐ) ์๋ ํ๊ฒฝ๋ณ์๋ฅผ ๋ถ๋ฆฌํด์ ๋ฐ์์ผ ํ๋๊น...
๋ก๊ทธ์ธํ ์ฌ์ฉ์๊ฐ ๊ด๋ฆฌ์(MANAGER/ADMIN)์ธ์ง ์ผ๋ฐ ์ฌ์ฉ์(USER)์ธ์ง์ ๋ฐ๋ผ ๋ณ์ ์ด๋ฆ์ ๋ค๋ฅด๊ฒ ์ ์ฅํ๋ฉด, ์ฌ๋ฌ ๊ณ์ ์ ํ ํฐ์ ๋ฒ๊ฐ์ ๊ฐ๋ฉฐ ํ ์คํธํ ๋ ํจ์ฌ ํธํด์ง๊ฒ๊ฐ์๋ฐ
(์๋๋ ์ง์ ํด๋ณด์ง ์์... ์ด์? ๊ฐ์๊ฒ๋๋ค)
1. Role์ด String์ธ ๊ฒฝ์ฐ
- ์๋ฒ ์๋ต JSON์์ role ๊ฐ์ด "ADMIN", "USER" ๋ฑ Enum์ด ์๋ ๋ฌธ์์ด๋ก ๋ฐ๋ก ์ค๋ ๊ฒฝ์ฐ
const jsonData = pm.response.json();
const token = jsonData.access_token || jsonData.accessToken;
const role = jsonData.role; // ์: "ADMIN", "USER", "MANAGER"
if (token && role) {
// role ๊ฐ์ ์๋ฌธ์๋ก ๋ณํํ์ฌ ๋ณ์๋ช
์์ฑ (์: admin_token, user_token)
const variableName = `${role.toLowerCase()}_token`;
pm.globals.set(variableName, token);
console.log(`โ
${role} ๊ถํ ํ ํฐ์ด {{${variableName}}}์ ์ ์ฅ๋จ`);
}
2. Role์ด Enum์ธ ๊ฒฝ์ฐ (๊ฐ์ฒด ๊ตฌ์กฐ ๋์)
์ผ๋ฐ์ ์ผ๋ก Java(Spring Boot) ๋ฑ์์ Enum์ ์ฌ์ฉํ๋ฉด, ์๋ต์ด ๋จ์ ๋ฌธ์์ด์ด ์๋๋ผ { "key": "ADMIN", "name": "๊ด๋ฆฌ์" } ์์ ๊ฐ์ฒด ํํ๋ก ๋ด๋ ค์ฌ ๋๊ฐ ๋ง์. ์ด๋ฅผ ๊ณ ๋ คํ ์ฝ๋์
const jsonData = pm.response.json();
const token = jsonData.access_token || jsonData.accessToken;
// Role์ด ๊ฐ์ฒด์ธ ๊ฒฝ์ฐ์ ๋ฌธ์์ด์ธ ๊ฒฝ์ฐ ๋ชจ๋ ๋์
let roleValue;
if (typeof jsonData.role === 'object' && jsonData.role !== null) {
roleValue = jsonData.role.key || jsonData.role.code; // Enum์ ํ๋๋ช
์ ๋ง์ถฐ ์์ (key ๋๋ code)
} else {
roleValue = jsonData.role;
}
if (token && roleValue) {
const variableName = `${roleValue.toLowerCase()}_token`;
pm.globals.set(variableName, token);
console.log(`โ
Enum ๊ธฐ๋ฐ ${roleValue} ํ ํฐ์ด {{${variableName}}}์ ์ ์ฅ๋จ`);
}
์ด๋ ๊ฒ Role๋ณ๋ก ์ ์ฅํ๋ฉด API ํ ์คํธ๋ฅผ ํ ๋ Authorization ์ค์ ์ ์ ์ฐํ๊ฒ ๋ฐ๊ฟ ์ ์์ ๋ฏ
- ๊ด๋ฆฌ์ API ํ ์คํธ ์: {{admin_token}} ์ฌ์ฉ
- ์ผ๋ฐ ์ ์ API ํ ์คํธ ์: {{user_token}} ์ฌ์ฉ
์ผ๋จ ์ง๊ธ์ ๋ก๊ทธ์ธ ์ access token๋ง ๋ฆฌํดํด์, role์ ๋ํ ์ ๋ณด๊ฐ ์์ด์ ์ด๋ ๊ฒ๋ง ์ ์๋ค
๋์ค์ ํด๋ณด๊ณ ์ถ๊ฐํ ์ง๋
'๊ธฐํ > ๊ฐ๋ฐ?' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| README ๊พธ๋ฏธ๊ธฐ - GitHub Stats Extended ์ปค์คํ ๋ฐฐํฌ ๋ฐ ํธ๋ฌ๋ธ์ํ ๊ธฐ๋ก (0) | 2026.03.17 |
|---|