Skip to content

Commit 367c2c6

Browse files
authored
merge: docs/swagger to develop (#14)
2 parents dfca98a + b5c9c02 commit 367c2c6

File tree

7 files changed

+105
-5
lines changed

7 files changed

+105
-5
lines changed

noweekend-core/core-api/build.gradle.kts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ dependencies {
1414
implementation("org.springframework.boot:spring-boot-starter-security")
1515

1616
testImplementation(project(":noweekend-tests:api-docs"))
17+
18+
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.7.0") {
19+
exclude(group = "io.swagger.core.v3", module = "swagger-annotations")
20+
}
1721
}
1822

1923
tasks.named<BootJar>("bootJar") {

noweekend-core/core-api/src/main/kotlin/noweekend/core/api/config/SecurityConfig.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ class SecurityConfig {
2626
fun permitDenyPathsOnDevelopment() = mapOf(
2727
"permit" to arrayOf(
2828
"/health",
29-
"/api-docs/**",
3029
"/swagger-ui/**",
30+
"/v3/api-docs/**",
3131
),
3232
"deny" to arrayOf(),
3333
)
@@ -37,10 +37,11 @@ class SecurityConfig {
3737
fun permitDenyPathsOnProduction() = mapOf(
3838
"permit" to arrayOf(
3939
"/health",
40+
"/swagger-ui/**",
41+
"/v3/api-docs/**",
4042
),
4143
"deny" to arrayOf(
42-
"/api-docs/**",
43-
"/swagger-ui/**",
44+
"/example",
4445
),
4546
)
4647

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package noweekend.core.api.config
2+
3+
import io.swagger.v3.oas.models.Components
4+
import io.swagger.v3.oas.models.OpenAPI
5+
import io.swagger.v3.oas.models.info.Info
6+
import io.swagger.v3.oas.models.security.SecurityRequirement
7+
import io.swagger.v3.oas.models.security.SecurityScheme
8+
import io.swagger.v3.oas.models.servers.Server
9+
import org.springframework.context.annotation.Bean
10+
import org.springframework.context.annotation.Configuration
11+
12+
@Configuration
13+
class SwaggerConfig {
14+
@Bean
15+
fun noWeekendApi(): OpenAPI {
16+
val info =
17+
Info()
18+
.title("noweekend Server API")
19+
.description("noweekend Server API 명세서")
20+
.version("v1.0.0")
21+
22+
val jwtSchemeName = "JWT TOKEN"
23+
24+
val securityRequirement = SecurityRequirement().addList(jwtSchemeName)
25+
26+
val components =
27+
Components()
28+
.addSecuritySchemes(
29+
jwtSchemeName,
30+
SecurityScheme()
31+
.name(jwtSchemeName)
32+
.type(SecurityScheme.Type.HTTP)
33+
.scheme("bearer")
34+
.bearerFormat("JWT"),
35+
)
36+
37+
return OpenAPI()
38+
.addServersItem(Server().url("https://noweekend.store"))
39+
.info(info)
40+
.addSecurityItem(securityRequirement)
41+
.components(components)
42+
}
43+
}
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
package noweekend.core.api.controller
22

3+
import io.swagger.v3.oas.annotations.Hidden
34
import org.springframework.http.HttpStatus
45
import org.springframework.http.ResponseEntity
56
import org.springframework.web.bind.annotation.GetMapping
67
import org.springframework.web.bind.annotation.RestController
78

9+
@Hidden
810
@RestController
911
class HealthController {
1012
@GetMapping("/health")
1113
fun health(): ResponseEntity<*> {
12-
return ResponseEntity.status(HttpStatus.OK).build<Any>()
14+
return ResponseEntity.status(HttpStatus.OK)
15+
.body("ok")
1316
}
1417
}

noweekend-core/core-api/src/main/kotlin/noweekend/core/api/controller/v1/AuthController.kt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package noweekend.core.api.controller.v1
22

3+
import io.swagger.v3.oas.annotations.Operation
4+
import io.swagger.v3.oas.annotations.media.Content
5+
import io.swagger.v3.oas.annotations.media.Schema
6+
import io.swagger.v3.oas.annotations.tags.Tag
37
import noweekend.client.google.GoogleClient
48
import noweekend.client.google.GoogleUserInfoRequest
59
import noweekend.core.api.controller.v1.request.LoginRequest
@@ -11,13 +15,46 @@ import org.springframework.web.bind.annotation.PostMapping
1115
import org.springframework.web.bind.annotation.RequestBody
1216
import org.springframework.web.bind.annotation.RequestMapping
1317
import org.springframework.web.bind.annotation.RestController
18+
import io.swagger.v3.oas.annotations.parameters.RequestBody as SwaggerRequestBody
19+
import io.swagger.v3.oas.annotations.responses.ApiResponse as SwaggerApiResponse
1420

21+
@Tag(name = "인증", description = "소셜 로그인 및 인증 API")
1522
@RestController
1623
@RequestMapping("/api/v1/login")
1724
class AuthController(
1825
private val authService: AuthService,
1926
private val googleClient: GoogleClient,
2027
) {
28+
29+
@Operation(
30+
summary = "구글 로그인",
31+
description = "구글 AccessToken을 이용한 회원 인증/가입 처리. 회원가입시 google accessToken과 name을 함께 보내주셔야하고, 로그인시에는 google accessToken만 보내주시면됩니다.",
32+
requestBody = SwaggerRequestBody(
33+
required = true,
34+
content = [
35+
Content(
36+
mediaType = "application/json",
37+
schema = Schema(implementation = LoginRequest::class),
38+
),
39+
],
40+
),
41+
responses = [
42+
SwaggerApiResponse(
43+
responseCode = "200",
44+
description = "로그인 성공",
45+
content = [
46+
Content(
47+
mediaType = "application/json",
48+
schema = Schema(implementation = GoogleLoginResponse::class),
49+
),
50+
],
51+
),
52+
SwaggerApiResponse(
53+
responseCode = "400",
54+
description = "잘못된 요청",
55+
),
56+
],
57+
)
2158
@PostMapping("/google")
2259
fun loginWithGoogle(
2360
@Validated @RequestBody req: LoginRequest,
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
package noweekend.core.api.controller.v1.request
22

3+
import io.swagger.v3.oas.annotations.media.Schema
34
import jakarta.validation.constraints.NotBlank
45

6+
@Schema(description = "구글 로그인 요청 DTO")
57
data class LoginRequest(
6-
@field:NotBlank(message = "accessToken은 필수입니다.") val accessToken: String,
8+
@field:NotBlank(message = "accessToken은 필수입니다.")
9+
@field:Schema(description = "구글 OAuth AccessToken", example = "ya29.a0Af...")
10+
val accessToken: String,
11+
12+
@field:Schema(description = "사용자 이름. 회원가입시 필수, 로그인시 null로 보내시면됩니다.", example = "홍길동")
713
val name: String?,
814
)
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
package noweekend.core.api.controller.v1.response
22

3+
import io.swagger.v3.oas.annotations.media.Schema
4+
5+
@Schema(description = "구글 로그인 응답 DTO")
36
data class GoogleLoginResponse(
7+
@field:Schema(description = "구글 이메일", example = "[email protected]")
48
val email: String,
9+
@field:Schema(description = "이미 가입된 회원 여부")
510
val exists: Boolean,
11+
@field:Schema(description = "발급된 액세스 토큰", example = "eyJhbGciOiJIUzI1NiIsInR5cCI6...")
612
val accessToken: String,
713
)

0 commit comments

Comments
 (0)