๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๊ฐœ๋ฐœ/๋Ÿฐ์„ธ๊ถŒ

API ๋ฌธ์„œ ๊ฐœ์„ ๊ณผ ๋ฌธ์„œํ™” ํˆด Stoplight๋กœ ๋ณ€๊ฒฝํ•˜๊ธฐ

๊ธฐ์กด ํ”„๋กœ์ ํŠธ์—์„œ API ๋ฌธ์„œ๋ฅผ Springdoc์„ ํ†ตํ•ด OpenAPI 3.0 ์ŠคํŽ™์— ๋งž๊ฒŒ ์ž๋™ ์ƒ์„ฑํ•˜์—ฌ Swagger UI ์กฐํ•ฉ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ๋‹ค.
 


์•„๋ฌด๋ž˜๋„ ๊ฐ€์žฅ ์ต์ˆ™ํ•œ ํˆด์ด๊ธฐ๋„ ํ•˜๊ณ , ๋‹น์‹œ์—๋Š” Springdoc + Swagger UI ์กฐํ•ฉ์œผ๋กœ ๊ฐ€๋А๋ƒ, Spring Rest Docs๋ฅผ ์‚ฌ์šฉํ•˜๋А๋ƒ์—๋งŒ ์ง‘์ค‘ํ–ˆ๊ธฐ์— ์ง์ ‘ ์„œ๋ฒ„์— ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์—์„œ Swagger UI๋ฅผ ์„ ํƒํ–ˆ์—ˆ๋‹ค.

ํ•˜์ง€๋งŒ, ๋ฌธ์„œ๊ฐ€ ๊ด€๋ฆฌ๋˜์ง€ ์•Š๊ณ  ๊ฐœ๋ฐœ์ž๋“ค๊ฐ„ ์‚ฌ์šฉ๋ฅ ์ด ์ ์  ์ €์กฐํ•ด์ง€๋Š” ๊ฒƒ์„ ๋ฐœ๊ฒฌํ–ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ํ•ด์†Œํ•˜๊ณ ์ž ๋จผ์ € ๋ฌธ์„œ๋ฅผ ์ „๋ฐ˜์ ์œผ๋กœ ๊ฒ€ํ† ํ•ด๋ณด์•˜๋‹ค.
 

๊ฐœ์„ 

1. ํŒŒ๋ผ๋ฏธํ„ฐ ์„ค๋ช… ๋ถ€์žฌ


์š”์ฒญ๊ณผ ์‘๋‹ต ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋จผ์ € ์‚ดํŽด๋ณด์•˜๋Š”๋ฐ, ์„ค๋ช…์ด ๋ถ™์–ด์žˆ๋Š” ๊ฒƒ๋„ ์žˆ์ง€๋งŒ ๋ถ™์–ด์žˆ์ง€ ์•Š๊ณ  ๋‹จ์ˆœํžˆ example๋งŒ ํฌํ•จํ•˜์—ฌ ์šด์˜๋˜๊ณ  ์žˆ๋Š” ๊ฒƒ๋„ ์žˆ์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋“ค์„ ํ†ตํ•ฉํ•˜๊ธฐ ์œ„ํ•ด ๋ชจ๋“  ์š”์ฒญ, ์‘๋‹ต ํŒŒ๋ผ๋ฏธํ„ฐ์— ๋ถ€๊ฐ€ ์„ค๋ช…์„ ๋ถ™์—ฌ์ฃผ์—ˆ๋‹ค.
 

 
2. ์–ด๋“œ๋ฏผ ๊ธฐ๋Šฅ์˜ ๋…ธ์ถœ
API ๋ฌธ์„œ์— ๋…ธ์ถœ๋˜์ง€ ์•Š์•„๋„ ๋˜๋Š” ํ˜น์€ ๋…ธ์ถœ๋˜์ง€ ์•Š์•„์•ผ ํ•˜๋Š” ์–ด๋“œ๋ฏผ ๊ธฐ๋Šฅ๋“ค์˜ API๋“ค์ด ๊ณ ์Šค๋ž€ํžˆ ๋ฌธ์„œ์— ๋…ธ์ถœ๋˜๊ณ  ์žˆ์—ˆ๋‹ค. ์–ด๋“œ๋ฏผ ํ† ํฐ์ด ์žˆ์–ด์•ผ ๋™์ž‘ํ•˜๊ธฐ์— ๊ทธ๋ฆฌ ํฐ ๋ฌธ์ œ๋Š” ์•„๋‹ˆ์ง€๋งŒ API ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•  ๋•Œ ํ•„์š”์—†๋Š” ๊ฒƒ๊นŒ์ง€ ๋…ธ์ถœ๋  ํ•„์š”๋Š” ์—†์—ˆ๊ธฐ์— ์ด๋ฅผ `@Hidden` ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ๊ฐ์ถฐ์คฌ๋‹ค.
 


