728x90
반응형
source 는 Github 에 있습니다.
목차는 선착순 쿠폰 발급 에 있습니다.
[선착순 쿠폰 발급 3편] API 설명
코틀린, Redis 공부를 위해 작성했습니다.
API 설명
- 쿠폰 발급 요청을 해주는 API 에 대해 간단히 정리했습니다.
Controller Source
@RestController
class CouponIssuanceController(
val couponIssuanceService: CouponIssuanceService
) {
@PostMapping("api/v1/coupon/issuance/request")
fun requestCouponIssuance(
@RequestBody request: CouponIssuanceDto.CouponIssuanceRequest
): ApiResponse<CouponIssuanceDto.CouponIssuanceResponse> {
val couponIssuanceDtoMapper = Mappers.getMapper(CouponIssuanceDtoMapper::class.java)
var couponIssuanceRequest = couponIssuanceDtoMapper.convertToCouponIssuanceRequest(request);
var result = couponIssuanceService.requestPreGeneratedCouponIssuance(couponIssuanceRequest);
return ApiResponse.success(couponIssuanceDtoMapper.convertCouponIssuanceResponse(result))
}
}
- 요약하면 /api/v1/coupon/issuance/request POST 요청이 들어왔을 때, request 를 변환해서 couponIssuanceService.requestPreGeneratedCouponIssuance 를 호출합니다.
- 응답 값은 couponId 입니다.
Redis 호출 Source
@Repository
class CouponRedisRepository(
private val redisTemplate: RedisTemplate<String, Any>
) {
private val AVAILABLE_COUPON_REDIS_KEY: String = "available-coupon"
private val COUPON_USER_MAPPING_REDIS_KEY: String = "coupon-user-mapping"
private val requestPreGeneratedCouponIssuanceScript: RedisScript<String> = DefaultRedisScript(
"""
-- 체크할 user Id를 매개변수로 받음
local userId = ARGV[1]
-- Hash에서 userId가 있는지 확인하고, 있다면 "exist"를 리턴
local check = redis.call('HEXISTS', KEYS[2], ARGV[1])
if check == 1 then
return "exist"
end
-- Set에서 쿠폰 ID를 가져와서 제거
local couponId = redis.call('SPOP', KEYS[1])
if not couponId or couponId == nil then
return "empty"
end
-- Hash에 쿠폰 ID를 저장
redis.call('HSET', KEYS[2], ARGV[1], couponId)
-- 발급된 쿠폰 ID 리턴
return couponId
""",
String::class.java
)
/**
* HASH coupon-user-mapping --> userId couponId 맵핑
* SADD available-coupon
*/
fun requestPreGeneratedCouponIssuance(userId: String): String {
val result: String? = redisTemplate.execute(
requestPreGeneratedCouponIssuanceScript,
listOf(AVAILABLE_COUPON_REDIS_KEY, COUPON_USER_MAPPING_REDIS_KEY), // KEYS[1~2]
userId // ARGS[1]
)
return Optional.ofNullable(result).orElse(Strings.EMPTY)
}
}
요약하면 controller --> service --> redis 를 호출하는 형태이며, requestPreGeneratedCouponIssuance 가 실행이 됩니다.
requestPreGeneratedCouponIssuance 가 하는 역할은 redis 의 lua script 를 실행시킵니다.
Lua script 내용은 다음과 같습니다.
- 처음에 중복 사용자인지 체크한 후 (HEXISTS), 쿠폰이 저장돼있는 redis key 에 접근해서 couponId 를 가져옵니다. (만약 couponId 가 없으면 empty 를 리턴합니다.)
- couponId 를 couponId, userId 맵핑 HASH 에 add 합니다.
'토이프로젝트 > 선착순쿠폰발급' 카테고리의 다른 글
[선착순 쿠폰 발급 4편] 동시 요청 테스트 (0) | 2023.03.27 |
---|---|
[선착순 쿠폰 발급 2편] Redis 자료 구조 설계 (lua script) (0) | 2023.03.18 |
[선착순 쿠폰 발급 1편] 개요 (0) | 2023.03.04 |
댓글