본문 바로가기
모각코

[모각코 10회차] 네이버 지역검색 API 활용 맛집 리스트 만들기

by moonstal 2022. 9. 8.

목표: 네이버 지역검색 API 활용 맛집 리스트 만들기

  1. 저장할 Entity 생성
    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    public class WishListEntity extends MemoryDbEntity {

        private String title;                   // 음식명, 장소명
        private String category;                // 카테고리
        private String address;                 // 주소
        private String roadAddress;             // 도로명
        private String homePageLink;            // 홈페이지 주소
        private String imageLink;               // 음식, 가게 이미지 주소
        private boolean isVisit;                // 방문여부
        private int visitCount;                 // 방문 카운트
        private LocalDateTime lastVisitDate;    // 마지막 방문일자
    }
  1. 네이버 api 연동
  • yml파일에 검색 url과 client id & secret 입력
  • NaverClient에 주입 받아 사용
  • naverLocalSearchUrl과 searchLocalReq를 이용해 uri 만들고
  • header 값에 naverClientId와 naverClientSecret 그리고 ContentType를 넣어
  • responseEntity 결과 받음
    @Component
    public class NaverClient {

        @Value("${naver.client.id}")
        private String naverClientId;

        @Value("${naver.client.secret}")
        private String naverClientSecret;

        @Value("${naver.url.search.local}")
        private String naverLocalSearchUrl;

        @Value("${naver.url.search.image}")
        private String naverImageSearchUrl;

        public SearchLocalRes searchLocal(SearchLocalReq searchLocalReq){
            var uri = UriComponentsBuilder.fromUriString(naverLocalSearchUrl)
                    .queryParams(searchLocalReq.toMultiValueMap())
                    .build()
                    .encode()
                    .toUri();

            var headers = new HttpHeaders();
            headers.set("X-Naver-Client-Id", naverClientId);
            headers.set("X-Naver-Client-Secret", naverClientSecret);
            headers.setContentType(MediaType.APPLICATION_JSON);

            var httpEntity = new HttpEntity<>(headers);
            var responseType = new ParameterizedTypeReference<SearchLocalRes>(){};


            var responseEntity = new RestTemplate().exchange(
                    uri,
                    HttpMethod.GET,
                    httpEntity,
                    responseType
            );

            return responseEntity.getBody();
        }
    }
  1. 지역 및 이미지 검색
  • 지역 검색 후 결과가 있으면 이미지 검색
  • WishListDto 만들어 반환
     public WishListDto search(String query) {
        // 지역검색
        var searchLocalReq = new SearchLocalReq();
        searchLocalReq.setQuery(query);
        var searchLocalRes = naverClient.searchLocal(searchLocalReq);

        if (searchLocalRes.getTotal() > 0) {
            var localItem = searchLocalRes.getItems().stream().findFirst().get();
            var imageQuery = localItem.getTitle().replaceAll("<[^>]*>", "");
            var searchImageReq = new SearchImageReq();
            searchImageReq.setQuery(imageQuery);

            // 이미지 검색
            var searchImageRes = naverClient.searchImage(searchImageReq);

            if (searchImageRes.getTotal() > 0) {
                var imageItem = searchImageRes.getItems().stream().findFirst().get();

                // 결과를 리턴
                var result = new WishListDto();
                result.setTitle(localItem.getTitle());
                result.setCategory(localItem.getCategory());
                result.setAddress(localItem.getAddress());
                result.setRoadAddress(localItem.getRoadAddress());
                result.setHomePageLink(localItem.getLink());
                result.setImageLink(imageItem.getLink());
                return result;
            }
        }

        return new WishListDto();
    }
  1. 지역 및 이미지 저장
  • wishListDto를 entity로 바꿔서 저장
  • 저장된 entity를 wishListDto로 바꿔서 반환
    public WishListDto add(WishListDto wishListDto) {
        var entity = dtoToEntity(wishListDto);
        var saveEntity = wishListRepository.save(entity);
        return entityToDto(saveEntity);
    }
  1. 저장된 지역 및 이미지 불러오기
  • wishListRepository에서 가져온 entity를 wishListDto로 바꿔서 리스트로 반환
    public List<WishListDto> findAll() {
        return wishListRepository.findAll()
                .stream()
                .map(it -> entityToDto(it))
                .collect(Collectors.toList());
    }
  1. 맛집 리스트 삭제, 방문 추가
  • PathVariable 이용하여 기존에 저장된 맛집 리스트 삭제 또는 업데이트
    @DeleteMapping("/{index}")
    public void delete(@PathVariable int index){
        wishListService.delete(index);
    }

    @PostMapping("/{index}")
    public void addVisit(@PathVariable int index){
        wishListService.addVisit(index);
    }

참고