๊ธฐ์กด์— ์ปจํŠธ๋กค๋Ÿฌ๋“ค์„ xxxWebApi๋ผ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๋ฌธ์„œํ™” ํ•ด์ฃผ๊ณ  ์žˆ์—ˆ๋Š”๋ฐ, Admin ๊ธฐ๋Šฅ๋“ค์€ ๋Œ€์ƒ์—์„œ ์ œ์™ธ๋˜์–ด ์žˆ์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ถ”๊ฐ€์ ์œผ๋กœ AdminWebApi๋„ ์ƒ์„ฑํ•ด์ฃผ์—ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ์ž‘๊ฒŒ๋‚˜๋งˆ ๊ฐœ์„ ์„ ์ง„ํ–‰ํ–ˆ๋Š”๋ฐ, ์—ฌ๊ธฐ์„œ Swagger UI์˜ ๋‹จ์ ์„ ๋ช‡ ๊ฐ€์ง€ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

๋‹จ์ 

1. ์Šคํฌ๋กค ๋ฐฉ์‹์˜ ๋ฌธ์„œ
Swagger UI๋Š” ์Šคํฌ๋กค ๋ฐฉ์‹์˜ ๋ฌธ์„œ์ด๋‹ค. ํ•˜๋‚˜์˜ API์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑ๋˜์–ด ์žˆ๊ธฐ์— ๋‹ค๋ฅธ API๋ฅผ ์ฐพ์œผ๋ ค๋ฉด ๊ธฐ์กด์— ๋ณด๊ณ  ์žˆ๋˜ API์˜ ํ† ๊ธ€์„ ์ ‘์–ด์•ผ๋งŒ ํŽธํ•˜๊ฒŒ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๊ธฐ์— ๋น„์Šทํ•œ API๋“ค์ด ์—ฌ๋Ÿฌ ๊ฐœ ์žˆ๋‹ค๋ฉด ํ•œ๋ฒˆ์— ๊ตฌ๋ถ„ํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋Š” ๋‹จ์ ๋„ ์žˆ์—ˆ๋‹ค.

2. ์‘๋‹ต ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ์„ค๋ช…์„ ๋ณด๊ธฐ ์–ด๋ ต๋‹ค -> ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง„๋‹ค
Swagger UI์—์„œ๋Š” ์‘๋‹ต ํŒŒ๋ผ๋ฏธํ„ฐ์˜ ์„ค๋ช…์„ ๋ณด๊ธฐ ์œ„ํ•ด์„œ๋Š” ์‘๋‹ต์—์„œ Schema๋ฅผ ์„ ํƒํ•˜๊ณ , ์—ฌ๋Ÿฌ ํ† ๊ธ€์„ ์ง์ ‘ ๋ˆŒ๋Ÿฌ๋ณด๋ฉด์„œ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ํƒ€์ž…์ด๋‚˜ ์„ค๋ช…์„ ์ ์–ด๋†”๋„ ์ด๋Ÿฐ ๊ฒƒ๋“ค์ด ์กด์žฌํ•˜๋Š”์ง€ ์กฐ์ฐจ ๋ชจ๋ฅด๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์•˜๋‹ค.
 


๊ทธ๋Ÿฌ๋‹ค๋ณด๋‹ˆ ์ž์—ฐ์Šค๋ ˆ ๊ตฌ๋‘๋กœ ์ „๋‹ฌํ•˜๋Š” ์ผ์ด ์žฆ์•„์กŒ๋‹ค.

๋ณ€๊ฒฝ

์œ„์˜ ๋‘ ๋‹จ์ ์„ ํ•ด์†Œํ•˜๋ฉด์„œ ๊ฐ€๋…์„ฑ์ด ์ข‹์€ ๋ฌธ์„œํ™” ํˆด ์ค‘ ํ›„๋ณด๋กœ Scalar์™€ ReDoc, Stoplight Elements๋ฅผ ๋ฝ‘์•˜๋‹ค. ํ•˜์ง€๋งŒ ReDoc์˜ ๊ฒฝ์šฐ ๋‚ด๋ถ€์—์„œ ์„œ๋ฒ„๋กœ ์ง์ ‘ ํ…Œ์ŠคํŠธ ํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์ œ๊ณต๋˜์ง€ ์•Š์•˜๊ณ , ์ตœ์ข…์ ์œผ๋กœ๋Š” Scalar, Stoplight Elements๋ฅผ ๋‘๊ณ  ๊ฒฝ์Ÿํ–ˆ๋‹ค.

