What to do?
kakao API 기능 구현
카카오 API 문서에 보고, DTO를 설계하고, Service코드를 작성
환경변수 등록
카카오 API를 활용하기 위해서는 API키가 필요하다.
이전 포스팅(#1)에서 만든 kakao 앱의 API키를 가져오자.
IntellJ에서 Edit Configuration버튼을 눌러서, KAKAO API키를 환경변수로 등록한다.
application.yaml 파일에서 API KEY를 주입받을수 있도록 하자.
kakao:
api:
base-url: "https://dapi.kakao.com/v2/local/search/address.json"
secret-key: ${KAKAO_API_SECRET_KEY}
base-url은 뒤에서 설명하겠지만 API 문서에서 나온 GET요청을 쏘는 주소다.
KaKao API 문서 살펴보기
kakao 개발자 사이트에서 지도 관련된 API 문서를 확인해보자
요청을 보내는 샘플코드다.
요약해보면 다음과 같다.
- 요청 경로
- 헤더
- 인증토큰 : KakaoAK ${REST_API_KEY}
- parameter
- query="검색할 주소"
응답은 다음과 같은 형태로 온다
meta데이터와 documents라는 키값으로 json이 반환되는걸 확인할 수 있다.
이에 맞게 ⓐ MetaDTO, ⓑ documentDTO을 먼저 정의하고, ⓒ responseDTO는 metaDTO, List<doumentDTO>를 가지도록 정의할 것이다.
Domain 정의하기
API 문서와 맞게 Dto를 정의해보자.
MetaDto
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class MetaDto {
/**
* total_count(Integer) 검색어에 검색된 문서 수
* pageable_count(Integer) total_count 중 노출 가능 문서 수(최대: 45)
* is_end(Boolean) 현재 페이지가 마지막 페이지인지 여부, 값이 false면 다음 요청 시 page 값을 증가시켜 다음 페이지 요청 가능
*/
@JsonProperty("total_count")
private Integer totalCount;
}
DocumentDto
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class DocumentDto {
/**
* address_name(String) 전체 지번 주소 또는 전체 도로명 주소, 입력에 따라 결정됨
* address_type(String) address_name의 값의 타입(Type)
* 다음 중 하나:
* REGION(지명)
* ROAD(도로명)
* REGION_ADDR(지번 주소)
* ROAD_ADDR(도로명 주소)
* x(String) X 좌표값, 경위도인 경우 경도(longitude)
* y(String) Y 좌표값, 경위도인 경우 위도(latitude)
* address(Address) 지번 주소 상세 정보, 아래 Address 참고
* road_address(RoadAaddress) 도로명 주소 상세 정보, 아래 RoadAaddress 참고
*/
@JsonProperty("address_name")
private String addressName;
@JsonProperty("x")
private Double longitude;
@JsonProperty("y")
private Double latitude;
}
KakaoApiResponseDto
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class KakaoApiResponseDto {
@JsonProperty("meta")
private MetaDto meta;
@JsonProperty("documents")
private List<DocumentDto> documents;
}
Configuration
RestTemplate을 Bean으로 등록해준다.
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
Service
- buidUri
- 한글 주소를 입력받아 uri로 인코딩
- searchAddress
- 한글 주소를 입력받아 buildUri 메써드로 URI로 변경
- 해당 URI로 검색한 결과를 Dto로 반환
@Slf4j
@Service
@RequiredArgsConstructor
public class KakaoApiService {
private String KAKAO_BASE_URL = "https://dapi.kakao.com/v2/local/search/address.json";
@Value("${kakao.api.secret-key}") private String KAKAO_SECRET_KEY;
private final RestTemplate restTemplate;
public URI buildUri(String address) {
UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(KAKAO_BASE_URL);
uriBuilder.queryParam("query", address);
URI uri = uriBuilder.build().encode().toUri();
log.info("KakaoApiService.buildUri - address: [{}], uri: [{}]", address, uri);
return uri;
}
public KakaoApiResponseDto searchAddress(String address) {
if(ObjectUtils.isEmpty(address)) return null;
URI uri = buildUri(address);
HttpHeaders headers = new HttpHeaders();
headers.set(HttpHeaders.AUTHORIZATION, "KakaoAK " + KAKAO_SECRET_KEY);
return restTemplate
.exchange(uri, HttpMethod.GET, new HttpEntity<>(headers), KakaoApiResponseDto.class)
.getBody();
}
}
Test
- Spock 라이브러리를 사용해 테스트 코드 작성
- 한글주소를 인코딩하고 다시 디코딩한 결과가 원래 한글주소와 같은지 확인
class KakaoApiServiceTest extends Specification {
private KakaoApiService kakaoService
def setup(){
kakaoService = new KakaoApiService()
}
def "buildUri"() {
given:
String 한글주소 = "서울 상도동"
def charset = StandardCharsets.UTF_8
when:
def uri = kakaoService.buildUri(한글주소)
def 인코딩 = uri.toString()
def 디코딩 = URLDecoder.decode(인코딩, charset)
then:
디코딩 == "https://dapi.kakao.com/v2/local/search/address.json?query=" + 한글주소
}
}
'Java > Spring' 카테고리의 다른 글
[Tableau] Plot #2 (0) | 2022.11.10 |
---|---|
[Spring] 게시판 만들기 #1 (0) | 2022.11.07 |
[Spring] 길찾기 서비스 #3 (0) | 2022.11.05 |
[Spring] 길찾기 서비스 #2 (0) | 2022.11.05 |
[Spring] 길찾기 서비스 #1 (0) | 2022.11.05 |