Project (Back-end + DevOps)/UMC_TravelCompass(2023~4)

[UMC] Naver Maps Api(Directions) + Open Feign 이용하여 소요시간 도출하기

persi0815 2024. 2. 12. 20:46

1. Naver Api 가져오기


https://www.ncloud.com/product/applicationService/maps

 

NAVER CLOUD PLATFORM

cloud computing services for corporations, IaaS, PaaS, SaaS, with Global region and Security Technology Certification

www.ncloud.com

 

1. 로그인

 

2. 이용신청

 

3. ai Naver Api

 

4. application 이름 설정

 

5. service 선택

저는 출발지와 도착지에 대한 좌표값이 주어졌을때 자가용 소요시간(이동시간)이 필요해서 Directions를 선택했습니다. 

서비스 소개는 다음과 같습니다. 

 

Directions 5와 Directions 15는 경유지의 개수 차이인데, 요금 측면에서 차이가 존재하니, 필요하신 서비스 고르시면 됩니다. 

 

6. 서비스 환경 등록

저희 서비스의 도메인 주소를 기입했습니다. 저렇게 기입해놓아도 로컬에서도 잘 동작합니다!

 

7. 등록

 

8. 인증키 확인

'저장' 누른 후 나오는 해당 화면에서

 

'인증 정보' 버튼 누르시면

client Id와 client Secret key 확인 가능합니다.

 

2. Naver Api + Open Feign -> 소요시간 도출


https://api.ncloud-docs.com/docs/ai-naver-mapsdirections-driving#OptionCode

 

driving

 

api.ncloud-docs.com

direction 5 개발 가이드 링크입니다! 개발 하다가 문제가 생길땐 꼭 꼼꼼히 읽어보시는 걸 추천합니다!

 

 

1. application.yml

# 네이버 경로 api
naver:
  directions:
    api-url: https://naveropenapi.apigw.ntruss.com/map-direction
    client-id: ${NAVER_DIRECTIONS_CLIENT_ID}
    client-secret: ${NAVER_DIRECTIONS_CLIENT_SECRET}

client Id와 client Secret은 환경변수 처리해주었습니다.

 

2. NaverPathController

package com.travelcompass.api.feign.Naver;

import com.travelcompass.api.global.api_payload.ApiResponse;
import com.travelcompass.api.global.api_payload.SuccessCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.json.JSONObject;

@RestController
public class NaverPathController {

    private final NaverPathService naverPathService;

    @Autowired
    public NaverPathController(NaverPathService naverPathService) {
        this.naverPathService = naverPathService;
    }

    // http://dev.enble.site:8080/getCarDuration?start=127.12345,37.12345&goal=128.12345,37.12345
    @GetMapping("/getCarDuration")
    public ApiResponse<Integer> getDuration(@RequestParam("start") String start,
                                              @RequestParam("goal") String goal) {
        // 클라이언트의 요청을 받아서 네이버 경로 서비스로 전달
        ResponseEntity<String> response = naverPathService.getDuration(start, goal);

        // API Response로부터 body 뽑아내기
        String body = response.getBody();
        JSONObject json = new JSONObject(body);

        // body에서 duration 추출하기
        int duration = json.getJSONObject("route").getJSONArray("traoptimal")
                .getJSONObject(0).getJSONObject("summary").getInt("duration");

        return ApiResponse.onSuccess(SuccessCode.PLAN_NAVER_GET_DURATION, duration);
    }
}

client가 아래와 같은 주소로 출발지와 도착지를 좌표값으로 파라미터에 넣어서 요청을 보내면, 

http://dev.enble.site:8080/getCarDuration?start=127.12345,37.12345&goal=128.12345,37.12345

컨트롤러에서는 client의 요청을 받아서 네이버 경로 서비스로 전달합니다. 

 

3. NaverPathService

package com.travelcompass.api.feign.Naver;

import com.travelcompass.api.feign.Naver.NaverDurationClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

@Service
public class NaverPathService {

    private final NaverDurationClient naverDurationClient;
    private final String clientId;
    private final String clientSecret;

    public NaverPathService(NaverDurationClient naverDurationClient,
                            @Value("${naver.directions.client-id}") String clientId,
                            @Value("${naver.directions.client-secret}") String clientSecret) {
        this.naverDurationClient = naverDurationClient;
        this.clientId = clientId;
        this.clientSecret = clientSecret;
    }

    public ResponseEntity<String> getDuration(String start, String goal) {
        // 네이버 API에 요청을 보내기 전에 클라이언트 ID와 시크릿을 헤더에 설정
        return naverDurationClient.getDuration(start, goal, clientId, clientSecret);
    }
}

service에서는 네이버 api에 요청을 보내기 전에 클라이언트 id와 secret을 헤더에 설정합니다. 

 

 

4. NaverDurationClient

package com.travelcompass.api.feign.Naver;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@FeignClient(name = "naverDurationClient", url = "${naver.directions.api-url}")
public interface NaverDurationClient {

    @GetMapping("/v1/driving")
    ResponseEntity<String> getDuration(@RequestParam("start") String start,
                                         @RequestParam("goal") String goal,
                                         @RequestHeader("X-NCP-APIGW-API-KEY-ID") String clientId,
                                         @RequestHeader("X-NCP-APIGW-API-KEY") String clientSecret);
}

Open Feign 사용시 꼭 수반되는 두 파일 중 하나인 Client입니다. 꼭 @FeignClient를 선언해주어야 합니다. 

 

3. 동작 과정


1. http://dev.enble.site:8080/getCarDuration?start=127.12345,37.12345&goal=128.12345,37.12345

로 요청을 받습니다. 

 

2. 파라미터로 받은 start, goal값을 이용해 다시 네이버에게 다음과 같이 요청합니다.  https://naveropenapi.apigw.ntruss.com/map-direction/v1/driving?start=127.12345,37.12345&goal=128.12345,37.12345

 

3. 네이버 api는 다음과 같이 응답합니다. 

 

4. 저희는 duration(소요시간)만 필요했기에 컨트롤러를 통해 api response로부터 body를 뽑아내고, body에서 duration을 추출하여 return 해주었습니다. 참고로 소요시간 단위는 millisecond(1/1000초) 입니다.

*로컬에서 테스트한 결과입니다.

 

4. 참고


https://velog.io/@yunsser/java-%EC%A7%80%EB%8F%84-%EB%B6%88%EB%9F%AC%EC%98%A4%EA%B8%B0

 

velog

 

velog.io