1. Scalar
https://github.com/scalar/scalar


Scalar๋Š” OpenAPI 3.0 ๋ช…์„ธ์— ๋”ฐ๋ผ ๋ Œ๋”๋ง ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ Notion๊ณผ ๋น„์Šทํ•œ ๋””์ž์ธ์„ ๊ฐ€์ง„ ๋ฌธ์„œํ™” ๋„๊ตฌ์ด๋‹ค. ๋””์ž์ธ ์ž์ฒด๋Š” ๋งˆ์Œ์— ๋“ค์—ˆ๊ณ , ๊ฐ€๋…์„ฑ๋„ ์ข‹์•˜์ง€๋งŒ ์™œ์ธ์ง€ ์œ„์˜ ์‚ฌ์ง„์ฒ˜๋Ÿผ ๊ฐœ์š” ๋ถ€๋ถ„์„ ์„ ํƒํ–ˆ์„ ๋•Œ ์ œ๋Œ€๋กœ ๋„˜์–ด๊ฐ€์ง€ ์•Š๋Š” ๋ฒ„๊ทธ๊ฐ€ ์žˆ์—ˆ๋‹ค.

2. Stoplight Elements
https://github.com/stoplightio/elements

๊ทธ๋ž˜์„œ ํŒ€์˜ ๋ฌธ์„œํ™” ํˆด์„ Stoplight Elements๋กœ ์„ ํƒํ–ˆ๋‹ค. ๋””์ž์ธ๋„ ์ˆ˜๋ คํ–ˆ๊ณ , ๊ฐ€๋…์„ฑ๋„ ์ข‹์•˜๋‹ค.


๊ทธ๋ฆฌ๊ณ  ๊ฐœ์š”๊ฐ€ ์ž˜ ์„ ํƒ๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๋„ ์—†์—ˆ๋‹ค.
 

์ ์šฉ

์ ์šฉ์€ ๊ฐ„๋‹จํ–ˆ๋‹ค. React Component๋ฅผ ์ด์šฉํ•œ ๋ฐฉ๋ฒ•์ฒ˜๋Ÿผ ๋‹ค์–‘ํ•˜๊ฒŒ ์กด์žฌํ•˜์ง€๋งŒ, ์ •์  ํŒŒ์ผ์„ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ–ˆ๋‹ค.

<!doctype html>  
<html lang="ko">  
<head>  
    <meta charset="utf-8">  
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">  
    <title>์ฝ”์Šคํ”ฝ API ๋ฌธ์„œ</title>  
    <meta name="description" content="์ฝ”์Šคํ”ฝ API ๋ฌธ์„œ">  
  
    <!-- Stoplight Elements CSS -->  
    <link rel="stylesheet" href="https://unpkg.com/@stoplight/elements@8/styles.min.css">  
</head>  
<body>  
  
    <elements-api        apiDescriptionUrl="/v3/api-docs"  
        router="hash"  
        layout="sidebar"  
    />  
  
    <!-- Stoplight Elements JS -->  
    <script src="https://unpkg.com/@stoplight/elements@8/web-components.min.js"></script>  
  
</body>  
</html>


์ด์™ธ์—๋„ application.yml์—์„œ swagger-ui ๊ด€๋ จํ•œ ์„ค์ •์„ ์ œ๊ฑฐํ•˜์˜€๋‹ค!
 

 

์•ž์œผ๋กœ์˜ ๊ณ„ํš

์•„๋ฌด๋ž˜๋„ ํ˜„์žฌ๋Š” ๋ฌธ์„œํ™”์— ๋“ค์–ด๊ฐ€๋Š” ๋‚ด์šฉ๋“ค์„ ์ง์ ‘ ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์ž‘์„ฑํ•ด์ค˜์•ผ ํ•˜๋‹ค๋ณด๋‹ˆ ํœด๋จผ ์—๋Ÿฌ๊ฐ€ ๋“ค์–ด๊ฐˆ ๊ฐ€๋Šฅ์„ฑ์ด ์กด์žฌํ•œ๋‹ค. ๊ทธ๋ ‡๊ธฐ์— ์ด๋Ÿฌํ•œ ๋ฌธ์„œ ๊ฐœ์„  ์ž‘์—…์„ ์ง„ํ–‰ํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ, ์ถ”ํ›„ API์˜ ๊ฐœ์ˆ˜๊ฐ€ ๋” ์ฆ๊ฐ€ํ•œ๋‹ค๋ฉด, Spring Rest Docs์™€ RestDocs-Api-Spec๋ฅผ ํ•จ๊ป˜ ํ™œ์šฉํ•˜์—ฌ OpenAPI 3.0 + Stoplight๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฐœ์„ ํ•ด๋ณผ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.