Skip to content

Commit da29834

Browse files
committed
Docs: Swagger 문서 개선
1 parent 1d64850 commit da29834

File tree

2 files changed

+309
-25
lines changed

2 files changed

+309
-25
lines changed

src/main/java/com/back/domain/user/controller/AuthController.java

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,11 @@
2222
@RestController
2323
@RequestMapping("/api/auth")
2424
@RequiredArgsConstructor
25-
public class AuthController {
25+
public class AuthController implements AuthControllerDocs {
2626
private final UserService userService;
2727

28+
// 회원가입
2829
@PostMapping("/register")
29-
@Operation(
30-
summary = "회원가입",
31-
description = "신규 사용자를 등록합니다."
32-
)
33-
@ApiResponses({
34-
@ApiResponse(responseCode = "201", description = "회원가입 성공"),
35-
@ApiResponse(responseCode = "400", description = "잘못된 요청 / 비밀번호 정책 위반"),
36-
@ApiResponse(responseCode = "409", description = "중복된 아이디/이메일/닉네임"),
37-
@ApiResponse(responseCode = "500", description = "서버 내부 오류")
38-
})
3930
public ResponseEntity<RsData<UserResponse>> register(
4031
@Valid @RequestBody UserRegisterRequest request
4132
) {
@@ -48,14 +39,8 @@ public ResponseEntity<RsData<UserResponse>> register(
4839
));
4940
}
5041

42+
// 로그인
5143
@PostMapping("/login")
52-
@Operation(summary = "로그인", description = "username + password로 로그인합니다.")
53-
@ApiResponses({
54-
@ApiResponse(responseCode = "200", description = "로그인 성공"),
55-
@ApiResponse(responseCode = "401", description = "잘못된 아이디/비밀번호"),
56-
@ApiResponse(responseCode = "403", description = "이메일 미인증/정지 계정"),
57-
@ApiResponse(responseCode = "410", description = "탈퇴한 계정")
58-
})
5944
public ResponseEntity<RsData<UserResponse>> login(
6045
@Valid @RequestBody LoginRequest request,
6146
HttpServletResponse response
@@ -68,14 +53,8 @@ public ResponseEntity<RsData<UserResponse>> login(
6853
));
6954
}
7055

