[Python + Flask ] 스파르타 코딩 4주 차 7번째 수업

안영우·2020년 10월 23일
0

✏️ 서론

저번시간에는 Flask Server를 활용하여 APIClientaJax통신을 해보는 기본적인 실험을 해봤다.
여기서 핵심적인 내용은 정해진API를 만들고 사용하는 내용이다.
API를 만드는 순서는 다음과 같다.

1. 서버부터 만들기
   * `Client`와 통신하는 API 규약 만들기 ➡️ `POST` 방식
   * `pymongo`패키지를 이용하여 `DB`에서 리뷰 정보를 모두 가져오기
   * 성공 여부와 리뷰 목록 반환하기
   * DB에 리뷰정보를 조회(Read)하고, 성공 메시지와 리뷰정보를 응답 데이터로 보냄
   
2. 클라이언트 만들기
   * 리뷰를 작성하기 위해 필요한 정보(제목 `title`, 저자 `author`,리뷰 `review`) 작성하기
   * 이후 리뷰 목록을 서버에 요청하기 ➡️ `GET` 방식
   * 요청 성공 여부 확인하기 ➡️ `GET` 방식
   * 요청 성공했을 때 리뷰를 올바르게 화면에 나타나기 ➡️ `GET` 방식
   
3. 서버와 클라이언트 통신 확인하기

프로젝트 API는 다음과 같다.

[리뷰 저장하기(CREATE)]
가. 요청 정보
  - 요청 URL = /review, 요청 방식 = `POST`
  - 요청 데이터 : 제목(title), 저자(author), 리뷰(review)
    * client 단에서 내용을 작성해야함.
    
나. `Flask, Server`의 제공 기능
  - `Client`에게 보낸 요청 데이터를 `DB`에 생성(CREATE)하고, 저장이 성공했다고 응답 데이터를 보냄
  
다. 응답 데이터 
  - `JSON 형식` 'result' = success, 'msg'='리뷰가 정상적으로 작성되었습니다.'
  
[리뷰 보여주기(Read)]
가. 요청 정보
  - 요청 URL = /review, 요청 방식 = `GET`
  - 요청 데이터 : 없음, `URL`에서 자료 조회가능
    
나. `Flask, Server`의 제공 기능
  - `DB`내 리뷰 정보를 조회(Read)하고, 성공 메시지와 리뷰 정보를 응답 데이터로 보냄
  
다. 응답 데이터 
  - `JSON 형식` 'result' = success, 'reviews' = DB 내 리뷰리스트

✏️ 본론

[ 모두의 책 리뷰 ] 프로젝트를 만들어 보자.
사용하는 패키지는 requests, flask, pymongo다.

자신이 읽은 책에 대해 제목, 저자, 리뷰(코멘트)를 작성하면 
지금까지 작성한DB들을 불러오는 기능이다.

💡 구현순서는 다음과 같다.

1. `제목, 저자, 리뷰`를 작성하고 `리뷰 작성하기` 버튼을 누른다.
2. `API`를 통해 `POST`방식으로 `Flask Server`에 해당내용을 `DB`로 저장한다.
3. `새로고침`을 하게되면 `DB`에 저장되어 있던 내용을 `GET`방식으로 불러온다.

(Flask) Server Code

from flask import Flask, render_template, jsonify, request
from pymongo import MongoClient

app = Flask(__name__)

client = MongoClient('localhost', 27017)
db = client.dbsparta

# HTML을 template시키는 코드
@app.route('/')
def home():
	return render_template('index.html')
    
# `POST`방식 `API`역할을 하는 코드
#  form.get('Client에서 보내야 하는 변수')
@app.route('/review', methods=['POST'])
def write_reveiew():
	title = request.form.get('title_get')
    	author = request.form.get('author_get')
        review = request.form.get('review_get')
    
# 해당 내용을 `db.prac_review`에 저장하는 코드
	reviews = {
    	'title': title,
        'author': author,
        'review': review
 	}
