오늘은 스프링부트에서 T Map API를 호출해보겠습니다.
원래는 API 호출을 서버에서 하는게 드문 일이지만, 서비스 상 도보 길찾기 API Response에 DB에 있는 데이터를 섞어서 새로운 Response를 돌려 주어야 하는 흐름으로 진행하기 때문에 서버에서 API 호출을 하게 되었습니다.
호출할 API : 보행자 경로 탐색 API
저는 현재 보행자 대상의 라우팅 서비스를 만들고 있습니다.
보행자 내비게이션은 현재 한국에서 T MAP만 API 사용이 가능합니다.
그래서 T Map에서 제공하는 보행자 경로 탐색 API 연결을 하겠습니다.
먼저 API 스펙을 살펴보겠습니다.
HttpResponse<String> response = Unirest.post("https://apis.openapi.sk.com/tmap/routes/pedestrian?version=1&callback=function")
.header("accept", "application/json")
.header("content-type", "application/json")
.header("appKey", "e8wHh2tya84M88aReEpXCa5XTQf3xgo01aZG39k5")
.body("{\"startX\":126.92365493654832,\"startY\":37.556770374096615,\"angle\":20,\"speed\":30,\"endPoiId\":\"10001\",\"endX\":126.92432158129688,\"endY\":37.55279861528311,\"passList\":\"126.92774822,37.55395475_126.92577620,37.55337145\",\"reqCoordType\":\"WGS84GEO\",\"startName\":\"%EC%B6%9C%EB%B0%9C\",\"endName\":\"%EB%8F%84%EC%B0%A9\",\"searchOption\":\"0\",\"resCoordType\":\"WGS84GEO\",\"sort\":\"index\"}")
.asString();
이 코드는 Java에서 Tmap API를 사용하여 보행자 경로를 요청하고 응답을 받는 예제입니다. 여기서 Tmap은 한국 SK텔레콤의 지도 및 위치기반 서비스 플랫폼입니다.
요청은 HTTP POST 방식을 사용하며, URL은 https://apis.openapi.sk.com/tmap/routes/pedestrian
입니다. 요청은 JSON 형식의 본문을 가지고 있습니다.
요청의 헤더에는 다음 정보가 포함되어 있습니다:
accept
: 응답으로 받기를 원하는 데이터 형식을 나타냅니다. 여기서는 JSON 형식을 요청하고 있습니다.content-type
: 요청의 본문 형식을 지정합니다. 여기서는 JSON 형식을 사용하고 있습니다.appKey
: Tmap API를 사용하기 위한 인증 키를 나타냅니다.요청 본문은 다음과 같은 정보를 포함하고 있습니다:
startX
, startY
: 출발 지점의 경도 및 위도를 나타냅니다.angle
: 출발 지점의 방향을 나타냅니다.speed
: 보행자의 평균 이동 속도를 나타냅니다.endPoiId
, endX
, endY
: 목적지 지점의 ID, 경도 및 위도를 나타냅니다.passList
: 경유지 목록을 나타냅니다.reqCoordType
: 요청 좌표 체계를 나타냅니다.startName
, endName
: 출발지 및 목적지 이름을 나타냅니다.searchOption
: 경로 탐색 옵션을 나타냅니다.resCoordType
: 응답 좌표 체계를 나타냅니다.sort
: 경로 결과의 정렬 방식을 나타냅니다.요청을 보내고 응답을 받기 위해 Unirest 라이브러리를 사용하고 있습니다. 받은 응답은 문자열 형태로 처리됩니다.
암튼 이렇게 호출을 하면 됩니다.
Tmap API를 호출하기 위해 필요한 요소들을 정리해보겠습니다.
POST
URL:
https://apis.openapi.sk.com/tmap/routes/pedestrian
헤더 (Headers):
파라미터 (Parameters):
우선 required 만 정리했습니다. 더 상세 스펙은 레퍼런스에서 확인할 수 있습니다.
저는 추후에 이 API 뿐만 아니라 OSRM API를 추가적으로 연결할 계획이 있습니다.
따라서 조금더 유연하게 설계하고자 합니다.
우선 프론트에서 위에 언급한 필수 파라미터를 받는다는 전제하에 진행합니다.
각 클래스는 여러개로 생성하고, 인터페이스를 두어 추후에 다른 서비스 호출에도 사용할 수 있도록 구조를 설계하였습니다.
이유는 유연한 서비스 구조를 만들면 유지보수도 쉽고 활용가능성도 높아 유용하기 때문입니다.
service 단에서 interface를 사용하는 이유는 다음과 같습니다.
구현 분리 (Implementation Separation)
의존성 역전 원칙 (Dependency Inversion Principle)
다형성 (Polymorphism)
테스트 용이성 (Testability)
코드의 유연성 (Flexibility)
이러한 이유로 서비스 계층에서 인터페이스를 사용하여 구현하는 것이 좋은 소프트웨어 디자인의 일반적인 원칙 중 하나입니다.
전에 언급했던 것과 같이, 저는 추후에 OSRM API 호출 또한 만들 예정입니다. 그렇기 때문에 다형성과 유연한 코드 흐름이 필요합니다. 그래서 다음과 같이 서비스 인터페이스를 설계했습니다.
해당 API 호출을 위한 controller를 구상합니다.
이를 클래스 다이어그램으로 나타내면 다음과 같습니다.
이런 식으로 설계를 완료했습니다.
작성하면서 다시한번 공부해야하는 것
interface vs abstract