Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

['21.07.13] Naver API 연동 본문

Project/영화리뷰 관리

['21.07.13] Naver API 연동

Seung__ 2021. 7. 13. 23:12

1. 오늘의 목표


 Naver Api와 연동하여 Req보내고 Res받기

 

 

2. REQ


Request 객체는 naver api에서 요구하는 변수를 필드로 가지고 있어야 한다.

 

Naver API의 개발 가이드를 보면 아래 정보를 확인할 수 있다.

 

 

1) 변수명 및 타입

변수명 타입 필수 기본값 설명
query string (필수) Y - 검색을 원하는 질의. UTF-8 인코딩이다.
display integer N 기본값 10, 최대 100 검색 결과 출력 건수를 지정한다. 최대 100까지 가능하다.
start integer N 기본값 1, 최대 1000 검색의 시작 위치를 지정할 수 있다. 최대 1000까지 가능하다.
genre string N - 검색을 원하는 장르 코드를 의미한다. 영화 코드는 다음과 같다.
1: 드라마 2: 판타지
3: 서부 4: 공포
5: 로맨스 6: 모험
7: 스릴러 8: 느와르
9: 컬트 10: 다큐멘터리
11: 코미디 12: 가족
13: 미스터리 14: 전쟁
15: 애니메이션 16: 범죄
17: 뮤지컬 18: SF
19: 액션20: 무협
21: 에로 22: 서스펜스
23: 서사 24: 블랙코미디
25: 실험 26: 영화카툰
27: 영화음악 28: 영화패러디포스터













country string N - 검색을 원하는 국가 코드를 의미한다. 국가코드는 대문자만 사용 가능하며,
분류는 다음과 같다.
한국 (KR), 일본 (JP), 미국 (US), 홍콩 (HK),
영국 (GB), 프랑스 (FR), 기타 (ETC)


yearfrom integer
(ex : 2000)
N - 검색을 원하는 영화의 제작년도(최소)를 의미한다.
yearfrom은 yearto와 함께 사용되어야 한다.
yearto integer
(ex : 2008)
N - 검색을 원하는 영화의 제작년도(최대)를 의미한다.
yearto는 yearfrom과 함께 사용되어야 한다.

 

2) 호출 형태 : Header에 client Id와 secret을 보내야 한다.

curl "https://openapi.naver.com/v1/search/movie.xml?query=%EC%A3%BC%EC%8B%9D&display=10&start=1&genre=1" \
    -H "X-Naver-Client-Id: {애플리케이션 등록 시 발급받은 client id 값}" \
    -H "X-Naver-Client-Secret: {애플리케이션 등록 시 발급받은 client secret 값}" -v

 

3) id, secre은 내 어플리케이션에서 확인 가능하다.

 

4) 호출 url을 보면 query에 값을 입력하여 보내야 한다. 

 

5) 요청 변수를 가지고 쿼리 만들어야함.

  LinkedMultiValueMap<K , V>을 활용하여 queryParam만들기 쌉가능.

 

Rest Template

1. Rest Template란? Spring 3.0부터 지원, 간편하게 Rest방식 API를 호출할 수 있는 spring 내장 클래스 2. 사용 방법  1-1) uri 생성  (naverLocalSearchUri에 uri를 String으로 저장해둠) URI uri = UriCompo..

bsh-developer.tistory.com

@Data
@NoArgsConstructor
@AllArgsConstructor
@Slf4j
public class SearchMovieReq {


    private String query;
    private int display;
    private int start;
    private String genre;
    private String country;
    private int yearform;
    private int yearto;

    
    private MultiValueMap<String, String> makeQuery(){

        var multiValueMap = new LinkedMultiValueMap<String, String>();

        multiValueMap.add("query", query);
        multiValueMap.add("display", String.valueOf(display));
        multiValueMap.add("start", String.valueOf(start));
        multiValueMap.add("genre", genre);
        multiValueMap.add("country", country);
        multiValueMap.add("yearfrom", String.valueOf(yearform));
        multiValueMap.add("yearto", String.valueOf(yearto));
    
        
        return multiValueMap;

    }


}

 

3. RES


개발가이드를 확인하면 아래와 같이 출력결과를 확인이 가능하다.

변수명 타입 설명
rss - 디버그를 쉽게 하고 RSS 리더기만으로 이용할 수 있게 하기 위해 만든 RSS 포맷의 컨테이너이며 그 외의 특별한 의미는 없다.
channel - 검색 결과를 포함하는 컨테이너이다. 이 안에 있는 title, link, description 등의 항목은 참고용으로 무시해도 무방하다.
lastBuildDate datetime 검색 결과를 생성한 시간이다.
item/items - XML 포멧에서는 item 태그로, JSON 포멧에서는 items 속성으로 표현된다. 개별 검색 결과이며 title, link, image, subtitle, pubDate, director, actor, userRating을 포함한다.
title string 검색 결과 영화의 제목을 나타낸다. 제목에서 검색어와 일치하는 부분은 태그로 감싸져 있다.
link string 검색 결과 영화의 하이퍼텍스트 link를 나타낸다.
image string 검색 결과 영화의 썸네일 이미지의 URL이다. 이미지가 있는 경우만 나타난다.
subtitle string 검색 결과 영화의 영문 제목이다.
pubDate date 검색 결과 영화의 제작년도이다.
director string 검색 결과 영화의 감독이다.
actor string 검색 결과 영화의 출연 배우이다.
userRating integer 검색 결과 영화에 대한 유저들의 평점이다.

