coding/JS

API / Ajax get / post DB 저장 및 출력

JIN_Coder 2022. 4. 29. 17:09

2022.04.29

 

간단하게 python flask로 로컬 서버를 열고

html에 데이터를 입력하면 post 요청으로 받아 db에 저장하고

db에 저장된 데이터들을 get요청으로 클라이언트에게 출력해 보여주는 기능

 

기본적인 API Ajax 코드

# GET 요청 API코드

@app.route('/test', methods=['GET'])
def test_get():
   title_receive = request.args.get('title_give')
   print(title_receive)
   return jsonify({'result':'success', 'msg': '이 요청은 GET!'})
   
   
# POST 요청 API코드

@app.route('/test', methods=['POST'])
def test_post():
   title_receive = request.form['title_give']
   print(title_receive)
   return jsonify({'result':'success', 'msg': '이 요청은 POST!'})

위는 app.py에 들어가 있는 서버 코드

 

// GET 요청 확인 Ajax코드

$.ajax({
    type: "GET",
    url: "/test?title_give=봄날은간다",
    data: {},
    success: function(response){
       console.log(response)
       alert(response['msg'])
    }
  })
  

// POST 요청 확인 Ajax코드
$.ajax({
    type: "POST",
    url: "/test",
    data: { title_give:'봄날은간다' },
    success: function(response){
       console.log(response)
       alert(response['msg'])
    }
  })

위는 index.html에 들어가있는 클라 코드

 

사용자가 get으로 요청하면 get으로 받고 post로 요청하면 post로 받는다

이때 /test로 받고 메소드는 get / post나누어서 사용됨

post로 예를 들면 title_give에 '봄날은간다'를 넣어서 data로 보내면

서버에서 request.args.get에 title_give를 받아서 title_receive에 담고

title_receive가 '봄날은간다' 이니까 '봄날은간다'를 출력하고

return에 json형식으로 'result' : 'success', 'msg': '이 요청은 POST!'을 담아서 클라한테 넘겨준다

그럼 클라에서 response으로 받아서 콘솔에 찍어 준다.

 

/ 내생각 : get은 post처럼 주는 데이터가 없지만 

url: "/test?title_give=봄날은간다", 처럼 ? 뒤에 조건을 붙여서 보낼수도 있다

 

예시 코드)

서버 app.py

from flask import Flask, render_template, request, jsonify

app = Flask(__name__)

from pymongo import MongoClient

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


@app.route('/')
def home():
    return render_template("index.html")


## API 역할을 하는 부분
@app.route('/review', methods=['POST'])
def write_review():
    title_receive = request.form['title_give']
    author_receive = request.form['author_give']
    review_receive = request.form['review_give']

    doc = {
        'title': title_receive,
        "author": author_receive,
        "review": review_receive
    }
    db.books.insert_one(doc)
    return jsonify({'msg': '저장 완료!'})


@app.route('/review', methods=['GET'])
def read_reviews():
    reviews = list(db.books.find({}, {'_id': False}))
    # sample_receive = request.args.get('sample_give')
    return jsonify({'all_reviews': reviews})


if __name__ == '__main__':
    app.run('0.0.0.0', port=5000, debug=True)

클라 index.html

<!DOCTYPE html>
<html lang="ko">

    <head>
        <!-- Webpage Title -->
        <title>모두의 책리뷰 | 스파르타코딩클럽</title>

        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

        <!-- Bootstrap CSS -->
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
              integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
              crossorigin="anonymous">

        <!-- JS -->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
                integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
                crossorigin="anonymous"></script>

        <!-- 구글폰트 -->
        <link href="https://fonts.googleapis.com/css?family=Do+Hyeon&display=swap" rel="stylesheet">

        <script type="text/javascript">

            $(document).ready(function () {
                showReview();
            });

            function makeReview() {
                let title = $("#title").val();
                let author = $("#author").val();
                let review = $("#bookReview").val();
                $.ajax({
                    type: "POST",
                    url: "/review",
                    data: {
                        title_give:title,
                        author_give:author,
                        review_give:review
                        },
                    success: function (response) {
                        alert(response["msg"]);
                        window.location.reload();
                    }
                })
            }

            function showReview() {
                $.ajax({
                    type: "GET",
                    url: "/review",
                    data: {},
                    success: function (response) {
                        let reviews = response["all_reviews"]
                        for (let i = 0; i < reviews.length; i++){
                            let title = reviews[i]["title"]
                            let author = reviews[i]["author"]
                            let review = reviews[i]["review"]
                            console.log(title, author, review)
                            let temp_html = `<tr>
                                                <td>${title}</td>
                                                <td>${author}</td>
                                                <td>${review}</td>
                                            </tr>`
                            $("#reviews-box").append(temp_html)
                        }


                        console.log((reviews))
                        // alert(response["msg"]);
                    }
                })
            }
        </script>

        <style type="text/css">
            * {
                font-family: "Do Hyeon", sans-serif;
            }

            h1,
            h5 {
                display: inline;
            }

            .info {
                margin-top: 20px;
                margin-bottom: 20px;
            }

            .review {
                text-align: center;
            }

            .reviews {
                margin-top: 100px;
            }
        </style>
    </head>

    <body>
        <div class="container">
            <img src="https://previews.123rf.com/images/maxxyustas/maxxyustas1511/maxxyustas151100002/47858355-education-concept-books-and-textbooks-on-the-bookshelf-3d.jpg"
                 class="img-fluid" alt="Responsive image">
            <div class="info">
                <h1>읽은 책에 대해 말씀해주세요.</h1>
                <p>다른 사람을 위해 리뷰를 남겨주세요! 다 같이 좋은 책을 읽는다면 다 함께 행복해질 수 있지 않을까요?</p>
                <div class="input-group mb-3">
                    <div class="input-group-prepend">
                        <span class="input-group-text">제목</span>
                    </div>
                    <input type="text" class="form-control" id="title">
                </div>
                <div class="input-group mb-3">
                    <div class="input-group-prepend">
                        <span class="input-group-text">저자</span>
                    </div>
                    <input type="text" class="form-control" id="author">
                </div>
                <div class="input-group mb-3">
                    <div class="input-group-prepend">
                        <span class="input-group-text">리뷰</span>
                    </div>
                    <textarea class="form-control" id="bookReview"
                              cols="30"
                              rows="5" placeholder="140자까지 입력할 수 있습니다."></textarea>
                </div>
                <div class="review">
                    <button onclick="makeReview()" type="button" class="btn btn-primary">리뷰 작성하기</button>
                </div>
            </div>
            <div class="reviews">
                <table class="table">
                    <thead>
                    <tr>
                        <th scope="col">제목</th>
                        <th scope="col">저자</th>
                        <th scope="col">리뷰</th>
                    </tr>
                    </thead>
                    <tbody id="reviews-box">
                    <tr>
                        <td>왕초보 8주 코딩</td>
                        <td>김르탄</td>
                        <td>역시 왕초보 코딩교육의 명가답군요. 따라하다보니 눈 깜짝할 사이에 8주가 지났습니다.</td>
                    </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </body>

