2021-03-18 11:39:29

오늘은 카카오 책 검색 API를 이용해서 도서 검색 웹 페이지를 구현해보겠습니다. 저는 책 제목을 검색하면, 정확도순으로 10개의 검색결과가 출력되고, 스크롤을 내려서 문서의 끝에 다다르면 추가로 10개의 검색결과가 하단에 붙는 그런 형식의 웹 페이지를 만들어 보겠습니다.

 

무한 스크롤 알고리즘

jQuery를 사용한다면, 제가 생각하는 무한 스크롤 기능의 알고리즘은 다음과 같습니다. 

 

1) 우선 화면에 보여질 데이터(예를 들어, 1-10행)를 서버로부터 AJAX 통신으로 비동기로 요청하여 가져옵니다.

2) 데이터를 표출하기 위해 준비한 html 요소(A라고 하겠습니다)에 데이터(1-10행)를 넣어줍니다. 

3) 스크롤을 내리다가 문서의 끝에 다다르면 추가로 보여줄 데이터(11-20행)를 서버로부터 AJAX 통신으로 비동기로 요청하여 가져옵니다. 

4) 서버에서 새롭게 가져온 데이터(11-20행)를 기존에 표출되고 있는 데이터(1-10행) 아래에 append 메소드를 활용하여 붙여줍니다. 그러면 요소 A 안에 1-20행의 데이터가 포함되어 있을 것이고 사용자들에게 보일 것입니다. 

5) 스크롤을 아래로 내려서 문서의 끝에 다다르면 절차 3), 4)가 반복 실행되게 합니다. 데이터가 추가되면서 스크롤을 계속 내릴 수 있는 상황이 되기 때문에 무한 스크롤이라고 불리는 것 같습니다. 

 

이 때 중요한 것은 데이터를 요청할 때 pageNum와 같은 변수를 넘겨줘서 요청할 데이터의 범위를 지정을 해줘야 합니다. 그래야 1-10행을 DB에서 조회하면 되는지, 11-20행을 DB에서 조회하면 되는지, 21-30행을 DB에서 조회하면 되는지를 결정할 수 있기 때문입니다. API 서버로부터 데이터를 받아와야 하는 경우에도 마찬가지입니다. 

 

무한 스크롤에 대한 고찰

무한 스크롤은 사용자에게 편리함은 줄 수 있지만, 서버에 입장에서는 부담스러운 알고리즘이라고 생각을 합니다. 인스타그램과 같은 앱에서는 안 사용할 수 없겠지만, 꼭 필요한 경우가 아니라면 무한 스크롤 대신에 "더보기" 버튼을 하단에 두어 그 버튼을 클릭할 때마다 데이터가 추가 되게 하는 것이 훨씬 서버에 부하를 줄이는 일이라고 생각합니다.

 

만약 무한 스크롤을 꼭 사용하고 싶다면, 무한 스크롤로 데이터를 추가하는 것에는 횟수 제한을 두고(예를 들어 5페이지까지만 스크롤링으로 데이터 추가되게 함), 몇 차례 스크롤링으로 데이터가 추가된 이후에는 더보기 버튼을 클릭해야 데이터가 추가되는 형태로 알고리즘을 설계하는 것이 낫지 않나 싶습니다. 사용자 편의라는 이슈와 개발적 편의라는 이슈 사이에 트레이드오프(tradeoff)가 있을 텐데 균형을 잘 맞추는 것이 중요하다고 생각합니다. 

 

코드 공유

카카오 책 검색 API 이용 무한 스크롤 도서 검색 웹 페이지에 관한 html 코드는 다음과 같습니다. 핵심 코드만 보여드리기 위해서 CSS를 이용해서 웹페이지를 꾸미지는 않았습니다. 

 

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<!DOCTYPE html>
<html lang="ko">
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>책 검색 사이트</title>
</head>
 
