Skip to content

Commit

Permalink
πŸš€ :: Api-v0.0.4
Browse files Browse the repository at this point in the history
πŸš€ :: Api-v0.0.4
  • Loading branch information
ImNM authored Jan 15, 2023
2 parents 4c104d5 + 69b037c commit e824f42
Show file tree
Hide file tree
Showing 97 changed files with 1,260 additions and 323 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
import band.gosrock.api.auth.service.RegisterUseCase;
import band.gosrock.api.auth.service.WithDrawUseCase;
import band.gosrock.api.auth.service.helper.CookieGenerateHelper;
import band.gosrock.common.annotation.ApiErrorCodeExample;
import band.gosrock.common.annotation.DevelopOnlyApi;
import band.gosrock.infrastructure.outer.api.oauth.exception.KakaoKauthErrorCode;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand Down Expand Up @@ -81,9 +83,10 @@ public OauthLoginLinkResponse getKakaoOauthLink(
return registerUseCase.getKaKaoOauthLink(referer);
}

@Operation(summary = "code μš”μ²­λ°›λŠ” ν•Έλ“€λŸ¬ ν΄λΌμ΄μ–ΈνŠΈκ°€ λͺ°λΌλ„λ©λ‹ˆλ‹€.")
@Operation(summary = "카카였 code μš”μ²­λ°›λŠ” κ³³μž…λ‹ˆλ‹€. referer,hostλŠ” 건듀이지 λ§μ•„μ£Όμ„Έμš”!μ•ˆλ³΄λ‚΄μ…”λ„λ©λ‹ˆλ‹€.")
@Tag(name = "카카였 oauth")
@GetMapping("/oauth/kakao")
@ApiErrorCodeExample(KakaoKauthErrorCode.class)
public OauthTokenResponse getCredentialFromKaKao(
@RequestParam("code") String code,
@RequestHeader(value = "referer", required = false) String referer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import band.gosrock.domain.common.vo.Money;
import band.gosrock.domain.common.vo.OptionAnswerVo;
import band.gosrock.domain.domains.cart.domain.CartLineItem;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -13,19 +14,29 @@
public class CartItemResponse {

// μΌλ°˜ν‹°μΌ“(1/3) - 4000원
@Schema(description = "카트라인의 μ΄λ¦„μž…λ‹ˆλ‹€.", defaultValue = "μΌλ°˜ν‹°μΌ“(1/3) - 4000원")
private String name;
// 응닡 λͺ©λ‘
private List<OptionAnswerVo> answers;

@Schema(description = "μ•„μ΄ν…œ κ³΅κΈ‰κ°€μ•‘μž…λ‹ˆλ‹€.", defaultValue = "3000원")
private Money itemPrice;

@Schema(
description = "카트 라인의 총 κ°€κ²©μž…λ‹ˆλ‹€. μ˜΅μ…˜λ“±μ„ ν†΅ν•΄μ„œ 곡급가앑에 ν•©μ‚°λ˜λŠ” ν˜•μ‹μž…λ‹ˆλ‹€. (μ•„μ΄ν…œκ°€κ²© + μ˜΅μ…˜κ°€) * μ•„μ΄ν…œ 개수",
defaultValue = "4000원")
private Money cartLinePrice;

@Schema(description = "담은 μƒν’ˆμ˜ κ°œμˆ˜μž…λ‹ˆλ‹€.", defaultValue = "1")
private Long packedQuantity;

public static CartItemResponse of(String name, CartLineItem cartLineItem) {
return CartItemResponse.builder()
.answers(cartLineItem.getOptionAnswerVos())
.name(name)
.cartLinePrice(cartLineItem.getTotalCartLinePrice())
.itemPrice(cartLineItem.getItemPrice())
.packedQuantity(cartLineItem.getQuantity())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,39 @@

import band.gosrock.domain.common.vo.Money;
import band.gosrock.domain.domains.cart.domain.Cart;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class CreateCartResponse {

@Schema(description = "μž₯λ°”κ΅¬λ‹ˆλͺ… μž…λ‹ˆλ‹€.", defaultValue = "")
private final String title;
// λ‚΄ν‹°μΌ“ ν™•μΈν•˜κΈ°
private final List<CartItemResponse> items;

// κΈˆμ•‘
@Schema(description = "μΉ΄νŠΈλΌμΈλ“€μ˜ 총 κ²°μ œκΈˆμ•‘μ„ ν•©ν•œ κΈˆμ•‘μž…λ‹ˆλ‹€", defaultValue = "15000원")
private final Money totalPrice;

@Schema(description = "μƒμ„±ν•œ μž₯λ°”κ΅¬λ‹ˆμ˜ μ•„μ΄λ””μž…λ‹ˆλ‹€", defaultValue = "30")
private final Long cartId;

@Schema(description = "전체 μ•„μ΄ν…œ μˆ˜λŸ‰μ„ μ˜λ―Έν•©λ‹ˆλ‹€", defaultValue = "3")
private final Long totalQuantity;

@Schema(description = "κ²°μ œκ°€ ν•„μš”ν•œμ§€μ— λŒ€ν•œ μ—¬λΆ€λ₯Ό κ²°μ •ν•©λ‹ˆλ‹€. ν•„μš”ν•œ trueλ©΄ 결제창 λ„μš°μ‹œλ©΄λ©λ‹ˆλ‹€.", defaultValue = "true")
private final Boolean isNeedPayment;

public static CreateCartResponse of(List<CartItemResponse> cartItemResponses, Cart cart) {
return CreateCartResponse.builder()
.items(cartItemResponses)
.totalPrice(cart.getTotalPrice())
.cartId(cart.getId())
.title(cart.getCartName())
.isNeedPayment(cart.isNeedPayment())
.totalQuantity(cart.getTotalQuantity())
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@


import io.swagger.v3.oas.models.examples.Example;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@Getter
@AllArgsConstructor
@Builder
public class ExampleHolder {
private Example holder;
private String name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

import static java.util.stream.Collectors.groupingBy;

import band.gosrock.common.annotation.ApiErrorExample;
import band.gosrock.common.annotation.ApiErrorCodeExample;
import band.gosrock.common.annotation.ApiErrorExceptionsExample;
import band.gosrock.common.annotation.DisableSwaggerSecurity;
import band.gosrock.common.annotation.ExplainError;
import band.gosrock.common.dto.ErrorReason;
import band.gosrock.common.dto.ErrorResponse;
import band.gosrock.common.exception.BaseErrorCode;
import band.gosrock.common.exception.DuDoongCodeException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.core.jackson.ModelResolver;
Expand Down Expand Up @@ -86,8 +88,11 @@ public OperationCustomizer customize() {
return (Operation operation, HandlerMethod handlerMethod) -> {
DisableSwaggerSecurity methodAnnotation =
handlerMethod.getMethodAnnotation(DisableSwaggerSecurity.class);
ApiErrorExample apiErrorExample =
handlerMethod.getMethodAnnotation(ApiErrorExample.class);
ApiErrorExceptionsExample apiErrorExceptionsExample =
handlerMethod.getMethodAnnotation(ApiErrorExceptionsExample.class);
ApiErrorCodeExample apiErrorCodeExample =
handlerMethod.getMethodAnnotation(ApiErrorCodeExample.class);

List<String> tags = getTags(handlerMethod);
// DisableSecurity μ–΄λ…Έν…Œμ΄μ…˜μžˆμ„μ‹œ μŠ€μ›¨κ±° μ‹œνλ¦¬ν‹° μ„€μ • μ‚­μ œ
if (methodAnnotation != null) {
Expand All @@ -97,22 +102,62 @@ public OperationCustomizer customize() {
if (!tags.isEmpty()) {
operation.setTags(Collections.singletonList(tags.get(0)));
}
// ApiErrorExample μ–΄λ…Έν…Œμ΄μ…˜ 단 ν΄λž˜μŠ€μ— 적용
if (apiErrorExample != null) {
generateErrorResponseExample(operation, apiErrorExample.value());
// ApiErrorExceptionsExample μ–΄λ…Έν…Œμ΄μ…˜ 단 λ©”μ†Œλ“œ 적용
if (apiErrorExceptionsExample != null) {
generateExceptionResponseExample(operation, apiErrorExceptionsExample.value());
}
// ApiErrorCodeExample μ–΄λ…Έν…Œμ΄μ…˜ 단 λ©”μ†Œλ“œ 적용
if (apiErrorCodeExample != null) {
generateErrorCodeResponseExample(operation, apiErrorCodeExample.value());
}
return operation;
};
}
/**
* BaseErrorCode νƒ€μž…μ˜ μ΄λ„˜κ°’λ“€μ„ λ¬Έμ„œν™” μ‹œν‚΅λ‹ˆλ‹€. ExplainError μ–΄λ…Έν…Œμ΄μ…˜μœΌλ‘œ λΆ€κ°€μ„€λͺ…을 λΆ™μΌμˆ˜μžˆμŠ΅λ‹ˆλ‹€. ν•„λ“œλ“€μ„ κ°€μ Έμ™€μ„œ μ˜ˆμ‹œ μ—λŸ¬ 객체λ₯Ό
* λ™μ μœΌλ‘œ μƒμ„±ν•΄μ„œ μ˜ˆμ‹œκ°’μœΌλ‘œ λΆ™μž…λ‹ˆλ‹€.
*/
private void generateErrorCodeResponseExample(
Operation operation, Class<? extends BaseErrorCode> type) {
ApiResponses responses = operation.getResponses();

/** ExplainError μ–΄λ…Έν…Œμ΄μ…˜μœΌλ‘œ λΆ€κ°€μ„€λͺ…을 λΆ™μΌμˆ˜μžˆμŠ΅λ‹ˆλ‹€. ν•„λ“œλ“€μ„ κ°€μ Έμ™€μ„œ μ˜ˆμ‹œ μ—λŸ¬ 객체λ₯Ό λ™μ μœΌλ‘œ μƒμ„±ν•΄μ„œ μ˜ˆμ‹œκ°’μœΌλ‘œ λΆ™μž…λ‹ˆλ‹€. */
private void generateErrorResponseExample(Operation operation, Class<?> type) {
BaseErrorCode[] errorCodes = type.getEnumConstants();

Map<Integer, List<ExampleHolder>> statusWithExampleHolders =
Arrays.stream(errorCodes)
.map(
baseErrorCode -> {
try {
ErrorReason errorReason = baseErrorCode.getErrorReason();
return ExampleHolder.builder()
.holder(
getSwaggerExample(
baseErrorCode.getExplainError(),
errorReason))
.code(errorReason.getStatus())
.name(errorReason.getCode())
.build();
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
})
.collect(groupingBy(ExampleHolder::getCode));

addExamplesToResponses(responses, statusWithExampleHolders);
}

/**
* SwaggerExampleExceptions νƒ€μž…μ˜ 클래슀λ₯Ό λ¬Έμ„œν™” μ‹œν‚΅λ‹ˆλ‹€. SwaggerExampleExceptions νƒ€μž…μ˜ ν΄λž˜μŠ€λŠ” ν•„λ“œλ‘œ
* DuDoongCodeException νƒ€μž…μ„ 가지며, DuDoongCodeException 의 errorReason 와,ExplainError 의 μ„€λͺ…을
* λ¬Έμ„œν™”μ‹œν‚΅λ‹ˆλ‹€.
*/
private void generateExceptionResponseExample(Operation operation, Class<?> type) {
ApiResponses responses = operation.getResponses();

// ----------------생성
Object bean = applicationContext.getBean(type);
Field[] declaredFields = bean.getClass().getDeclaredFields();
Map<Integer, List<ExampleHolder>> stringListMap =
Map<Integer, List<ExampleHolder>> statusWithExampleHolders =
Arrays.stream(declaredFields)
.filter(field -> field.getAnnotation(ExplainError.class) != null)
.filter(field -> field.getType() == DuDoongCodeException.class)
Expand All @@ -124,23 +169,33 @@ private void generateErrorResponseExample(Operation operation, Class<?> type) {
ExplainError annotation =
field.getAnnotation(ExplainError.class);
String value = annotation.value();
ErrorReason errorReason =
exception.getErrorCode().getErrorReason();
ErrorResponse errorResponse =
new ErrorResponse(errorReason, "μš”μ²­μ‹œ νŒ¨μŠ€μ •λ³΄μž…λ‹ˆλ‹€.");
Example example = new Example();
example.description(value);
example.setValue(errorResponse);
return new ExampleHolder(
example, field.getName(), errorReason.getStatus());
ErrorReason errorReason = exception.getErrorReason();
return ExampleHolder.builder()
.holder(getSwaggerExample(value, errorReason))
.code(errorReason.getStatus())
.name(field.getName())
.build();
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
})
.collect(groupingBy(ExampleHolder::getCode));

// -------------------------- μ½˜ν…μΈ  μ„ΈνŒ… μ½”λ“œλ³„λ‘œ 진행
stringListMap.forEach(
addExamplesToResponses(responses, statusWithExampleHolders);
}

private Example getSwaggerExample(String value, ErrorReason errorReason) {
ErrorResponse errorResponse = new ErrorResponse(errorReason, "μš”μ²­μ‹œ νŒ¨μŠ€μ •λ³΄μž…λ‹ˆλ‹€.");
Example example = new Example();
example.description(value);
example.setValue(errorResponse);
return example;
}

private void addExamplesToResponses(
ApiResponses responses, Map<Integer, List<ExampleHolder>> statusWithExampleHolders) {
statusWithExampleHolders.forEach(
(status, v) -> {
Content content = new Content();
MediaType mediaType = new MediaType();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package band.gosrock.api.config.response;


import band.gosrock.common.dto.ErrorReason;
import band.gosrock.common.dto.ErrorResponse;
import band.gosrock.common.exception.BaseErrorCode;
import band.gosrock.common.exception.DuDoongCodeException;
import band.gosrock.common.exception.DuDoongDynamicException;
import band.gosrock.common.exception.ErrorCode;
import band.gosrock.common.exception.GlobalErrorCode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.List;
Expand Down Expand Up @@ -79,10 +81,12 @@ protected ResponseEntity<Object> handleMethodArgumentNotValid(
@ExceptionHandler(DuDoongCodeException.class)
public ResponseEntity<ErrorResponse> DuDoongCodeExceptionHandler(
DuDoongCodeException e, HttpServletRequest request) {
ErrorCode code = e.getErrorCode();
BaseErrorCode code = e.getErrorCode();
ErrorReason errorReason = code.getErrorReason();
ErrorResponse errorResponse =
new ErrorResponse(code.getErrorReason(), request.getRequestURL().toString());
return ResponseEntity.status(HttpStatus.valueOf(code.getStatus())).body(errorResponse);
new ErrorResponse(errorReason, request.getRequestURL().toString());
return ResponseEntity.status(HttpStatus.valueOf(errorReason.getStatus()))
.body(errorResponse);
}

@ExceptionHandler(DuDoongDynamicException.class)
Expand All @@ -107,7 +111,7 @@ protected ResponseEntity<ErrorResponse> handleException(Exception e, HttpServlet
.toUriString();

log.error("INTERNAL_SERVER_ERROR", e);
ErrorCode internalServerError = ErrorCode.INTERNAL_SERVER_ERROR;
GlobalErrorCode internalServerError = GlobalErrorCode.INTERNAL_SERVER_ERROR;
ErrorResponse errorResponse =
new ErrorResponse(
internalServerError.getStatus(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package band.gosrock.api.config.security;


import band.gosrock.common.dto.ErrorReason;
import band.gosrock.common.dto.ErrorResponse;
import band.gosrock.common.exception.BaseErrorCode;
import band.gosrock.common.exception.DuDoongCodeException;
import band.gosrock.common.exception.ErrorCode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import javax.servlet.FilterChain;
Expand Down Expand Up @@ -46,9 +47,10 @@ protected void doFilterInternal(
}
}

private ErrorResponse getErrorResponse(ErrorCode errorCode, String path) {
private ErrorResponse getErrorResponse(BaseErrorCode errorCode, String path) {
ErrorReason errorReason = errorCode.getErrorReason();
return new ErrorResponse(
errorCode.getStatus(), errorCode.getCode(), errorCode.getReason(), path);
errorReason.getStatus(), errorReason.getCode(), errorReason.getReason(), path);
}

private void responseToClient(HttpServletResponse response, ErrorResponse errorResponse)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@


import band.gosrock.common.dto.ErrorResponse;
import band.gosrock.common.exception.BaseErrorCode;
import band.gosrock.common.exception.DuDoongCodeException;
import band.gosrock.common.exception.ErrorCode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import javax.servlet.FilterChain;
Expand Down Expand Up @@ -36,7 +36,7 @@ protected void doFilterInternal(
}
}

private ErrorResponse getErrorResponse(ErrorCode errorCode, String path) {
private ErrorResponse getErrorResponse(BaseErrorCode errorCode, String path) {

return new ErrorResponse(errorCode.getErrorReason(), path);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package band.gosrock.api.eventHandlers;


import band.gosrock.domain.common.events.order.DoneOrderEvent;
import band.gosrock.domain.common.events.order.WithDrawOrderEvent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;

@Component
@RequiredArgsConstructor
@Slf4j
public class OrderEventHandler {

@Async
@TransactionalEventListener(
classes = DoneOrderEvent.class,
phase = TransactionPhase.AFTER_COMMIT)
public void handleDoneOrderEvent(DoneOrderEvent doneOrderEvent) {
log.info(doneOrderEvent.getUuid() + "μ£Όλ¬Έ μƒνƒœ μ™„λ£Œ, ν‹°μΌ“ μƒμ„±ν•„μš”");
}

@Async
@TransactionalEventListener(
classes = WithDrawOrderEvent.class,
phase = TransactionPhase.AFTER_COMMIT)
public void handleRegisterUserEvent(WithDrawOrderEvent withDrawOrderEvent) {
log.info(withDrawOrderEvent.getUuid() + "μ£Όλ¬Έ μƒνƒœ 철회 , ν‹°μΌ“ 제거 ν•„μš”");
}
}
Loading

0 comments on commit e824f42

Please sign in to comment.