주의사항으로는 JSON의 경우 items에 title, link등이 포함된다.

 

따라서 Res class의 내부 class로 Item class를 별도로 선언이 필요하다.

 

@Data
@NoArgsConstructor
@AllArgsConstructor
@Slf4j
public class SearchMovieRes {

    private String lastBuildDate;

    private List<Item> items;


    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    private class Item{

        private String title;
        private String link;
        private String image;
        private String subtitle;
        private LocalDate pubDate;
        private String director;
        private String actor;
        private String userRating;

    }

}

 

 

4. NaverClinet class


 

Req, Res 객체 구성을 완료했다. 

 

이제 naver에 요청을 보내고 받는 NaverClinet class가 필요하다.

 

 NaverClient는 REQ를 보내고 RES를 받아오는 기능이 필요.

 

 해당 method는 REQ를 받아 RES를 return해야한다.

 

또한 HttpRquest를 보낼 때 NaverAPi에서 요구하는 url, header 구성이 필요하다.

 

RestTemplate를 이용하면 간단히 구성할 수 있다.

 

Rest Template

1. Rest Template란? Spring 3.0부터 지원, 간편하게 Rest방식 API를 호출할 수 있는 spring 내장 클래스 2. 사용 방법  1-1) uri 생성  (naverLocalSearchUri에 uri를 String으로 저장해둠) URI uri = UriCompo..

bsh-developer.tistory.com

 

1) GET method의 JSON형태 요쳥  URL

	https://openapi.naver.com/v1/search/movie.json

 

2) 호출 형태 : Header에 client Id와 secret을 보내야 한다.

curl "https://openapi.naver.com/v1/search/movie.xml?query=%EC%A3%BC%EC%8B%9D&display=10&start=1&genre=1" \
    -H "X-Naver-Client-Id: {애플리케이션 등록 시 발급받은 client id 값}" \
    -H "X-Naver-Client-Secret: {애플리케이션 등록 시 발급받은 client secret 값}" -v

 

 

3) Uri 생성 방법 : UriComponentBuilder사용

URI uri = UriComponentsBuilder.fromUriString("https://openapi.naver.com/v1/search/movie.json")
                .queryParams(searchMovieReq.makeQuery())
                .build()
                .encode()
                .toUri();

4) JSON형태 Header 생성 : HttpHeaders()

 //JSON형태 header생성
 var headers = new HttpHeaders();
 headers.set("X-Naver-Client-Id", "");
 headers.set("X-Naver-Client-Secret", "");
 headers.setContentType(MediaType.APPLICATION_JSON);

 

5) HttpEntity<T>(header)

var httpEntity = new HttpEntity<>(headers);

   HttpEntity란? HTTP 요청(Request) 또는 응답(Response)에 해당하는 HttpHeader와 HttpBody를 포함하는 클래스이다.

 

  

6) ResponseType : Response의 type을 설정

var responseType = new ParameterizedTypeReference<SearchMovieRes>(){};

 ParameterizedTypeReference<T> : The purpose of this class is to enable capturing and passing a generic Type.

  즉, ParameterizedTypeReference는 generic Type을 cpaturing하거나 passing하도록 하능 class이다.

 

 

7) Response Entity

  RestTemplate.exchange()를 통해 response를 받아올 수 있다.

  exchange안에 url, HttpMethod, requestEntity, reponse type 등을 넣어주면 된다.

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

 

흠 근데 reponseType을 직접 SearchMovieRes.class로 지정해도 작동한다...?

 

 

8) Return : 최종적으로 우리가 원하는 reponse는 reponseEntity의 body에 있다.

 

9) @Component적용이 필요하다. 

   @Component : 싱글톤 빈을 생성 , 해당 annotation 적용된 class는 bean으로 등록됨.

    bean을 사용하는 이유 : 자주 사용하는 객체를 싱글톤으로 만들어 놓고, 어디서는 불러쓸 수 있도록 하기위해.

  

5. ApiController


   @GetMapping("/search")
    public SearchMovieRes movieSearch(@RequestParam String query){

        SearchMovieReq searchMovieReq = new SearchMovieReq();
        searchMovieReq.setQuery(query);

        var result = naverClient.searchMovie(searchMovieReq);

        return result;
    }

 

Swagger를 활용하여 get method를 실행해보자.

 

두근두근

 

내부 시스템 에러가 발생했다..?

앗....

 

에러코드 SE99는 서버 내부에러라고 한다..아.............................................................................

흠....어쩌지..?ㅋㅋㅋㅋㅋ 다른거부터 하자..

 

 

6. applicatio.yml 추가 설정


api url, id, secre을 코드에 String으로 직접 입력하지 말고,

 

application.yml에 입력 후 불러와서 사용해보자.

 

<application.yml>

naver:
  url:
    search:
      movie: https://openapi.naver.com/v1/search/movie.json

  client:
    id: BIw2f7RuMel8TY4qU5HZ
    secret:

 

다음과 같이 @Value를 통해 application.yml의 값을 쉽게 가져올 수 있다.

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

@Value("${naver.clinet.secre}")
private String naverClientSecre;

@Value("${naver.url.search.movie}")
private String naverMovieSearchUrl;

 

7. GitHub : 210713, Naver API


 

bsh6463/MovieManager

Contribute to bsh6463/MovieManager development by creating an account on GitHub.

github.com

 

Comments