Backend/Flask

Flask 기초 - REST API (1) (create, read)

yxemsy 2022. 2. 23. 01:17

1) REST API

REST는 자원을 이름으로 구분하여 해당 자원의 상태를 주고받는 모든 것을 의미한다.

REST 서버는 API 제공, 클라이언트는 사용자 인증 등을 직접 관리하는 구조로 각각의 역할이 확실히 구분되기 때문에 클라이언트와 서버에서 개발해야 할 내용이 명확해지고 서로 의존성이 줄어들게 된다

 

  • 자원: URI에 표현 되어야 한다. → 무엇을 서버에 요청할 것인지  ex) /book/1
  • 행위: HTTP 메소드 → 어떤 방법으로 요청할 것인지
  • 표현: API만 보고 무엇을 요청할지 알 수 있도록

 

*정리하자면*

URI에 어떤 데이터를 요청하는지 표현이 되어야하고,

그 데이터에 대해 어떤 동작을 할 것인지를 HTTP Method들로 표현을 해야하는데

Mehtod에는 GET, POST, PUT, DELETE가 있는 것이다.

 

 

- 자원에 대한 어떤 동작이 불가능 하면 각 상황에 맞는 상태 코드를 반환해줄 수 있다.

HTTP 응답 상태 코드에는 다음과 같은 것들이 있다.

200 정상적으로 수행
201 성공적으로 리소스 생성
400 클라이언트의 요청이 부적절
401 인증되지 않은 상태에서 리소스 요청
404 응답 불가능한 리소스, 없는 리소스 요청
500 서버 문제

 


2) Flask를 사용한 REST API 형태 웹 애플리케이션 간단한 개발 예제

REST API 형태의 서버를 개발할 때는 서버에서 직접 HTML 파일을 렌더링 하면서 페이지를 보여주는 것이 아니라, 웹 페이지를 구성하는 데 필요한 정보만 반환해주도록 구현해야한다.

 

(1) CREATE

- 게시판에 글을 생성하는 행위를 구현한다. name과 context가 글을 이룬다.

from flask import Flask, render_template, request, redirect, url_for, jsonify
import json


app = Flask(__name__)

board = []

@app.route('/')
def index():
    return render_template('Board.html', rows = board)

@app.route('/board', methods = ['GET','POST'])
def create():
    # name과 context를 board 리스트에 추가
    if request.method == 'POST':
        board.append([request.form['name'], request.form['context']])
        # 성공했을 시 index API 실행
        return redirect(url_for('index')) 
    else:
    	# 만약 POST가 아니라 GET 작업일 때에는 json형태의 다음과 같은 데이터를 반환하도록
        return jsonify({"status":200, "result":{"Id": len(board)}})
        # 새로 생성된 글의 id는 board의 길이값을 갖는다.
    
if __name__ == '__main__':
    app.run(debug=True)

메소드가 POST, GET일 때로 나누어 if, else 문으로 각각 다르게 처리해주었다.

request.form은 이전 포스팅에서도 다루었지만 html파일의 form 태그에서 받아오는 값이다.

 

화면은 이렇게 구성되어 있다. 이름과 내용을 입력받으면 각각 name과 context 값으로 넘어가서 성공적으로 등록되면,

redirect를 통해 목록에 새 글이 추가된 화면이 나온다.

 


 

(2) READ

- 글이 정상적으로 GET되었을 때 json형식으로 상태코드와 등록된 데이터가 반환되게 구현한다.

위의 CREATE()가 POST, GET을 같이 처리한 것과 달리 각각 따로 처리해본다.

@app.route('/')
def index():
    return render_template('Board.html', rows = board)

@app.route('/board', methods = ['POST'])
def create():
    board.append([request.form['name'], request.form['context']])
    
    return redirect(url_for('index'))


@app.route('/board', methods = ['GET'])
def read():
    return jsonify({"status":200, "result":board})

어떤 글을 생성했을 때, 그 글이 정상적으로 GET이 가능하다면 jsonify를 사용해 json 형식으로 데이터를 출력해준다.

 

이런 이름과 내용의 글을 등록하고서 /board URL로 get요청을 하면

이렇게 result로 board의 내용과  status로 200이 반환된다.


*참고용 HTML 파일코드*

<!doctype html>
<html lang="ko">
    <head>
        <meta charset="UTF-8">
        <meta name="Generator" content="EditPlus®">
        <meta name="Author" content="">
        <meta name="Keywords" content="">
        <meta name="Description" content="">
        <title>게시판 등록</title>
        <style type="text/css">
            body{ text-align: center; }
        </style>
     </head>
    <body>
        <h1>게시판</h1>
        <h4>추가</h4>
        <form action = "/board" method = "POST">
            이름<br>
            <input type = "text" name = "name" /><br>
            내용<br>    
            <textarea name = "context" cols="50" rows="10"></textarea><br><br>
            <input type = "submit" value = "게 시" /><br>
        </form>
        <h4>목록보기</h4>
        <table class="table" border="1" width = 600 style = "word-break:break-all" style="table-layout: fixed" align="center">
        <thread>
            <th width="4%">목차</th>
            <th width="15%">이름</th>
            <th width="25%">내용</th>
        </thread>
        {% for row in rows %}
        <tr>
            <td>{{ loop.index }}</td>
            <td>{{ row[0] }}</td>
            <td>{{ row[1] }}</td>
        </tr>
        {% endfor %}
        </table>
    </body>
</html>

 

다음 포스팅에 이어서..

 

강의와 코드 참고: 엘리스 AI트랙