-
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 #86 from le2sky/feat/84
[기능 구현] 카카오 주소 조회 api 연동 (issue#84)
- Loading branch information
Showing
18 changed files
with
291 additions
and
26 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
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
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
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
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
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
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
4 changes: 0 additions & 4 deletions
4
mealkitary-infrastructure/adapter-address-resolver/build.gradle.kts
This file was deleted.
Oops, something went wrong.
7 changes: 7 additions & 0 deletions
7
...itary-infrastructure/adapter-address-resolver/kakao-api-address-resolver/build.gradle.kts
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 |
---|---|---|
@@ -0,0 +1,7 @@ | ||
dependencies { | ||
val mockWebServerVersion: String by properties | ||
implementation("org.springframework.boot:spring-boot-starter-webflux") | ||
implementation(project(":mealkitary-domain")) | ||
testImplementation("com.squareup.okhttp3:mockwebserver:$mockWebServerVersion") | ||
testImplementation("io.projectreactor:reactor-test") | ||
} |
39 changes: 39 additions & 0 deletions
39
...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 |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.mealkitary.address | ||
|
||
import com.mealkitary.common.model.Address | ||
import com.mealkitary.common.model.Coordinates | ||
import com.mealkitary.shop.domain.shop.address.ShopAddress | ||
import com.mealkitary.shop.domain.shop.factory.AddressResolver | ||
import org.springframework.context.annotation.Primary | ||
import org.springframework.stereotype.Component | ||
|
||
@Primary | ||
@Component | ||
class KakaoApiAddressResolver( | ||
private val kakaoApiWebClient: KakaoApiWebClient | ||
) : AddressResolver { | ||
|
||
override fun resolve(fullAddress: String): ShopAddress { | ||
val kakaoApiAddressResponse = kakaoApiWebClient.requestAddress(fullAddress) | ||
|
||
val (x, y, address, roadAddress) = kakaoApiAddressResponse.document | ||
|
||
val (longitude, latitude) = listOf(x, y).map { | ||
it.toDoubleOrNull() ?: throw IllegalArgumentException("유효하지 않은 좌표 범위입니다.") | ||
} | ||
|
||
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 | ||
) | ||
) | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
...er/kakao-api-address-resolver/src/main/kotlin/com/mealkitary/address/KakaoApiWebClient.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 |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.mealkitary.address | ||
|
||
import com.mealkitary.address.payload.KakaoApiAddressResponse | ||
import org.springframework.beans.factory.annotation.Value | ||
import org.springframework.stereotype.Component | ||
import org.springframework.web.reactive.function.client.WebClient | ||
|
||
private const val KAKAO_API_BASE_URL = "/v2/local/search/address" | ||
private const val FORMAT = "json" | ||
|
||
@Component | ||
class KakaoApiWebClient( | ||
private val webClient: WebClient, | ||
@Value("\${kakaoapi.address.serviceKey}") | ||
private val serviceKey: String, | ||
) { | ||
|
||
fun requestAddress(query: String): KakaoApiAddressResponse { | ||
val kakaoApiAddressResponse = webClient.get() | ||
.uri { uriBuilder -> | ||
uriBuilder.path("$KAKAO_API_BASE_URL.$FORMAT") | ||
.queryParam("query", query) | ||
.build() | ||
} | ||
.header("Authorization", "KakaoAK $serviceKey") | ||
.retrieve() | ||
.bodyToMono(KakaoApiAddressResponse::class.java) | ||
.block() | ||
|
||
return kakaoApiAddressResponse!! | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
...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 |
---|---|---|
@@ -0,0 +1,23 @@ | ||
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 | ||
) | ||
|
||
data class Address( | ||
val region_1depth_name: String, | ||
val region_2depth_name: String, | ||
val region_3depth_name: String, | ||
) | ||
|
||
data class RoadAddress( | ||
val road_name: String, | ||
val h_code: String | ||
) | ||
} |
47 changes: 47 additions & 0 deletions
47
...api-address-resolver/src/test/kotlin/com/mealkitary/addess/KakaoApiAddressResolverTest.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 |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package com.mealkitary.addess | ||
|
||
import com.mealkitary.address.KakaoApiAddressResolver | ||
import com.mealkitary.address.KakaoApiWebClient | ||
import com.mealkitary.address.payload.KakaoApiAddressResponse | ||
import io.kotest.core.spec.style.AnnotationSpec | ||
import io.kotest.matchers.shouldBe | ||
import io.mockk.every | ||
import io.mockk.mockk | ||
|
||
class KakaoApiAddressResolverTest : AnnotationSpec() { | ||
|
||
private val kakaoApiWebClient = mockk<KakaoApiWebClient>() | ||
private val kakaoApiAddressResolver = KakaoApiAddressResolver(kakaoApiWebClient) | ||
|
||
@Test | ||
fun `Kakao API를 통해 해당하는 주소 정보를 받아온다`() { | ||
val address = "경기도 남양주시 다산중앙로82번안길 132-12" | ||
val response = KakaoApiAddressResponse( | ||
document = KakaoApiAddressResponse.Document( | ||
x = "127.166069448936", | ||
y = "37.6120947950094", | ||
address = KakaoApiAddressResponse.Address( | ||
region_1depth_name = "경기", | ||
region_2depth_name = "남양주시", | ||
region_3depth_name = "다산동" | ||
), | ||
road_address = KakaoApiAddressResponse.RoadAddress( | ||
road_name = "다산중앙로82번안길", | ||
h_code = "4136011200" | ||
) | ||
) | ||
) | ||
|
||
every { kakaoApiWebClient.requestAddress(address) } returns response | ||
|
||
val shopAddress = kakaoApiAddressResolver.resolve(address) | ||
|
||
shopAddress.address.region1DepthName shouldBe "경기" | ||
shopAddress.address.region2DepthName shouldBe "남양주시" | ||
shopAddress.address.region3DepthName shouldBe "다산동" | ||
shopAddress.address.roadName shouldBe "다산중앙로82번안길" | ||
shopAddress.cityCode shouldBe "4136011200" | ||
shopAddress.coordinates.longitude shouldBe 127.166069448936 | ||
shopAddress.coordinates.latitude shouldBe 37.6120947950094 | ||
} | ||
} |
105 changes: 105 additions & 0 deletions
105
...kakao-api-address-resolver/src/test/kotlin/com/mealkitary/addess/KakaoApiWebClientTest.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 |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package com.mealkitary.addess | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper | ||
import com.mealkitary.address.KakaoApiWebClient | ||
import com.mealkitary.address.payload.KakaoApiAddressResponse | ||
import io.kotest.assertions.throwables.shouldThrow | ||
import io.kotest.inspectors.forAll | ||
import io.kotest.matchers.shouldBe | ||
import okhttp3.mockwebserver.MockResponse | ||
import okhttp3.mockwebserver.MockWebServer | ||
import org.junit.jupiter.api.AfterEach | ||
import org.junit.jupiter.api.BeforeEach | ||
import org.junit.jupiter.api.Test | ||
import org.springframework.http.HttpHeaders | ||
import org.springframework.http.MediaType | ||
import org.springframework.web.reactive.function.client.WebClient | ||
import java.lang.RuntimeException | ||
|
||
class KakaoApiWebClientTest { | ||
|
||
private lateinit var mockWebServer: MockWebServer | ||
private lateinit var webClient: WebClient | ||
private lateinit var kakaoApiWebClient: KakaoApiWebClient | ||
private val objectMapper = ObjectMapper() | ||
|
||
@BeforeEach | ||
fun setUp() { | ||
mockWebServer = MockWebServer() | ||
mockWebServer.start() | ||
webClient = WebClient.builder() | ||
.baseUrl(mockWebServer.url("").toString()) | ||
.codecs { configurer -> | ||
configurer.defaultCodecs().maxInMemorySize(5 * 1024 * 1024) | ||
} | ||
.defaultHeaders { headers -> | ||
headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) | ||
headers.set(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) | ||
} | ||
.build() | ||
|
||
kakaoApiWebClient = KakaoApiWebClient(webClient, "serviceKey") | ||
} | ||
|
||
@AfterEach | ||
fun teardown() { | ||
mockWebServer.shutdown() | ||
} | ||
|
||
@Test | ||
fun `200 OK를 받으면 아무 예외도 발생하지 않는다`() { | ||
val address = "경기도 남양주시 다산중앙로82번안길 132-12" | ||
val response = createResponse() | ||
|
||
mockWebServer.enqueue( | ||
MockResponse() | ||
.setBody(objectMapper.writeValueAsString(response)) | ||
.setResponseCode(200) | ||
.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON) | ||
) | ||
|
||
val actualResponse = kakaoApiWebClient.requestAddress(address) | ||
|
||
val recordedRequest = mockWebServer.takeRequest() | ||
recordedRequest.method shouldBe "GET" | ||
|
||
actualResponse.document.road_address.h_code shouldBe response.document.road_address.h_code | ||
actualResponse.document.x shouldBe response.document.x | ||
actualResponse.document.y shouldBe response.document.y | ||
actualResponse.document.address.region_1depth_name shouldBe response.document.address.region_1depth_name | ||
actualResponse.document.address.region_2depth_name shouldBe response.document.address.region_2depth_name | ||
actualResponse.document.address.region_3depth_name shouldBe response.document.address.region_3depth_name | ||
actualResponse.document.road_address.road_name shouldBe response.document.road_address.road_name | ||
} | ||
|
||
@Test | ||
fun `200이 아닌 코드는 RuntimeException으로 처리한다`() { | ||
listOf(400, 401, 500).forAll { | ||
mockWebServer.enqueue( | ||
MockResponse() | ||
.setResponseCode(it) | ||
.setBody(objectMapper.writeValueAsString(createResponse())) | ||
.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON) | ||
) | ||
shouldThrow<RuntimeException> { | ||
kakaoApiWebClient.requestAddress("경기도남양주시다산중앙로82번안길132-12") | ||
} | ||
} | ||
} | ||
|
||
private fun createResponse() = KakaoApiAddressResponse( | ||
document = KakaoApiAddressResponse.Document( | ||
x = "127.166069448936", | ||
y = "37.6120947950094", | ||
address = KakaoApiAddressResponse.Address( | ||
region_1depth_name = "경기", | ||
region_2depth_name = "남양주시", | ||
region_3depth_name = "다산동" | ||
), | ||
road_address = KakaoApiAddressResponse.RoadAddress( | ||
road_name = "다산중앙로82번안길", | ||
h_code = "4136011200" | ||
) | ||
) | ||
) | ||
} |
3 changes: 3 additions & 0 deletions
3
mealkitary-infrastructure/adapter-address-resolver/simple-address-resolver/build.gradle.kts
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 |
---|---|---|
@@ -0,0 +1,3 @@ | ||
dependencies { | ||
implementation(project(":mealkitary-domain")) | ||
} |
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
Oops, something went wrong.