Skip to content

Result Codes

Q-Framework result codes are a declaration-based contract. Response codes are declared with annotations, and type-safe constants are automatically generated at compile time.

The Result Code Contract

In traditional approaches, result codes are scattered across multiple locations:

java
// Problem: hardcoded strings — duplicated definitions, typo risk
if (result.getCode().equals("PRODUCT_NOT_FOUND")) { ... }

// Problem: constant file management — not centralized
public static final String PRODUCT_NOT_FOUND = "PRODUCT_NOT_FOUND";

In Q-Framework, result codes are declared as SSOT:

java
// SSOT: declared with annotation
@QfResultCode(code = "PRODUCT_NOT_FOUND", httpStatus = 404, ...)
// → Type-safe constants auto-generated at compile time
// → Automatically included in API documentation
// → Automatically integrated with frontend i18n

@QfResultCode Annotation Attributes

java
@QfResultCode(
    code = "PRODUCT_NOT_FOUND",           // result code string
    httpStatus = 404,                      // HTTP status code
    message = "Product not found.",        // default message
    i18n = @QfI18n(                        // localized messages
        en = "Product not found",
        ko = "상품을 찾을 수 없습니다."
    )
)
AttributeTypeRequiredDescriptionDefault
codeStringResult code identifier
httpStatusintHTTP status code
messageStringDefault message""
i18n@QfI18nLocalized messages

Code Format Rules

Result codes follow this format:

{DOMAIN}_{ACTION}_{STATUS}
    ↓          ↓        ↓
PRODUCT  _  NOT_FOUND  (none)

MEMBER   _  CREATE  _  FAILED

ORDER    _  PAYMENT _  TIMEOUT

Rules:

  • Uppercase letters only
  • Words separated by underscore (_)
  • Domain prefix required

Examples:

  • PRODUCT_NOT_FOUND
  • MEMBER_DUPLICATE_LOGIN_ID
  • ORDER_PAYMENT_TIMEOUT
  • VALIDATION_FAILED (system-level)
  • UNAUTHORIZED (system-level)

Defining Result Codes

Domain-Based Interface Declaration

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

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

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

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

Auto-Generated Code Example

Type-safe constant classes are generated at compile time.

Before (declaration):

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

After (auto-generated code):

java
// Auto-generated — do not modify manually
public final class QfProductResultCodes {

    public static final QfResultCodeDef NOT_FOUND =
        new QfResultCodeDef("PRODUCT_NOT_FOUND", 404, "Product not found");

    public static final QfResultCodeDef OUT_OF_STOCK =
        new QfResultCodeDef("PRODUCT_OUT_OF_STOCK", 409, "Product is out of stock");

    private QfProductResultCodes() {}
}

Usage

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)) {
            // use type-safe result code
            throw new QfManagedException(QfProductResultCodes.NOT_FOUND);
        }
    }
}

Standard Response Structure

json
{
  "success": false,
  "code": "PRODUCT_NOT_FOUND",
  "message": "Product not found",
  "data": null
}

Success response:

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

System Default Result Codes

Result codes provided by Q-Framework out of the box.

CodeHTTP StatusDescription
SUCCESS200Successful operation
VALIDATION_FAILED400Input validation failed
UNAUTHORIZED401Authentication required
FORBIDDEN403Access denied
NOT_FOUND404Resource not found
CONFLICT409Duplicate entry or conflict
INTERNAL_SERVER_ERROR500Internal server error
RUNTIME_NOT_INITIALIZED503Runtime initialization failed

Next Steps

Released under the Apache 2.0 License.