56+
// 로그아웃
7157
@PostMapping("/logout")
72-
@Operation(summary = "로그아웃", description = "Refresh Token을 무효화합니다.")
73-
@ApiResponses({
74-
@ApiResponse(responseCode = "200", description = "로그아웃 성공"),
75-
@ApiResponse(responseCode = "400", description = "잘못된 요청"),
76-
@ApiResponse(responseCode = "401", description = "이미 만료되었거나 유효하지 않은 토큰"),
77-
@ApiResponse(responseCode = "500", description = "서버 내부 오류")
78-
})
7958
public ResponseEntity<RsData<Void>> logout(
8059
HttpServletRequest request,
8160
HttpServletResponse response
Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
package com.back.domain.user.controller;
2+
3+
import com.back.domain.user.dto.LoginRequest;
4+
import com.back.domain.user.dto.UserRegisterRequest;
5+
import com.back.domain.user.dto.UserResponse;
6+
import com.back.global.common.dto.RsData;
7+
import io.swagger.v3.oas.annotations.Operation;
8+
import io.swagger.v3.oas.annotations.media.Content;
9+
import io.swagger.v3.oas.annotations.media.ExampleObject;
10+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
11+
import io.swagger.v3.oas.annotations.responses.ApiResponses;
12+
import io.swagger.v3.oas.annotations.tags.Tag;
13+
import jakarta.servlet.http.HttpServletRequest;
14+
import jakarta.servlet.http.HttpServletResponse;
15+
import jakarta.validation.Valid;
16+
import org.springframework.http.ResponseEntity;
17+
import org.springframework.web.bind.annotation.RequestBody;
18+
19+
@Tag(name = "Auth API", description = "인증/인가 관련 API")
20+
public interface AuthControllerDocs {
21+
22+
@Operation(
23+
summary = "회원가입",
24+
description = "신규 사용자를 등록합니다. " +
25+
"회원가입 시 기본 상태는 `PENDING`이며, 추후 이메일 인증 완료 시 `ACTIVE`로 변경됩니다."
26+
)
27+
@ApiResponses({
28+
@ApiResponse(
29+
responseCode = "201",
30+
description = "회원가입 성공",
31+
content = @Content(
32+
mediaType = "application/json",
33+
examples = @ExampleObject(value = """
34+
{
35+
"success": true,
36+
"code": "SUCCESS_200",
37+
"message": "회원가입이 성공적으로 완료되었습니다. 이메일 인증을 완료해주세요.",
38+
"data": {
39+
"userId": 1,
40+
"username": "testuser",
41+
"email": "[email protected]",
42+
"nickname": "홍길동",
43+
"role": "USER",
44+
"status": "PENDING",
45+
"createdAt": "2025-09-19T15:00:00"
46+
}
47+
}
48+
""")
49+
)
50+
),
51+
@ApiResponse(
52+
responseCode = "409",
53+
description = "중복된 아이디/이메일/닉네임",
54+
content = @Content(
55+
mediaType = "application/json",
56+
examples = {
57+
@ExampleObject(name = "중복 아이디", value = """
58+
{
59+
"success": false,
60+
"code": "USER_002",
61+
"message": "이미 사용 중인 아이디입니다.",
62+
"data": null
63+
}
64+
"""),
65+
@ExampleObject(name = "중복 이메일", value = """
66+
{
67+
"success": false,
68+
"code": "USER_003",
69+
"message": "이미 사용 중인 이메일입니다.",
70+
"data": null
71+
}
72+
"""),
73+
@ExampleObject(name = "중복 닉네임", value = """
74+
{
75+
"success": false,
76+
"code": "USER_004",
77+
"message": "이미 사용 중인 닉네임입니다.",
78+
"data": null
79+
}
80+
""")
81+
}
82+
)
83+
),
84+
@ApiResponse(
85+
responseCode = "400",
86+
description = "잘못된 요청 / 비밀번호 정책 위반",
87+
content = @Content(
88+
mediaType = "application/json",
89+
examples = {
90+
@ExampleObject(name = "비밀번호 정책 위반", value = """
91+
{
92+
"success": false,
93+
"code": "USER_005",
94+
"message": "비밀번호는 최소 8자 이상, 숫자/특수문자를 포함해야 합니다.",
95+
"data": null
96+
}
97+
"""),
98+
@ExampleObject(name = "잘못된 요청", value = """
99+
{
100+
"success": false,
101+
"code": "COMMON_400",
102+
"message": "잘못된 요청입니다.",
103+
"data": null
104+
}
105+
""")
106+
}
107+
)
108+
),
109+
@ApiResponse(
110+
responseCode = "500",
111+
description = "서버 내부 오류",
112+
content = @Content(
113+
mediaType = "application/json",
114+
examples = @ExampleObject(value = """
115+
{
116+
"success": false,
117+
"code": "COMMON_500",
118+
"message": "서버 오류가 발생했습니다.",
119+
"data": null
120+
}
121+
""")
122+
)
123+
)
124+
})
125+
ResponseEntity<RsData<UserResponse>> register(
126+
@Valid @RequestBody UserRegisterRequest request
127+
);
128+
129+
@Operation(
130+
summary = "로그인",
131+
description = "username + password로 로그인합니다. " +
132+
"로그인 성공 시 Access Token은 `Authorization` 헤더에, Refresh Token은 HttpOnly 쿠키로 발급됩니다."
133+
)
134+
@ApiResponses({
135+
@ApiResponse(
136+
responseCode = "200",
137+
description = "로그인 성공",
138+
content = @Content(
139+
mediaType = "application/json",
140+
examples = @ExampleObject(value = """
141+
{
142+
"success": true,
143+
"code": "SUCCESS_200",
144+
"message": "로그인에 성공했습니다.",
145+
"data": {
146+
"userId": 1,
147+
"username": "testuser",
148+
"email": "[email protected]",
149+
"nickname": "홍길동",
150+
"role": "USER",
151+
"status": "ACTIVE",
152+
"createdAt": "2025-09-19T15:00:00"
153+
}
154+
}
155+
""")
156+
)
157+
),
158+
@ApiResponse(
159+
responseCode = "401",
160+
description = "잘못된 아이디/비밀번호",
161+
content = @Content(
162+
mediaType = "application/json",
163+
examples = @ExampleObject(value = """
164+
{
165+
"success": false,
166+
"code": "USER_006",
167+
"message": "아이디 또는 비밀번호가 올바르지 않습니다.",
168+
"data": null
169+
}
170+
""")
171+
)
172+
),
173+
@ApiResponse(
174+
responseCode = "403",
175+
description = "이메일 미인증 / 정지 계정",
176+
content = @Content(
177+
mediaType = "application/json",
178+
examples = {
179+
@ExampleObject(name = "이메일 미인증", value = """
180+
{
181+
"success": false,
182+
"code": "USER_007",
183+
"message": "이메일 인증 후 로그인할 수 있습니다.",
184+
"data": null
185+
}
186+
"""),
187+
@ExampleObject(name = "정지 계정", value = """
188+
{
189+
"success": false,
190+
"code": "USER_008",
191+
"message": "정지된 계정입니다. 관리자에게 문의하세요.",
192+
"data": null
193+
}
194+
""")
195+
}
196+
)
197+
),
198+
@ApiResponse(
199+
responseCode = "410",
200+
description = "탈퇴한 계정",
201+
content = @Content(
202+
mediaType = "application/json",
203+
examples = @ExampleObject(value = """
204+
{
205+
"success": false,
206+
"code": "USER_009",
207+
"message": "탈퇴한 계정입니다.",
208+
"data": null
209+
}
210+
""")
211+
)
212+
),
213+
@ApiResponse(
214+
responseCode = "500",
215+
description = "서버 내부 오류",
216+
content = @Content(
217+
mediaType = "application/json",
218+
examples = @ExampleObject(value = """
219+
{
220+
"success": false,
221+
"code": "COMMON_500",
222+
"message": "서버 오류가 발생했습니다.",
223+
"data": null
224+
}
225+
""")
226+
)
227+
)
228+
})
229+
ResponseEntity<RsData<UserResponse>> login(
230+
@Valid @RequestBody LoginRequest request,
231+
HttpServletResponse response
232+
);
233+
234+
@Operation(
235+
summary = "로그아웃",
236+
description = "사용자의 Refresh Token을 무효화하여 더 이상 토큰 재발급이 불가능하게 합니다. " +
237+
"Access Token은 클라이언트(프론트엔드) 메모리에서 삭제해야 합니다."
238+
)
239+
@ApiResponses({
240+
@ApiResponse(
241+
responseCode = "200",
242+
description = "로그아웃 성공",
243+
content = @Content(
244+
mediaType = "application/json",
245+
examples = @ExampleObject(value = """
246+
{
247+
"success": true,
248+
"code": "SUCCESS_200",
249+
"message": "로그아웃 되었습니다.",
250+
"data": null
251+
}
252+
""")
253+
)
254+
),
255+
@ApiResponse(
256+
responseCode = "401",
257+
description = "이미 만료되었거나 유효하지 않은 Refresh Token",
258+
content = @Content(
259+
mediaType = "application/json",
260+
examples = @ExampleObject(value = """
261+
{
262+
"success": false,
263+
"code": "AUTH_401",
264+
"message": "이미 만료되었거나 유효하지 않은 토큰입니다.",
265+
"data": null
266+
}
267+
""")
268+
)
269+
),
270+
@ApiResponse(
271+
responseCode = "400",
272+
description = "잘못된 요청 (토큰 없음 / 형식 오류)",
273+
content = @Content(
274+
mediaType = "application/json",
275+
examples = @ExampleObject(value = """
276+
{
277+
"success": false,
278+
"code": "COMMON_400",
279+
"message": "잘못된 요청입니다.",
280+
"data": null
281+
}
282+
""")
283+
)
284+
),
285+
@ApiResponse(
286+
responseCode = "500",
287+
description = "서버 내부 오류",
288+
content = @Content(
289+
mediaType = "application/json",
290+
examples = @ExampleObject(value = """
291+
{
292+
"success": false,
293+
"code": "COMMON_500",
294+
"message": "서버 오류가 발생했습니다.",
295+
"data": null
296+
}
297+
""")
298+
)
299+
)
300+
})
301+
ResponseEntity<RsData<Void>> logout(
302+
HttpServletRequest request,
303+
HttpServletResponse response
304+
);
305+
}

0 commit comments

Comments
 (0)