Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci-java.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ jobs:
run: |
./gradlew unitTest
./gradlew integrationTest
./gradlew javadoc
if [ "${{ github.base_ref }}" = "main" ] || [[ "${{ github.ref }}" == refs/tags/* ]]; then
./gradlew e2eTest
./gradlew openapi3
Expand Down
9 changes: 3 additions & 6 deletions apps/user-service/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ plugins {
}

group = 'site.icebang'
version = '0.0.1-alpha-SNAPSHOT'
version = '0.0.1-beta-STABLE'
description = 'Ice bang - fast campus team4'

java {
Expand All @@ -21,7 +21,6 @@ configurations {
compileOnly {
extendsFrom annotationProcessor
}
// Spring Boot의 기본 로깅(Logback) 제외
all {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
Expand Down Expand Up @@ -50,18 +49,16 @@ dependencies {
// Retry
implementation 'org.springframework.retry:spring-retry'

// logging
implementation 'org.springframework.boot:spring-boot-starter-log4j2'
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml'
implementation 'org.apache.logging.log4j:log4j-layout-template-json'
implementation 'pl.tkowalcz.tjahzi:log4j2-appender-nodep:0.9.17'
implementation 'org.apache.httpcomponents:httpclient:4.5.14'
implementation 'org.apache.httpcomponents:httpcore:4.4.16'

// 비동기 로깅
// implementation 'com.lmax:disruptor:3.4.4'
// implementation 'org.apache.commons:commons-dbcp2'
// implementation 'org.apache.commons:commons-pool2'

// micrometer & actuator
implementation "io.micrometer:micrometer-tracing-bridge-brave"
implementation "io.micrometer:micrometer-tracing"
implementation 'io.micrometer:micrometer-registry-prometheus'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,123 @@

import lombok.Data;

/**
* 공통 APi 응답 DTO 클래스입니다.
*
* <p>REST API의 응답 형식을 표준화하기 위해 사용됩니다. 모든 응답은 성공 여부({@link #success}), 응답 데이터({@link #data}), 응답
* 메시지({@link #message}), 그리고 HTTP 상태 코드({@link #status})를 포함합니다.
*
* <p><b>사용 예시:</b>
*
* <pre>{@code
* // 성공 응답 생성
* ApiResponse<UserDto> response = ApiResponse.success(userDto);
*
* // 메시지를 포함한 성공 응답
* ApiResponse<UserDto> response = ApiResponse.success(userDto, "회원 조회 성공");
*
* // 오류 응답 생성
* ApiResponse<Void> errorResponse = ApiResponse.error("잘못된 요청입니다.", HttpStatus.BAD_REQUEST);
* }</pre>
*
* @param <T> 응답 데이터의 타입
* @author jys01012@gmail.com
* @since v0.0.1-alpha
* @see HttpStatus
* @see lombok.Data
*/
@Data
public class ApiResponse<T> {
/**
* 요청 처리 성공 여부.
*
* <p>true: 요청이 정상적으로 처리됨 false: 요청 처리 중 오류 발생
*/
private boolean success;

/**
* 실제 응답 데이터(payload).
*
* <p>요청이 성공적으로 처리되었을 경우 반환되는 데이터이며, 실패 시에는 {@code null}일 수 있습니다.
*/
private T data;

/**
* 응답 메세지.
*
* <p>성공 또는 오류 상황을 설명하는 메시지를 담습니다. 클라이언트에서 사용자에게 직접 표시할 수도 있습니다.
*/
private String message;

/**
* HTTP 상태 코드.
*
* <p>Spring의 {@link HttpStatus} 열거형을 사용합니다.
*/
private HttpStatus status; // HttpStatus로 변경

/** 기본 생성자입니다. 모든 필드가 기본값으로 초기화됩니다. */
public ApiResponse() {}

/**
* 모든 필드를 초기화하는 생성자.
*
* @param success 요청 성공 여부
* @param data 응답 데이터
* @param message 응답 메시지
* @param status HTTP 상태 코드
*/
public ApiResponse(boolean success, T data, String message, HttpStatus status) {
this.success = success;
this.data = data;
this.message = message;
this.status = status;
}

/**
* 성공 응답을 생성합니다. (기본 메시지: "OK", 상태: 200 OK)
*
* @param data 응답 데이터
* @param <T> 데이터 타입
* @return 성공 응답 객체
*/
public static <T> ApiResponse<T> success(T data) {
return new ApiResponse<>(true, data, "OK", HttpStatus.OK);
}

/**
* 성공 응답을 생성합니다. (상태: 200 OK)
*
* @param data 응답 데이터
* @param message 사용자 정의 메시지
* @param <T> 데이터 타입
* @return 성공 응답 객체
*/
public static <T> ApiResponse<T> success(T data, String message) {
return new ApiResponse<>(true, data, message, HttpStatus.OK);
}

/**
* 성공 응답을 생성합니다.
*
* @param data 응답 데이터
* @param message 사용자 정의 메시지
* @param status 사용자 정의 상태 코드
* @param <T> 데이터 타입
* @return 성공 응답 객체
*/
public static <T> ApiResponse<T> success(T data, String message, HttpStatus status) {
return new ApiResponse<>(true, data, message, status);
}

/**
* 오류 응답을 생성합니다.
*
* @param message 오류 메시지
* @param status HTTP 상태 코드
* @param <T> 데이터 타입
* @return 오류 응답 객체
*/
public static <T> ApiResponse<T> error(String message, HttpStatus status) {
return new ApiResponse<>(false, null, message, status);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,90 @@

import lombok.Data;

/**
* 페이징, 검색, 정렬, 필터링을 위한 공통 매개변수 클래스입니다.
*
* <p>목록 조회 API에서 공통적으로 사용되는 요청 파라미터를 정의합니다. 현재 페이지 번호({@link #current}), 페이지 크기({@link #pageSize}),
* 검색어({@link #search}), 정렬 조건({@link #sorters}), 필터 조건({@link #filters})를 포함합니다.
*
* <p><b>사용 예시:</b>
*
* <pre>{@code
* PageParams params = new PageParams();
* params.setCurrent(2);
* params.setPageSize(20);
* params.setSearch("회원");
*
* int offset = params.getOffset(); // 20
* boolean searchable = params.hasSearch(); // true
* }</pre>
*
* @author jys01012@gmail.com
* @since v0.0.1-alpha
* @see lombok.Data
*/
@Data
public class PageParams {
/**
* 현재 페이지 번호 (1부터 시작).
*
* <p>1부터 시작하며, 기본값은 1입니다. 0 이하의 값은 유효하지 않습니다.
*/
private int current = 1;

/**
* 한 펭지에 표시할 데이터 개수.
*
* <p>한 페이지에 표시할 항목의 개수를 지정합니다. 기본값은 10개이며, 일반적으로 10, 20, 50, 100 등의 값을 사용합니다.
*/
private int pageSize = 10;

/**
* 검색어.
*
* <p>목록에서 특정 조건으로 검색할 때 사용되는 키워드입니다. {@code null}이거나 빈 문자열인 경우 검색 조건이 적용되지 않습니다.
*/
private String search;

/**
* 정렬 조건 배열.
*
* <p>예: {@code ["name:asc", "createdAt:desc"]} API 설계에 따라 "필드명:정렬방향" 형식을 권장합니다. {@code null}이거나 빈
* 배열인 경우 기본 정렬이 적용됩니다.
*/
private String[] sorters;

/**
* 필터링 조건 배열.
*
* <p>예: {@code ["status:active", "role:admin"]} 각 요소는 특정 필드에 대한 필터링 조건을 나타냅니다. 형태는 구현에 따라 다를 수
* 있습니다.
*/
private String[] filters;

// 계산된 offset
/**
* 페이징 처리를 위한 offset(시작 위치)을 계산합니다.
*
* @return (current - 1) * pageSize
*/
public int getOffset() {
return (current - 1) * pageSize;
}

/**
* 검색어가 유효하게 존재하는지 확인합니다.
*
* @return 검색어가 null이 아니고 공백이 아닌 경우 true
*/
public boolean hasSearch() {
return search != null && !search.trim().isEmpty();
}

/**
* 정렬 조건이 존재하는지 확인합니다.
*
* @return 정렬 조건 배열이 null이 아니고, 1개 이상 있는 경우 true
*/
public boolean hasSorters() {
return sorters != null && sorters.length > 0;
}
Expand Down
Loading
Loading