From 5b766838d94aa220d19d7f2b693f924b5ccc6092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EA=B7=9C?= Date: Sat, 17 Jan 2026 16:30:15 +0900 Subject: [PATCH 1/4] =?UTF-8?q?:sparkles:=20feat:=20=EC=9D=91=EB=8B=B5=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/exception/AppException.java | 14 +++++++ .../global/exception/ErrorCode.java | 25 +++++++++++ .../exception/GlobalExceptionHandler.java | 41 +++++++++++++++++++ .../global/response/DataResponse.java | 33 +++++++++++++++ .../global/response/DefaultIdResponse.java | 9 ++++ .../global/response/ErrorResponse.java | 34 +++++++++++++++ 6 files changed, 156 insertions(+) create mode 100644 src/main/java/com/whereyouad/WhereYouAd/global/exception/AppException.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/global/exception/ErrorCode.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/global/exception/GlobalExceptionHandler.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/global/response/DataResponse.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/global/response/DefaultIdResponse.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/global/response/ErrorResponse.java diff --git a/src/main/java/com/whereyouad/WhereYouAd/global/exception/AppException.java b/src/main/java/com/whereyouad/WhereYouAd/global/exception/AppException.java new file mode 100644 index 0000000..92090b3 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/global/exception/AppException.java @@ -0,0 +1,14 @@ +package com.whereyouad.WhereYouAd.global.exception; + +import lombok.Getter; + +@Getter +public class AppException extends RuntimeException { + + private final BaseErrorCode errorCode; + + public AppException(BaseErrorCode errorCode) { + super(errorCode.getMessage()); + this.errorCode = errorCode; + } +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/global/exception/ErrorCode.java b/src/main/java/com/whereyouad/WhereYouAd/global/exception/ErrorCode.java new file mode 100644 index 0000000..8cdfdc0 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/global/exception/ErrorCode.java @@ -0,0 +1,25 @@ +package com.whereyouad.WhereYouAd.global.exception; + + +import lombok.AllArgsConstructor; +import org.springframework.http.HttpStatus; + +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum ErrorCode implements BaseErrorCode{ + + //400 + BAD_REQUEST(HttpStatus.BAD_REQUEST, "잘못된 요청입니다.", "COMMON-001"), + INVALID_PARAMETER(HttpStatus.BAD_REQUEST, "요청 파라미터가 잘못되었습니다.", "COMMON-002"), + NOT_FOUND(HttpStatus.NOT_FOUND, "찾을 수 없습니다.", "COMMON-003"), + + //500 + INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "서버 내부에서 에러가 발생하였습니다.", "COMMON-004"), + ; + + private final HttpStatus httpStatus; + private final String message; + private final String code; +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/global/exception/GlobalExceptionHandler.java b/src/main/java/com/whereyouad/WhereYouAd/global/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..006f4b0 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/global/exception/GlobalExceptionHandler.java @@ -0,0 +1,41 @@ +package com.whereyouad.WhereYouAd.global.exception; + +import com.whereyouad.WhereYouAd.global.response.ErrorResponse; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + + +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; + + +@Slf4j +@RestControllerAdvice +public class GlobalExceptionHandler { + + // 처리되지 않은 모든 예외를 잡는 핸들러 + @ExceptionHandler(Exception.class) + public ResponseEntity handleAllException(Exception e, HttpServletRequest request) { + log.error("처리되지 않은 예외 발생: ", e); + log.error("에러가 발생한 지점 {}, {}", request.getMethod(), request.getRequestURI()); + ErrorResponse errorResponse = ErrorResponse.of( + ErrorCode.INTERNAL_SERVER_ERROR, + request + ); + return ResponseEntity + .status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(errorResponse); + } + + @ExceptionHandler(AppException.class) + public ResponseEntity handleAppCustomException(AppException e, HttpServletRequest request) { + log.error("AppException 발생: {}", e.getErrorCode().getMessage()); + log.error("에러가 발생한 지점 {}, {}", request.getMethod(), request.getRequestURI()); + ErrorResponse errorResponse = ErrorResponse.of(e.getErrorCode(), request); + return ResponseEntity + .status(e.getErrorCode().getHttpStatus()) + .body(errorResponse); + } +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/global/response/DataResponse.java b/src/main/java/com/whereyouad/WhereYouAd/global/response/DataResponse.java new file mode 100644 index 0000000..6925fed --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/global/response/DataResponse.java @@ -0,0 +1,33 @@ +package com.whereyouad.WhereYouAd.global.response; + +import org.springframework.http.HttpStatus; + +import com.fasterxml.jackson.annotation.JsonInclude; + +import lombok.Getter; + +@Getter +@JsonInclude(JsonInclude.Include.NON_NULL) +public class DataResponse extends BaseResponse { + + private final T data; + + private DataResponse(HttpStatus status, T data) { + super(status); + this.data = data; + } + + public static DataResponse from(T data) { + return new DataResponse<>(HttpStatus.OK, data); + } + + public static DataResponse ok() { + return new DataResponse<>(HttpStatus.OK, null); + } + + public static DataResponse created(T data) { + return new DataResponse<>(HttpStatus.CREATED, data); + } + + // 다른 응답 필요하면 추가 +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/global/response/DefaultIdResponse.java b/src/main/java/com/whereyouad/WhereYouAd/global/response/DefaultIdResponse.java new file mode 100644 index 0000000..b6b653d --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/global/response/DefaultIdResponse.java @@ -0,0 +1,9 @@ +package com.whereyouad.WhereYouAd.global.response; + +public record DefaultIdResponse( + Long id +) { + public static DefaultIdResponse of(Long id) { + return new DefaultIdResponse(id); + } +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/global/response/ErrorResponse.java b/src/main/java/com/whereyouad/WhereYouAd/global/response/ErrorResponse.java new file mode 100644 index 0000000..a9d434b --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/global/response/ErrorResponse.java @@ -0,0 +1,34 @@ +package com.whereyouad.WhereYouAd.global.response; + +import com.whereyouad.WhereYouAd.global.exception.BaseErrorCode; +import org.springframework.http.HttpStatus; + +import jakarta.servlet.http.HttpServletRequest; +import lombok.Getter; + +@Getter +public class ErrorResponse extends BaseResponse { + + private final String code; + private final String message; + private final String method; + private final String requestURI; + + private ErrorResponse(String code, String message, String method, String requestURI, HttpStatus httpStatus) { + super(httpStatus); + this.code = code; + this.message = message; + this.method = method; + this.requestURI = requestURI; + } + + public static ErrorResponse of(BaseErrorCode errorCode, HttpServletRequest request) { + return new ErrorResponse( + errorCode.getCode(), + errorCode.getMessage(), + request.getMethod(), + request.getRequestURI(), + errorCode.getHttpStatus() + ); + } +} \ No newline at end of file From ad6eb8f2866b705db034ba5ad5ec1fc1e8761df3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EA=B7=9C?= Date: Sat, 17 Jan 2026 16:30:35 +0900 Subject: [PATCH 2/4] =?UTF-8?q?:sparkles:=20feat:=20=EC=8A=A4=EC=9B=A8?= =?UTF-8?q?=EA=B1=B0=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 6 ++- .../global/config/SwaggerConfig.java | 39 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/whereyouad/WhereYouAd/global/config/SwaggerConfig.java diff --git a/build.gradle b/build.gradle index 28c0c3d..00b59ba 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-validation' // Security - implementation 'org.springframework.boot:spring-boot-starter-security' + // implementation 'org.springframework.boot:spring-boot-starter-security' // Database & Cache implementation 'org.springframework.boot:spring-boot-starter-data-jpa' @@ -46,6 +46,10 @@ dependencies { testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + + //swagger + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.0' + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-api:2.8.0' } tasks.named('test') { diff --git a/src/main/java/com/whereyouad/WhereYouAd/global/config/SwaggerConfig.java b/src/main/java/com/whereyouad/WhereYouAd/global/config/SwaggerConfig.java new file mode 100644 index 0000000..66c2dc6 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/global/config/SwaggerConfig.java @@ -0,0 +1,39 @@ +package com.whereyouad.WhereYouAd.global.config; + +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; +import io.swagger.v3.oas.models.servers.Server; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SwaggerConfig { + + @Bean + public OpenAPI swagger() { + Info info = new Info() + .title("Where you AD API Document") + .description("Where you AD(너의 광고는) 프로젝트 API 명세서") + .version("0.0.1"); + + // JWT 토큰 헤더 방식 + String securityScheme = "JWT TOKEN"; + SecurityRequirement securityRequirement = new SecurityRequirement().addList(securityScheme); + + Components components = new Components() + .addSecuritySchemes(securityScheme, new SecurityScheme() + .name(securityScheme) + .type(SecurityScheme.Type.HTTP) + .scheme("bearer") + .bearerFormat("JWT")); + + return new OpenAPI() + .info(info) + .addServersItem(new Server().url("/")) + .addSecurityItem(securityRequirement) + .components(components); + } +} From 0eaa53e4ee5b4f09ff84dcf0326be5085747b377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EA=B7=9C?= Date: Sat, 17 Jan 2026 16:31:54 +0900 Subject: [PATCH 3/4] =?UTF-8?q?:sparkles:=20feat:=20=EC=BB=A8=ED=8A=B8?= =?UTF-8?q?=EB=A1=A4=EB=9F=AC=20=EB=B0=8F=20=EB=94=94=EB=A0=89=ED=84=B0?= =?UTF-8?q?=EB=A6=AC=20=EA=B5=AC=EC=A1=B0=20=EC=98=88=EC=8B=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/ExampleRequest.java | 6 +++ .../dto/response/ExampleResponse.java | 16 ++++++++ .../example/application/mapper/.gitkeep | 0 .../example/application/usecase/.gitkeep | 0 .../domain/example/domain/constant/.gitkeep | 0 .../domain/service/ExampleService.java | 34 +++++++++++++++++ .../example/exception/ExampleException.java | 10 +++++ .../exception/code/ExampleErrorCode.java | 18 +++++++++ .../persistence/entity/ExampleEntity.java | 27 +++++++++++++ .../example/persistence/mapper/.gitkeep | 0 .../repository/ExampleRepository.java | 7 ++++ .../presentation/ExampleController.java | 38 +++++++++++++++++++ .../docs/ExampleControllerDocs.java | 33 ++++++++++++++++ .../global/exception/BaseErrorCode.java | 9 +++++ .../global/response/BaseResponse.java | 19 ++++++++++ .../WhereYouAd/global/security/.gitkeep | 0 .../WhereYouAd/global/utils/.gitkeep | 0 src/main/resources/application.yaml | 26 +++++++++++++ 18 files changed, 243 insertions(+) create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domain/example/application/dto/request/ExampleRequest.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domain/example/application/dto/response/ExampleResponse.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domain/example/application/mapper/.gitkeep create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domain/example/application/usecase/.gitkeep create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domain/example/domain/constant/.gitkeep create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domain/example/domain/service/ExampleService.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domain/example/exception/ExampleException.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domain/example/exception/code/ExampleErrorCode.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domain/example/persistence/entity/ExampleEntity.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domain/example/persistence/mapper/.gitkeep create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domain/example/persistence/repository/ExampleRepository.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domain/example/presentation/ExampleController.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/domain/example/presentation/docs/ExampleControllerDocs.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/global/exception/BaseErrorCode.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/global/response/BaseResponse.java create mode 100644 src/main/java/com/whereyouad/WhereYouAd/global/security/.gitkeep create mode 100644 src/main/java/com/whereyouad/WhereYouAd/global/utils/.gitkeep create mode 100644 src/main/resources/application.yaml diff --git a/src/main/java/com/whereyouad/WhereYouAd/domain/example/application/dto/request/ExampleRequest.java b/src/main/java/com/whereyouad/WhereYouAd/domain/example/application/dto/request/ExampleRequest.java new file mode 100644 index 0000000..f4b2862 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domain/example/application/dto/request/ExampleRequest.java @@ -0,0 +1,6 @@ +package com.whereyouad.WhereYouAd.domain.example.application.dto.request; + +public record ExampleRequest( + String name +) { +} \ No newline at end of file diff --git a/src/main/java/com/whereyouad/WhereYouAd/domain/example/application/dto/response/ExampleResponse.java b/src/main/java/com/whereyouad/WhereYouAd/domain/example/application/dto/response/ExampleResponse.java new file mode 100644 index 0000000..7943239 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domain/example/application/dto/response/ExampleResponse.java @@ -0,0 +1,16 @@ +package com.whereyouad.WhereYouAd.domain.example.application.dto.response; + +import com.whereyouad.WhereYouAd.domain.example.persistence.entity.ExampleEntity; + +public record ExampleResponse( + Long id, + String name +) { + public static ExampleResponse from(ExampleEntity example) { + return new ExampleResponse( + example.getId(), + example.getName() + ); + } +} + diff --git a/src/main/java/com/whereyouad/WhereYouAd/domain/example/application/mapper/.gitkeep b/src/main/java/com/whereyouad/WhereYouAd/domain/example/application/mapper/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/com/whereyouad/WhereYouAd/domain/example/application/usecase/.gitkeep b/src/main/java/com/whereyouad/WhereYouAd/domain/example/application/usecase/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/com/whereyouad/WhereYouAd/domain/example/domain/constant/.gitkeep b/src/main/java/com/whereyouad/WhereYouAd/domain/example/domain/constant/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/com/whereyouad/WhereYouAd/domain/example/domain/service/ExampleService.java b/src/main/java/com/whereyouad/WhereYouAd/domain/example/domain/service/ExampleService.java new file mode 100644 index 0000000..a68cb90 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domain/example/domain/service/ExampleService.java @@ -0,0 +1,34 @@ +package com.whereyouad.WhereYouAd.domain.example.domain.service; + +import com.whereyouad.WhereYouAd.domain.example.application.dto.response.ExampleResponse; +import com.whereyouad.WhereYouAd.domain.example.exception.ExampleException; +import com.whereyouad.WhereYouAd.domain.example.exception.code.ExampleErrorCode; +import com.whereyouad.WhereYouAd.domain.example.persistence.entity.ExampleEntity; +import com.whereyouad.WhereYouAd.domain.example.persistence.repository.ExampleRepository; +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor(access = AccessLevel.PROTECTED) +public class ExampleService { + + private final ExampleRepository exampleRepository; + + @Transactional + public Long save(String name) { + ExampleEntity example = ExampleEntity.builder() + .name(name) + .build(); + return exampleRepository.save(example).getId(); + } + + public ExampleResponse findById(Long id) { + return ExampleResponse.from( + exampleRepository.findById(id) + .orElseThrow(() -> new ExampleException(ExampleErrorCode.EXAMPLE_NOT_FOUND)) + ); + } +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domain/example/exception/ExampleException.java b/src/main/java/com/whereyouad/WhereYouAd/domain/example/exception/ExampleException.java new file mode 100644 index 0000000..6992bb7 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domain/example/exception/ExampleException.java @@ -0,0 +1,10 @@ +package com.whereyouad.WhereYouAd.domain.example.exception; + +import com.whereyouad.WhereYouAd.global.exception.AppException; +import com.whereyouad.WhereYouAd.global.exception.BaseErrorCode; + +public class ExampleException extends AppException { + public ExampleException(BaseErrorCode code) { + super(code); + } +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domain/example/exception/code/ExampleErrorCode.java b/src/main/java/com/whereyouad/WhereYouAd/domain/example/exception/code/ExampleErrorCode.java new file mode 100644 index 0000000..0f03db8 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domain/example/exception/code/ExampleErrorCode.java @@ -0,0 +1,18 @@ +package com.whereyouad.WhereYouAd.domain.example.exception.code; + +import com.whereyouad.WhereYouAd.global.exception.BaseErrorCode; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum ExampleErrorCode implements BaseErrorCode { + + EXAMPLE_NOT_FOUND(HttpStatus.NOT_FOUND, "EXAMPLE-001", "엔티티를 찾을 수 없습니다.") + ; + + private final HttpStatus httpStatus; + private final String code; + private final String message; +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domain/example/persistence/entity/ExampleEntity.java b/src/main/java/com/whereyouad/WhereYouAd/domain/example/persistence/entity/ExampleEntity.java new file mode 100644 index 0000000..1a1f97f --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domain/example/persistence/entity/ExampleEntity.java @@ -0,0 +1,27 @@ +package com.whereyouad.WhereYouAd.domain.example.persistence.entity; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Table(name = "example_entity") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ExampleEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "example_id") + private Long id; + + @Column(name = "name", nullable = false) + private String name; + + @Builder + public ExampleEntity(String name) { + this.name = name; + } +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domain/example/persistence/mapper/.gitkeep b/src/main/java/com/whereyouad/WhereYouAd/domain/example/persistence/mapper/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/com/whereyouad/WhereYouAd/domain/example/persistence/repository/ExampleRepository.java b/src/main/java/com/whereyouad/WhereYouAd/domain/example/persistence/repository/ExampleRepository.java new file mode 100644 index 0000000..9533aae --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domain/example/persistence/repository/ExampleRepository.java @@ -0,0 +1,7 @@ +package com.whereyouad.WhereYouAd.domain.example.persistence.repository; + +import com.whereyouad.WhereYouAd.domain.example.persistence.entity.ExampleEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ExampleRepository extends JpaRepository { +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domain/example/presentation/ExampleController.java b/src/main/java/com/whereyouad/WhereYouAd/domain/example/presentation/ExampleController.java new file mode 100644 index 0000000..864fe9a --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domain/example/presentation/ExampleController.java @@ -0,0 +1,38 @@ +package com.whereyouad.WhereYouAd.domain.example.presentation; + +import com.whereyouad.WhereYouAd.domain.example.application.dto.request.ExampleRequest; +import com.whereyouad.WhereYouAd.domain.example.application.dto.response.ExampleResponse; +import com.whereyouad.WhereYouAd.domain.example.domain.service.ExampleService; +import com.whereyouad.WhereYouAd.domain.example.presentation.docs.ExampleControllerDocs; +import com.whereyouad.WhereYouAd.global.response.DataResponse; +import com.whereyouad.WhereYouAd.global.response.DefaultIdResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequiredArgsConstructor(access = AccessLevel.PROTECTED) +@RequestMapping("/api/examples") +public class ExampleController implements ExampleControllerDocs { + + private final ExampleService exampleService; + + @PostMapping + public ResponseEntity> save(@RequestBody ExampleRequest request) { + return ResponseEntity.ok( + DataResponse.created( + DefaultIdResponse.of(exampleService.save(request.name())) + ) + ); + } + + @GetMapping("/{id}") + public ResponseEntity> findById(@PathVariable Long id) { + return ResponseEntity.ok( + DataResponse.from(exampleService.findById(id)) + ); + } +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/domain/example/presentation/docs/ExampleControllerDocs.java b/src/main/java/com/whereyouad/WhereYouAd/domain/example/presentation/docs/ExampleControllerDocs.java new file mode 100644 index 0000000..50d9938 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/domain/example/presentation/docs/ExampleControllerDocs.java @@ -0,0 +1,33 @@ +package com.whereyouad.WhereYouAd.domain.example.presentation.docs; + +import com.whereyouad.WhereYouAd.domain.example.application.dto.request.ExampleRequest; +import com.whereyouad.WhereYouAd.domain.example.application.dto.response.ExampleResponse; +import com.whereyouad.WhereYouAd.global.response.DataResponse; +import com.whereyouad.WhereYouAd.global.response.DefaultIdResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; + +public interface ExampleControllerDocs { + @Operation( + summary = "예시 이름 저장 API", + description = "이름을 받아와서 DB에 저장합니다." + ) + @ApiResponses({ + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "성공"), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "실패") + }) + public ResponseEntity> save(@RequestBody ExampleRequest request); + + @Operation( + summary = "예시 이름 조회 API", + description = "id값에 해당하는 이름을 반환합니다." + ) + @ApiResponses({ + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "성공"), + @io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "실패") + }) + public ResponseEntity> findById(@PathVariable Long id); +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/global/exception/BaseErrorCode.java b/src/main/java/com/whereyouad/WhereYouAd/global/exception/BaseErrorCode.java new file mode 100644 index 0000000..8e6cc69 --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/global/exception/BaseErrorCode.java @@ -0,0 +1,9 @@ +package com.whereyouad.WhereYouAd.global.exception; + +import org.springframework.http.HttpStatus; + +public interface BaseErrorCode { + HttpStatus getHttpStatus(); + String getCode(); + String getMessage(); +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/global/response/BaseResponse.java b/src/main/java/com/whereyouad/WhereYouAd/global/response/BaseResponse.java new file mode 100644 index 0000000..75715fa --- /dev/null +++ b/src/main/java/com/whereyouad/WhereYouAd/global/response/BaseResponse.java @@ -0,0 +1,19 @@ +package com.whereyouad.WhereYouAd.global.response; + +import java.time.LocalDateTime; + +import org.springframework.http.HttpStatus; + +import com.fasterxml.jackson.annotation.JsonFormat; + +import lombok.Getter; + +@Getter +public abstract class BaseResponse { + + private final String status; + + protected BaseResponse(HttpStatus status) { + this.status = status.getReasonPhrase(); + } +} diff --git a/src/main/java/com/whereyouad/WhereYouAd/global/security/.gitkeep b/src/main/java/com/whereyouad/WhereYouAd/global/security/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/com/whereyouad/WhereYouAd/global/utils/.gitkeep b/src/main/java/com/whereyouad/WhereYouAd/global/utils/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml new file mode 100644 index 0000000..89e0322 --- /dev/null +++ b/src/main/resources/application.yaml @@ -0,0 +1,26 @@ +spring: + application: + name: "umc9th" + + + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver # MySQL JDBC 드라이버 클래스 이름 + url: ${DB_URL} # jdbc:mysql://localhost:3306/{데이터베이스명} + username: ${DB_USER} # MySQL 유저 이름 + password: ${DB_PW} # MySQL 비밀번호 + + jpa: + database: mysql # 사용할 데이터베이스 유형 지정 (MySQL) + database-platform: org.hibernate.dialect.MySQLDialect # Hibernate에서 사용할 MySQL 방언(dialect) 설정 + show-sql: true # 실행된 SQL 쿼리를 콘솔에 출력할지 여부 설정 + hibernate: + ddl-auto: update # 애플리케이션 실행 시 데이터베이스 스키마의 상태를 설정 + properties: + hibernate: + format_sql: true # 출력되는 SQL 쿼리를 보기 좋게 포맷팅 + +jwt: + token: + secretKey: ZGh3YWlkc2F2ZXdhZXZ3b2EgMTM5ZXUgMDMxdWMyIHEyMiBAIDAgKTJFVio= + expiration: + access: 14400000 \ No newline at end of file From 565d94ca0a765e3932aa490484511bd871a4ae9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EA=B7=9C?= Date: Sun, 18 Jan 2026 13:24:30 +0900 Subject: [PATCH 4/4] =?UTF-8?q?:sparkles:=20feat:=20=EB=94=94=EB=A0=89?= =?UTF-8?q?=ED=84=B0=EB=A6=AC=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20yaml?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/application/usecase/.gitkeep | 0 src/main/resources/application.yaml | 26 ------------------- 2 files changed, 26 deletions(-) delete mode 100644 src/main/java/com/whereyouad/WhereYouAd/domain/example/application/usecase/.gitkeep delete mode 100644 src/main/resources/application.yaml diff --git a/src/main/java/com/whereyouad/WhereYouAd/domain/example/application/usecase/.gitkeep b/src/main/java/com/whereyouad/WhereYouAd/domain/example/application/usecase/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml deleted file mode 100644 index 89e0322..0000000 --- a/src/main/resources/application.yaml +++ /dev/null @@ -1,26 +0,0 @@ -spring: - application: - name: "umc9th" - - - datasource: - driver-class-name: com.mysql.cj.jdbc.Driver # MySQL JDBC 드라이버 클래스 이름 - url: ${DB_URL} # jdbc:mysql://localhost:3306/{데이터베이스명} - username: ${DB_USER} # MySQL 유저 이름 - password: ${DB_PW} # MySQL 비밀번호 - - jpa: - database: mysql # 사용할 데이터베이스 유형 지정 (MySQL) - database-platform: org.hibernate.dialect.MySQLDialect # Hibernate에서 사용할 MySQL 방언(dialect) 설정 - show-sql: true # 실행된 SQL 쿼리를 콘솔에 출력할지 여부 설정 - hibernate: - ddl-auto: update # 애플리케이션 실행 시 데이터베이스 스키마의 상태를 설정 - properties: - hibernate: - format_sql: true # 출력되는 SQL 쿼리를 보기 좋게 포맷팅 - -jwt: - token: - secretKey: ZGh3YWlkc2F2ZXdhZXZ3b2EgMTM5ZXUgMDMxdWMyIHEyMiBAIDAgKTJFVio= - expiration: - access: 14400000 \ No newline at end of file