<body>
 
    <input type="text" id="query">
    <button id="search">검색</button>
 
    <div></div>
 
    <script src="https://code.jquery.com/jquery-3.6.0.js"
        integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
 
    <script>
        $(document).ready(function () {
            var pageNum = 1;
 
            $("#search").click(function () {
                $("div").html("");
 
                $.ajax({
                    method: "GET",
                    url: "https://dapi.kakao.com/v3/search/book?target=title",
                    data: { query: $("#query").val(), page: pageNum},
                    headers: {Authorization: "KakaoAK ########"// ########부분에 본인의 REST API 키를 넣어주세요.
 
                })
                .done(function (msg) {
                    console.log(msg);
                    for (var i = 0; i < 10; i++){
                        $("div").append("<h2><a href='"+ msg.documents[i].url +"'>" + msg.documents[i].title + "</a></h2>");
                        $("div").append("<strong>저자:</strong> " + msg.documents[i].authors + "<br>");
                        $("div").append("<strong>출판사:</strong> " + msg.documents[i].publisher + "<br>");
                        $("div").append("<strong>요약:</strong> " + msg.documents[i].contents + "...<br>");
                        $("div").append("<img src='" + msg.documents[i].thumbnail + "'/><br>");
                    }
                });
            })
 
            $(window).scroll(function(){  
 
                if ( Math.ceil($(window).scrollTop()) + $(window).height() >= $(document).height() ){
                    pageNum++;
 
 
                    $.ajax({
                        method: "GET",
                        url: "https://dapi.kakao.com/v3/search/book?target=title",
                        data: { query: $("#query").val(),  page: pageNum},
                        headers: {Authorization: "KakaoAK ########"// ########부분에 본인의 REST API 키를 넣어주세요.
 
                    })
                    .done(function (msg) {
                        console.log(msg);
                        for (var i = 0; i < 10; i++){
                            $("div").append("<h2><a href='"+ msg.documents[i].url +"'>" + msg.documents[i].title + "</a></h2>");
                            $("div").append("<strong>저자:</strong> " + msg.documents[i].authors + "<br>");
                            $("div").append("<strong>출판사:</strong> " + msg.documents[i].publisher + "<br>");
                            $("div").append("<strong>요약:</strong> " + msg.documents[i].contents + "...<br>");
                            $("div").append("<img src='" + msg.documents[i].thumbnail + "'/><br>");
                        }
                    });
 
                }
                
            });
        })
 
        
    </script>
</body>
 
</html>
cs

 

위 코드를 그대로 복사해서 붙여넣으시면 실행이 제대로 안 될 것입니다. 실행이 되게 하려면 REST API KEY가 필요합니다. 카카오 앱 키의 REST API KEY를 얻는 방법은 다음과 같습니다.  

 

developers.kakao.com/에 들어가셔서 로그인하신 후에 [내 애플리케이션]을 클릭합니다.

 

 

그 다음에 [애플리케이션 추가하기]를 누르신 후, 앱 이름과 사업자명에 각각 테스트라고 기입합니다. 다른 이름을 기입하셔도 좋습니다. 

 

저장을 클릭하시고 생성된 테스트라는 앱을 클릭하시면 다음과 같은 화면이 뜰 것입니다. 

 

 

이 중에서 REST API 키를 복사하셔서 위 코드에서 ######## 부분을 대체해줍니다. 주석이 딸려 있는 두 군데를 바꿔주셔야 합니다. 그 다음에 웹페이지를 열어보면, 우리가 만든 책 검색 웹페이지가 제대로 작동할 것입니다. 

 

 

보시는 것처럼 스크롤이 문서의 끝에 도달하면, 추가되는 것을 확인하실 수 있습니다. 그리고 다시 검색을 하면, 이전 기록이 지워지고 새로운 검색 결과가 보여집니다. 

 

참고자료

[1] www.youtube.com/watch?v=QPEUU89AOg8&t=34s, 조코딩, "[JavaScript 기초와 활용 #2] API의 개념과 활용! 카카오 책 검색 기능 구현하기" 

[2] api.jquery.com/jquery.ajax/, jquery, "jquery.ajax()"