[프로젝트] 책 좋아요 페이지 - #2. API 만들기, 완성

예니·2020년 11월 1일
0

프로젝트

목록 보기
1/8

flask 서버, ajax, mongoDB 이용해서 책 좋아요 페이지 만들기

📅 기간 : 2020.10.29 ~ 30


📖 책 리스트 불러오기 (좋아요 순)

📌 서버

@app.route('/api/list', methods=['GET'])
def show_books():
    result = list(db.bookshop.find({},{'_id':0}).sort('like', -1))
    return jsonify({'result':'success','book_list':result})

list(db.bookshop.find({},{'_id':0}).sort('like', -1))
딕셔너리 형태를 like 키 기준으로 내림차순 정리함
list 안쪽에 sort가 있는거 조심!!


📌 클라이언트

function showBooks() {
            $('.book-list').empty();
            $.ajax({
                type: 'GET',
                url: '/api/list',
                data: {},
                success: function (response) {
                    if (response['result'] === 'success') {
                        let books = response['book_list'];

                        for (let i = 0; i < books.length; i++) {
                            let title = books[i]['title'];
                            let img = books[i]['img'];
                            let desc = books[i]['desc'];
                            let author = books[i]['author'];
                            let like = books[i]['like'];
                            let url = books[i]['url'];

                            makeCard(title, img, desc, author, like, url);
                        }
                    }
                }
            })
        }

showBooks() 함수는 $(function(){ showBooks()} ); 로 화면 로딩될 때마다 실행되도록 함
전달사항은 없으니 GET
정보를 서버로부터 받아서 필요한 정보들을 변수에 각각 저장하고 makeCard함수



📖 새 책 추가하기


추가박스를 열면 원하는 책을 추가할 수 있도록 만들었다.
단, yes24 홈페이지에서 책 상세페이지 링크를 넣어야 한다.
아직 이런 입력값들을 일반화시키는 부분은 공부를 못했다😂
차차 공부해나가야지!

📌 서버

@app.route('/api/list', methods=['POST'])
def post_book():
    url_receive = request.form['url_give']
    data = requests.get(url_receive)
    soup = BeautifulSoup(data.text, 'html.parser')

    target = soup.select_one('#yDetailTopWrap > div.topColLft > div.gd_imgArea > span > em > img')

    img_url = target['src']
    title = target['alt']
    author = soup.select_one('span.gd_auth > a:nth-child(1)')
    desc = soup.select_one('div.infoWrap_txtInner > textarea > b')
    rate = soup.select_one('#spanGdRating > a > em')

    if (desc == None) or (rate == None):
        return jsonify({'result': 'success', 'msg':'이 책은 추가할 수 없어요ㅠㅠ'})

    book = {
        'url': url_receive,
        'title': title,
        'img': img_url,
        'author': author.text,
        'desc': desc.text,
        'rate': rate.text,
        'like': 0,
    }

    db.bookshop.insert_one(book)
    return jsonify({'result': 'success', 'msg':'추가 완료!'})

유저가 입력한 url에서 필요한 정보 스크래핑

속성값 가져올때는 [''] 로, 태그 안의 값 가져올때는 .text 사용한다.

책마다 다른 건 다있어도 간혹 상세설명이나 평점이 없는 경우가 있는데 이럴 경우 None.text를 적용할 수 없다고 에러가 발생한다.
if (desc == None) or (rate == None): 로 예외처리해줬다.


📌 클라이언트

클라이언트는 그냥 input 값을 받아와서 전달해주고, 서버에서 성공하면
alert 띄워주고 새로고침해준다.



📖 책 좋아요, 별로에요


책마다 좋아요, 별로에요 버튼으로 순위를 설정할 수 있다.
좋아요 누르면 (좋아요: X) 숫자가 +1
별로에요 누르면 숫자가 -1 된다.
처음에는 (좋아요:X, 별로에요:X) 이렇게 따로 구상했었는데, 두개를 따로 순위매기는 것도 애매하기도해서 그냥 +,-로 바꿨다.
이게 더 깔끔하고 의미도 잘 전달되는 듯하다.

📌 서버

@app.route('/api/like', methods=['POST'])
def like_book():
    book_receive = request.form['book_give']
    book = db.bookshop.find_one({'title':book_receive},{'_id':0})
    new_like = book['like'] + 1
    db.bookshop.update_one({'title':book_receive}, {'$set':{'like':new_like}})
    return jsonify({'result': 'success', 'msg': '위로!'})

dislike는 다 똑같고 숫자만 -1, 메세지: 아래로! 인것만 다르다.

버튼 눌러진 책의 이름을 받아서 서버에서 해당 책을 찾는다.
+1 해준 숫자를 새로운 변수에 담아 update_one 으로 수정해준다.
이때, $set: 이 수정해줄 부분 앞에 붙는 것 주의하자

📌 클라이언트

onclick="likeBook('${title}')"
책 좋아요 버튼 누르면 작동하는 likeBook() 함수에 인자로 책 제목을 넘겨준다.

function likeBook(book)
전달된 인자를 매개변수로 받는다.

성공하면 메세지 띄우고, 새로고침한다.



🖐🏻 완성작

프론트는 부트스트랩 프레임워크 사용했다.
내가 처음에 기본으로 넣어둔 db는 책 40권이고, 여기에 계속 추가 가능하다.



🖐🏻 후기

처음에 API 만들기 시작했을 땐, 이걸 어떻게 설계하고 서버, 클라이언트 다 만들고하나.. 싶었는데 좀 하다보니 어느정도 머리에 정형화가 되가는 느낌이다.
그리고 확실히 그냥 공부하는 것보다는 미니 프로젝트하면서 맨땅에 헤딩하면서 공부하는 것이 훨씬 도움이 많이 된다.
구글 최고.. 없는게 없다.
프로그래밍은 정말 자기주도학습이 중요한 분야란 걸 계속 느낀다.
힘내쟈💪🏻

0개의 댓글