-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #90 from le2sky/fix/89
[문제] 카카오 주소 검색 API 연동 문제(issue#89)
- Loading branch information
Showing
6 changed files
with
414 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
72 changes: 56 additions & 16 deletions
72
...ao-api-address-resolver/src/main/kotlin/com/mealkitary/address/KakaoApiAddressResolver.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,79 @@ | ||
package com.mealkitary.address | ||
|
||
import com.mealkitary.address.payload.Document | ||
import com.mealkitary.address.payload.Meta | ||
import com.mealkitary.address.payload.RoadAddress | ||
import com.mealkitary.common.model.Address | ||
import com.mealkitary.common.model.Coordinates | ||
import com.mealkitary.shop.domain.shop.ShopAddress | ||
import com.mealkitary.shop.domain.shop.factory.AddressResolver | ||
import org.springframework.context.annotation.Primary | ||
import org.springframework.stereotype.Component | ||
|
||
private const val INVALID_ROAD_ADDR_MESSAGE = "올바른 도로명 주소를 입력해주세요." | ||
private const val INVALID_COORDINATE_FORMAT = "유효하지 않은 좌표 범위입니다." | ||
private const val BUILDING_NO_DELIMITER = "-" | ||
private const val VALID_ADDR_TYPE = "ROAD_ADDR" | ||
|
||
@Primary | ||
@Component | ||
class KakaoApiAddressResolver( | ||
private val kakaoApiWebClient: KakaoApiWebClient | ||
) : AddressResolver { | ||
|
||
override fun resolve(fullAddress: String): ShopAddress { | ||
val kakaoApiAddressResponse = kakaoApiWebClient.requestAddress(fullAddress) | ||
val (documents, meta) = kakaoApiWebClient.requestAddress(fullAddress, "https://dapi.kakao.com") | ||
checkHasDocument(meta, documents) | ||
val document = findFirstMatchedDocument(documents) | ||
|
||
val (x, y, address, roadAddress) = kakaoApiAddressResponse.document | ||
return ShopAddress.of(resolveCityCode(document), resolveCoordinates(document), resolveAddress(document)) | ||
} | ||
|
||
val (longitude, latitude) = listOf(x, y).map { | ||
it.toDoubleOrNull() ?: throw IllegalArgumentException("유효하지 않은 좌표 범위입니다.") | ||
private fun checkHasDocument(meta: Meta, documents: List<Document>) { | ||
if (meta.total_count < 0 || documents.isEmpty()) { | ||
throw IllegalArgumentException(INVALID_ROAD_ADDR_MESSAGE) | ||
} | ||
} | ||
|
||
private fun findFirstMatchedDocument(documents: List<Document>): Document { | ||
val firstMatchedDocument = documents[0] | ||
checkIsValidAddressType(firstMatchedDocument) | ||
|
||
return firstMatchedDocument | ||
} | ||
|
||
private fun checkIsValidAddressType(addressDocument: Document) { | ||
if (addressDocument.address_type != VALID_ADDR_TYPE) { | ||
throw IllegalArgumentException(INVALID_ROAD_ADDR_MESSAGE) | ||
} | ||
} | ||
|
||
private fun resolveCityCode(document: Document): String { | ||
requireNotNull(document.address) { INVALID_ROAD_ADDR_MESSAGE } | ||
|
||
return document.address.h_code | ||
} | ||
|
||
private fun resolveCoordinates(loadAddressDocument: Document): Coordinates { | ||
val (longitude, latitude) = listOf(loadAddressDocument.x, loadAddressDocument.y).map { | ||
it.toDoubleOrNull() ?: throw IllegalArgumentException(INVALID_COORDINATE_FORMAT) | ||
} | ||
|
||
return Coordinates.of(longitude, latitude) | ||
} | ||
|
||
private fun resolveAddress(document: Document): Address { | ||
val roadAddress: RoadAddress = requireNotNull(document.road_address) { INVALID_ROAD_ADDR_MESSAGE } | ||
val roadName = | ||
"${roadAddress.road_name} ${roadAddress.main_building_no}-${roadAddress.sub_building_no}".trim() | ||
|
||
return ShopAddress.of( | ||
roadAddress.h_code, | ||
Coordinates.of( | ||
longitude, | ||
latitude | ||
), | ||
Address.of( | ||
address.region_1depth_name, | ||
address.region_2depth_name, | ||
address.region_3depth_name, | ||
roadAddress.road_name | ||
) | ||
return Address.of( | ||
roadAddress.region_1depth_name, | ||
roadAddress.region_2depth_name, | ||
roadAddress.region_3depth_name, | ||
if (roadName.endsWith(BUILDING_NO_DELIMITER)) { | ||
roadName.replace(BUILDING_NO_DELIMITER, "") | ||
} else roadName | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 47 additions & 18 deletions
65
...ddress-resolver/src/main/kotlin/com/mealkitary/address/payload/KakaoApiAddressResponse.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,52 @@ | ||
package com.mealkitary.address.payload | ||
|
||
data class KakaoApiAddressResponse( | ||
val document: Document | ||
) { | ||
data class Document( | ||
val x: String, | ||
val y: String, | ||
val address: Address, | ||
val road_address: RoadAddress | ||
) | ||
val documents: List<Document>, | ||
val meta: Meta | ||
) | ||
|
||
data class Address( | ||
val region_1depth_name: String, | ||
val region_2depth_name: String, | ||
val region_3depth_name: String, | ||
) | ||
data class Meta( | ||
val is_end: Boolean, | ||
val pageable_count: Int, | ||
val total_count: Int | ||
) | ||
|
||
data class RoadAddress( | ||
val road_name: String, | ||
val h_code: String | ||
) | ||
} | ||
data class Document( | ||
val address_name: String, | ||
val address_type: String, | ||
val address: Address?, | ||
val road_address: RoadAddress?, | ||
val x: String, | ||
val y: String | ||
) | ||
|
||
class Address( | ||
val address_name: String, | ||
val b_code: String, | ||
val h_code: String, | ||
val main_address_no: String, | ||
val mountain_yn: String, | ||
val region_1depth_name: String, | ||
val region_2depth_name: String, | ||
val region_3depth_h_name: String, | ||
val region_3depth_name: String, | ||
val sub_address_no: String, | ||
val x: String, | ||
val y: String | ||
|
||
) | ||
|
||
class RoadAddress( | ||
val address_name: String, | ||
val building_name: String, | ||
val main_building_no: String, | ||
val region_1depth_name: String, | ||
val region_2depth_name: String, | ||
val region_3depth_name: String, | ||
val road_name: String, | ||
val sub_building_no: String, | ||
val underground_yn: String, | ||
val x: String, | ||
val y: String, | ||
val zone_no: String | ||
) |
Oops, something went wrong.