본문 바로가기
Spring Boot

[스프링] 오픈 api 사용해서 데이터 가져오기 (네이버 영화 검색 api)

by 빅팜 2020. 1. 14.
728x90

 

 

네이버 오픈 api를 사용해서 영화를 검색하는 애플리케이션을 구현해보려고 한다. 오픈 api에 대한 정보를 네이버 오픈 api 검색 > 영화에 있다.

 

오픈 API 이용 신청

오픈 api를 사용하려면 보통 key가 필요하다. 아무나 막 가져다 쓰는 것을 막기 위해 보통 key를 api 호출 시 header에 넣어서 사용한다. key 발급을 위해 우선 api 이용 신청을 한다.

초록색 버튼의 [오픈 API 이용 신청]을 누르면 애플리케이션 등록 화면이 나오고 본인의 애플리케이션을 등록하면 된다.

등록을 마치면 내 애플리케이션 카테고리에서 Client ID와 Client Secret을 확인할 수 있다. 이 값이 위에서 말한 key 값이다.

 

 

코드를 구현하기 전에 Postman으로 테스트를 해보니 정상적으로 반환되는 것을 확인할 수 있었다.

 

 

mustache 템플릿 엔진

검색창에 키워드를 입력 받아 영화를 검색해야 하므로, 클라이언트 화면을 간단하게 꾸며준다. 화면은 부트스트랩으로 만들었다. mustache 템플릿 엔진을 사용하고 있어서 header와 footer 사이에 코드를 작성해주었다. 버튼을 누르면 동작하게 할 js 파일도 작성해준다. js 파일에서 find 함수를 통해 통신을 할 것이다. 결과 화면은 아직 구현이 안 되었으므로, 데이터가 정상적으로 받아와지는지 alert을 띄어본다.

{{>layout/header}}


<div class="col-md-12">
    <h1>영화 검색</h1>
    <div class="col-md-4">
        <form>
            <div class="form-group">
                <input type="text" class ="form-control" id="keyword" placeholder="검색어를 입력하세요">
                <button type="button" class="btn btn-primary" id="btn-movies-find">검색</button>
            </div>
    </div>
</div>

{{>layout/footer}}

 

var main = {
    init : function () {
        var _this = this;
        $('#btn-movies-find').on('click', function () {
            _this.find();
        });
    },
    find : function () {
        var keyword = $('#keyword').val();

        $.ajax({
            type: 'GET',
            url: '/api/v1/movies/'+keyword,
            dataType: 'json',
            contentType:'application/json; charset=utf-8',
        }).done(function(res) {
            alert(JSON.stringify(res));
        }).fail(function (error) {
            alert(JSON.stringify(error));
        });
    }
};

main.init();

 

spring boot

web/MoviesApiController

package com.leveloper.test.springboot.web;

import com.leveloper.test.springboot.service.movies.MoviesService;
import com.leveloper.test.springboot.web.dto.MoviesResponseDto;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RestController
public class MoviesApiController {
    private final MoviesService moviesService;

    @GetMapping("/api/v1/movies/{keyword}")
    public MoviesResponseDto get(@PathVariable String keyword){
        return moviesService.findByKeyword(keyword);
    }
}

 

service/movies/MoviesService

package com.leveloper.test.springboot.service.movies;

import com.leveloper.test.springboot.api.MovieApiClient;
import com.leveloper.test.springboot.web.dto.MoviesResponseDto;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@RequiredArgsConstructor
@Service
public class MoviesService {
    private final MovieApiClient movieApiClient;

    @Transactional(readOnly = true)
    public MoviesResponseDto findByKeyword(String keyword) {
        return movieApiClient.requestMovie(keyword);
    }
}

 

api/MovieApiClient

package com.leveloper.test.springboot.api;

import com.leveloper.test.springboot.web.dto.MoviesResponseDto;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@RequiredArgsConstructor
@Service
public class MovieApiClient {
    private final RestTemplate restTemplate;

    private final String CLIENT_ID = 개인의 Client id;
    private final String CLIENT_SECRET = 개인의 Client secret;

    private final String OpenNaverMovieUrl_getMovies = "https://openapi.naver.com/v1/search/movie.json?query={keyword}";

    public MoviesResponseDto requestMovie(String keyword) {
        final HttpHeaders headers = new HttpHeaders(); // 헤더에 key들을 담아준다.
        headers.set("X-Naver-Client-Id", CLIENT_ID);
        headers.set("X-Naver-Client-Secret", CLIENT_SECRET);

        final HttpEntity<String> entity = new HttpEntity<>(headers);

        return restTemplate.exchange(OpenNaverMovieUrl_getMovies, HttpMethod.GET, entity, MoviesResponseDto.class, keyword).getBody();
    }
}

 

web/dto/MoviesResponseDto

 Item은 MoviesResponseDto에서만 사용하는 클래스이므로 static inner class로 선언하여 사용해주자.

package com.leveloper.test.springboot.web.dto;

import lombok.Data;

import java.util.Date;

@Data
public class MoviesResponseDto {
    private int display;
    private Item[] items;
    
    @Data
    static class Item {
        public String title;
        public String link;
        public String image;
        public String subtitle;
        public Date pubDate;
        public String director;
        public String actor;
        public float userRating;
    }
}

 

확인

이제 연결이 다 되었으니 애플리케이션을 실행하여 검색을 해보자. 정상적으로 동작 되었다면 alert창에 검색 결과가 나올 것이다.

 

 

마무리

작년 여름에 학교에서 스프링을 간단하게 배울 때 오픈 api를 사용해서 데이터를 가져오는 실습을 한 적이 있다. 라이엇 게임즈에서 유저 정보를 가져오는 api였는데, 그때의 기억을 되짚으며 구현을 해보았다. 한 가지 삽질을 한 부분이 Dto 작성을 할 때, 배열을 어떻게 받는지였다. 배열 정보를 받을 때 어떤 식으로 Dto를 선언해야 할지가 난감했다.

이제 api로 데이터를 받아 왔으니 화면에 보여주는 걸 만들고, db에도 저장을 해야하니 db랑도 연동을 해야할 듯 하다.

728x90