Skip to content

결과 코드

Q-Framework의 결과 코드는 선언 기반 계약입니다. 응답 코드가 어노테이션으로 선언되며, 컴파일 시점에 타입 안전한 상수가 자동 생성됩니다.

결과 코드 계약 설명

전통적인 방식에서는 결과 코드가 여러 곳에 분산됩니다:

java
// 문제: 문자열 하드코딩 — 중복 정의, 오타 위험
if (result.getCode().equals("PRODUCT_NOT_FOUND")) { ... }

// 문제: 상수 파일 관리 — 중앙화되지 않음
public static final String PRODUCT_NOT_FOUND = "PRODUCT_NOT_FOUND";

Q-Framework에서는 결과 코드가 SSOT로 선언됩니다:

java
// SSOT: 어노테이션으로 선언
@QfResultCode(code = "PRODUCT_NOT_FOUND", httpStatus = 404, ...)
// → 컴파일 시점에 타입 안전한 상수 자동 생성
// → API 문서에 자동 포함
// → 프론트엔드 i18n과 자동 연동

@QfResultCode 어노테이션 속성

java
@QfResultCode(
    code = "PRODUCT_NOT_FOUND",          // 결과 코드 문자열
    httpStatus = 404,                     // HTTP 상태 코드
    message = "상품을 찾을 수 없습니다.",   // 기본 메시지
    i18n = @QfI18n(                       // 다국어 메시지
        ko = "상품을 찾을 수 없습니다.",
        en = "Product not found"
    )
)
속성타입필수설명기본값
codeString결과 코드 식별자
httpStatusintHTTP 상태 코드
messageString기본 메시지""
i18n@QfI18n다국어 메시지

코드 형식 규칙

결과 코드는 다음 형식을 따릅니다:

{DOMAIN}_{ACTION}_{STATUS}
    ↓          ↓        ↓
PRODUCT  _  NOT_FOUND  (없음)

MEMBER   _  CREATE  _  FAILED

ORDER    _  PAYMENT _  TIMEOUT

규칙:

  • 대문자만 사용
  • 단어 구분은 언더스코어(_)
  • 도메인 접두사 필수

예시:

  • PRODUCT_NOT_FOUND
  • MEMBER_DUPLICATE_LOGIN_ID
  • ORDER_PAYMENT_TIMEOUT
  • VALIDATION_FAILED (시스템 공통)
  • UNAUTHORIZED (시스템 공통)

결과 코드 정의 방법

도메인별 인터페이스 선언

java
// ProductResultCode.java
@QfResultCodeGroup(domain = "PRODUCT")
public interface ProductResultCode {

    @QfResultCode(
        code = "PRODUCT_NOT_FOUND",
        httpStatus = 404,
        i18n = @QfI18n(
            ko = "상품을 찾을 수 없습니다.",
            en = "Product not found"
        )
    )
    String NOT_FOUND = "PRODUCT_NOT_FOUND";

    @QfResultCode(
        code = "PRODUCT_OUT_OF_STOCK",
        httpStatus = 409,
        i18n = @QfI18n(
            ko = "품절된 상품입니다.",
            en = "Product is out of stock"
        )
    )
    String OUT_OF_STOCK = "PRODUCT_OUT_OF_STOCK";

    @QfResultCode(
        code = "PRODUCT_CREATE_FAILED",
        httpStatus = 500,
        i18n = @QfI18n(
            ko = "상품 등록에 실패했습니다.",
            en = "Failed to create product"
        )
    )
    String CREATE_FAILED = "PRODUCT_CREATE_FAILED";
}

자동 생성 코드 예시

컴파일 시점에 타입 안전한 상수 클래스가 생성됩니다.

생성 전 (선언):

java
@QfResultCode(code = "PRODUCT_NOT_FOUND", httpStatus = 404, ...)
String NOT_FOUND = "PRODUCT_NOT_FOUND";

생성 후 (자동 생성 코드):

java
// 자동 생성 - 수동 수정 금지
public final class QfProductResultCodes {

    public static final QfResultCodeDef NOT_FOUND =
        new QfResultCodeDef("PRODUCT_NOT_FOUND", 404, "상품을 찾을 수 없습니다.");

    public static final QfResultCodeDef OUT_OF_STOCK =
        new QfResultCodeDef("PRODUCT_OUT_OF_STOCK", 409, "품절된 상품입니다.");

    private QfProductResultCodes() {}
}

사용 방법

java
@QfOn(entity = ProductEntity.class, event = QfEvent.BEFORE_READ)
public class ProductReadHook implements QfHook<ProductEntity> {

    @Override
    public void execute(QfHookContext<ProductEntity> context) {
        String id = context.getId();

        if (!productRepository.existsById(id)) {
            // 타입 안전한 결과 코드 사용
            throw new QfManagedException(QfProductResultCodes.NOT_FOUND);
        }
    }
}

표준 응답 구조

json
{
  "success": false,
  "code": "PRODUCT_NOT_FOUND",
  "message": "상품을 찾을 수 없습니다.",
  "data": null
}

성공 응답:

json
{
  "success": true,
  "code": "SUCCESS",
  "data": {
    "id": "prod-001",
    "name": "노트북",
    "price": 1500000
  }
}

시스템 기본 결과 코드

Q-Framework가 기본으로 제공하는 결과 코드입니다.

코드HTTP 상태설명
SUCCESS200정상 처리
VALIDATION_FAILED400입력값 검증 실패
UNAUTHORIZED401인증 필요
FORBIDDEN403권한 없음
NOT_FOUND404리소스 없음
CONFLICT409중복 등록 등 충돌
INTERNAL_SERVER_ERROR500서버 내부 오류
RUNTIME_NOT_INITIALIZED503런타임 초기화 실패

다음 단계

Released under the Apache 2.0 License.