</html>

 

보통 코드 작성 서순은 아래와 같다

1. 클라와 서버 확인하기

2. 서버 만들기

3. 클라 만들기

4. 완성 확인

 

1) 클라와 서버 확인

기본 골격 코드를 서버와 클라에 넣어주고 

요청 URL, 요청 방식 get / post, 제공 데이터 title_give 같은 것들을 확인

 

2) 서버 만들기

클라에게 받아야 할 데이터 확인(title, author, review)

디비 저장하기

성공 여부 & 성공메세지 반환

@app.route('/review', methods=['POST'])
def write_review():
    # title_receive로 클라이언트가 준 title 가져오기
    title_receive = request.form['title_give']
    # author_receive로 클라이언트가 준 author 가져오기
    author_receive = request.form['author_give']
    # review_receive로 클라이언트가 준 review 가져오기
    review_receive = request.form['review_give']

    # DB에 삽입할 review 만들기
    doc = {
        'title': title_receive,
        'author': author_receive,
        'review': review_receive
    }
    # reviews에 review 저장하기
    db.bookreview.insert_one(doc)
    # 성공 여부 & 성공 메시지 반환
    return jsonify({'msg': '리뷰가 성공적으로 작성되었습니다.'})
    
# get
@app.route('/review', methods=['GET'])
def read_reviews():
    # 1. DB에서 리뷰 정보 모두 가져오기
    reviews = list(db.bookreview.find({}, {'_id': False}))
    # 2. 성공 여부 & 리뷰 목록 반환하기
    return jsonify({'all_reviews': reviews})

 

3) 클라 만들기

- 서버에 줄 데이터 만들어 보내기(title_give, ..ect)

데이터를 만들때 jQuery를 이용해 input 값 가져오기,

_give에 input 값 넣기

- 서버로 받은 데이터(메세지) 띄우기

메세지 띄우거나,

temp_html로 틀 만들어서 화면에 추가해서 보여주기

function makeReview() {
    // 화면에 입력어 있는 제목, 저자, 리뷰 내용을 가져옵니다.
    let title = $("#title").val();
    let author = $("#author").val();
    let review = $("#bookReview").val();

    // POST /review 에 저장(Create)을 요청합니다.
    $.ajax({
        type: "POST",
        url: "/review",
        data: { title_give: title, author_give: author, review_give: review },
        success: function (response) {
            alert(response["msg"]);
            window.location.reload();
        }
    })
}

# get
function showReview() {
                $.ajax({
                    type: "GET",
                    url: "/review",
                    data: {},
                    success: function (response) {
                        let reviews = response['all_reviews']
                        for (let i = 0; i < reviews.length; i++) {
                            let title = reviews[i]['title']
                            let author = reviews[i]['author']
                            let review = reviews[i]['review']

                            let temp_html = `<tr>
                                                <td>${title}</td>
                                                <td>${author}</td>
                                                <td>${review}</td>
                                            </tr>`
                            $('#reviews-box').append(temp_html)
                        }
                    }
                })
            }

4) 완성 확인

직접 실행하면서 정상 작동 되는지 확인 및 수정

 

+=====+

2022.05.04

 

api에서 get요청 받을때 url잘 보고

랜더 템플릿 하는 url와 똑같지 않게 조심 이것도 데이터를 따로 안받으니까

get 처럼 충돌 일어나는 듯

get url를 다르게 해주니까 디비 find 잘함

 

 

 

'coding > JS' 카테고리의 다른 글

네이버 지도 API 사용  (0) 2022.05.02
함수 실행 후 새로고침  (0) 2022.04.30
자동실행 함수 $(document).ready()  (0) 2022.04.28
Ajax  (0) 2022.04.28
문자열에서 특정 문자열 찾기 search()  (0) 2022.04.28