# `DB`에 정보 삽입하기
	db.prac_review.insert_one(reviews)
    
# `POST` 성공 여부 및 성공메시지 반환하기
# `Client`에서 리뷰를 작성하면 메세지를 받을 수 있다.
	return jsonify({'result': 'success', 'msg': '리뷰가 성공적으로 작성되었습니다.'})
    
# `GET`방식 `API`역할을 하는 코드
# `db`에서 전체 list를 불러온다.
@app.route('/review', methods=['GET'])
def read_reviews():
	reviews = list(db.prac_review.find({}, {'_id': False}))
    	print(reviews)
    	return jsonify({'result': 'success', 'msg': 'DB를 성공적으로 가져왔습니다.', 'reviews': reviews})
    
    if __name__ == '__main__':
    	app.run('0.0.0.0.', port=5002, debug=True)    

(HTML) Client Function Code

<script type="text/javascript">

    // 내용을 읽어오기 전에 새로고침하는 코드
    $(document).ready(function () {
        $("#reviews-box").html("");
        showReview();
    });

    function makeReview() {
        // 1. 제목, 저자, 리뷰 내용을 가져옵니다.
        let title = $(`#title`).val()
        let author = $(`#author`).val()
        let review = $(`#bookReview`).val()

        // 2. 제목, 저자, 리뷰 중 하나라도 입력하지 않았을 경우 alert를 띄웁니다.
        if (title == '') {
            alert('제목을 작성해주세요.')
            return;
        } else if (author == '') {
            alert('저자를 입력해주세요.')
            return;
        } else if (review == '') {
            alert('리뷰를 채워주세요.')
            return;
        }

        // 3. POST /review 에 저장을 요청합니다.
        // 이때 `msg`는 `Flask`에서 작성했음.
        $.ajax({
            type: "POST",
            url: "/review",
            data: {title_give: title, author_give: author, review_give: review},
            success: function (response) {
                if (response["result"] == "success") {
                    alert(response["msg"]);
                    window.location.reload();
                }
            }
        })
    }

    function showReview() {
        // 1. 리뷰 목록을 서버에 요청하기
        // 2. 요청 성공 여부 확인하기
        // 3. 요청 성공했을 때 리뷰를 올바르게 화면에 나타내기
        $.ajax({
            type: "GET",
            url: "/review",
            data: {},
            success: function (response) {
                if (response["result"] == "success") {
                    let reviews = response['reviews']
                    console.log(reviews)
                    for (let i = 0; i < reviews.length; i++) {
                        let book_reviews = reviews[i]
                        let {title, author, review} = book_reviews
                        let tempHtml = `
                                            <tr>
                                            <td>${title}</td>
                                            <td>${author}</td>
                                            <td>${review}</td>
                                            </tr>`
                        console.log(tempHtml)
                        $(`#reviews-box`).append(tempHtml)
                    }
                } else {
                    alert("리뷰를 받아오지 못했습니다");
                }
            }
        })
    }

    function validateLength(obj) {
        let content = $(obj).val();
        if (content.length > 140) {
            alert("리뷰는 140자까지 기록할 수 있습니다.");
            $(obj).val(content.substring(0, content.length - 1));
        }
    }
</script>     

실행결과는 다음과 같다.
1. 실행 전

2. 실행 후

3. DB내용


✏️ 결론

지금까지 [ 모두의 북리뷰 ] 실습 과정을 거쳤다.
초심자가 하기엔 복잡한 과정이라고 생각하지만, 원리만 알면 간단하게 해결 할 수 있었다.
결론적으로 Server API를 얼마나 핵심적으로 만드는지에 따라 결과가 달라진다고 생각했다.

그리고 POST 방식과 GET 방식을 어떤 상황에서 사용하는지 알면 여러방면으로 응용이 가능 할 것이다.

다음시간에는 [ 모두의 북리뷰 ] 와 원리는 비슷하지만 [ Crawling ] 기능을 더한 예제를 복습하고자 한다.

profile
YW_Tech

0개의 댓글