(4-1) Flask

Yongjoo Lee·2020년 12월 21일
0
post-thumbnail

Flask

![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2F1854d995-7e32-413e-b8a9-1c033c245507%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2F1854d995-7e32-413e-b8a9-1c033c245507%2Fimage.png)

Python 기반 마이크로 웹 프레임워크

Flask 시작

가상환경 구축하기

python -m venv venv

.\venv\Scripts\activate

Flask 설치하기

pip install flask

아주 간단한 flask app

인터넷과 웹

  • 인터넷(Internet) : 전 세계 컴퓨터를 하나로 합치는 거대한 통신망
    • 인터넷에는 웹, 메일 등이 존재함
  • 웹(Web) : 인터넷에 연결된 사용자들이 정보를 공유할 수 있는 공간
    • 웹페이지 : 웹에 있는 정보
    • 웹사이트 : 웹페이지의 집합

Web의 동작 방식

  • 일반적인 웹 사용하는 방식
    1. 웹 브라우저 실행
    2. 주소창에 주소를 입력하고 Enter

👇

  1. Client가 Server에 정보를 요청
  2. Server는 요청받은 정보에 대한 처리 를 진행
  3. Server가 Client에게 처리 결과를 응답

💡 Client와 Server는 HTTP 프로토콜 방식으로 통신한다!

📌

  • API : 프로그램들이 서로 상호작용하는 것을 도와주는 매개체
  • REST (Representational State Transfer) : 웹 서버가 요청을 응답하는 방법론 중 하나,
    데이터가 아닌 자원(Resource)의 관점으로 접근

REST API

  • HTTP URI 를 통해 자원을 명시하고
  • HTTP Method 를 통해 해당 자원에 대한 CRUD를 진행

URI ( Uniform Resource Identifier, 통합 자원 식별자 ) : 인터넷에 있는 자원을 나타내는 유일한 주소

HTTP Method : 자원에 대한 행위를 나타내는 수단 ( GET, POST, PUT, PATCH, DELETE 등이 있음 )

예시 # 1 REST API

![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2Fd29e10d2-bbe2-4b6d-9047-e0ebd8941f12%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2Fd29e10d2-bbe2-4b6d-9047-e0ebd8941f12%2Fimage.png)

👉 자원(Resource) 은 모두 /order 으로 이어도 HTTP Method에 따라서 행위가 달라짐.

🔥 REST API의 Stateless (상태 비보존형)

  • Client의 Context를 서버에서 유지하지 않는다.

예시 # 2 REST API Stateless

  • POST /shoes 는 자원에 새로운 정보를 생성
  • GET /shoes 는 DB에서 shoes가 있는지 확인 후 해당 자원 반환

👉 (서버 입장에서) 아이템을 GET 하기 위해서 POST를 진행할 필요가 없음

REST API 구축해보기

Coffee Shop Menu API 구축

같은 자원(Menu)에 대해서 다른 로직을 구현

  • GET
  • POST
    • @app.route('/menus', method=['POST'])
      • methods의 기본값은 'GET'
      • methods는 리스트형으로써 여러 메소드를 지정할 수 있다.
from flask import Flask, jsonify, request

app = Flask(__name__)

menus = [
    {"id": 1, "name": "Espresso", "price": 3800},
    {"id": 2, "name": "Americano", "price": 4100},
    {"id": 3, "name": "CafeLatte", "price": 4600},
]

@app.route('/')
def hello_flask():
    return "Hello World!"

# GET /menus    | 자료를 가지고 온다.
@app.route('/menus')
def get_menus():
    return jsonify({"menus": menus})

# POST /menus   | 자료를 자원에 추가한다.
@app.route('/menus', methods=['POST'])
def create_menus():  # request가 JSON이라고 가정
    # 전달받은 자료를 menus 자원에 추가
    request_data = request.get_json()  # {"id": ..., "name": ..., "price": ...},
    new_menu = {
        "id": 4,
        "name": request_data['name'],
        "price": request_data['price'],
    }
    menus.append(new_menu)
    return jsonify(new_menu)

if __name__ == "__main__":
    app.run()

API 테스트

Postman을 통해 API 테스트 진행

  1. GET menus/

    ![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2Fb8a4c019-028e-4000-836e-aaf616679d1b%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2Fb8a4c019-028e-4000-836e-aaf616679d1b%2Fimage.png)

  2. POST menus/

    ![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2F4850ac39-e797-47d0-8a37-672540de72ac%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2F4850ac39-e797-47d0-8a37-672540de72ac%2Fimage.png)

  3. GET menus/

    ![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2Fed7b8b03-e6c8-4531-9cd3-d47bd5fbc087%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2Fed7b8b03-e6c8-4531-9cd3-d47bd5fbc087%2Fimage.png)

🏃‍♂️필수 과제: 메뉴 관리 CRUD 구현하기

  • HTTP 메서드 PUT 를 이용해 Update, DELETE 를 이용해 Delete 기능을 구현해주세요.
  • PUT /menu/<int:id> : 해당하는 id에 해당하는 데이터를 갱신합니다. (HTTPRequest의 Body에 갱신할 내용이 json으로 전달됩니다.)
  • DELETE /menu/<int:id> : 해당하는 id에 해당하는 데이터를 삭제합니다.
  • @app.route() 의 인자로 들어가는 경로에는 다음과 같이 사용해줄 수도 있습니다.
  1. PUT /menu/<int:id> 구현

    # PUT /menus/<int:id>   | 자료를 자원에서 수정한다.
    @app.route('/menus/<int:menu_id>', methods=['PUT'])
    def update_menus(menu_id):
        request_data = request.get_json()
    
        for menu in menus:
            if menu['id'] == menu_id:
                menu['name'] = request_data['name']
                menu['price'] = request_data['price']
                return jsonify(menu)
        return jsonify({'error_msg': "해당 자료가 존재하지 않습니다!"})

    ![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2F0e208fee-8b62-4b4c-b92c-a4b1377cdfc5%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2F0e208fee-8b62-4b4c-b92c-a4b1377cdfc5%2Fimage.png)

    ![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2F1bc6ce4d-2934-46f4-9fad-bd94bf03ee08%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2F1bc6ce4d-2934-46f4-9fad-bd94bf03ee08%2Fimage.png)

    ![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2F1a8f1460-8f1f-48a4-8f55-d21b0b58b31f%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2F1a8f1460-8f1f-48a4-8f55-d21b0b58b31f%2Fimage.png)

  2. DELETE /menu/<int:id> 구현

    # DELETE /menus/<int:id>   | 자료를 자원에서 삭제한다.
    @app.route('/menus/<int:menu_id>', methods=['DELETE'])
    def delete_menus(menu_id):
        request_data = request.get_json()
    
        for i, menu in enumerate(menus):
            if menu['id'] == menu_id:
                return jsonify(menus.pop(i))
        return jsonify({'error_msg': "해당 자료가 존재하지 않습니다!"})

    ![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2F85615195-c7ff-4892-9a67-a512c97f9ca9%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2F85615195-c7ff-4892-9a67-a512c97f9ca9%2Fimage.png)

    ![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2Fc289241c-f9c3-4a9c-926f-51609c387c0a%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2Fc289241c-f9c3-4a9c-926f-51609c387c0a%2Fimage.png)

    ![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2F7422d45c-f000-4f95-af49-2f21f7d94524%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2F7422d45c-f000-4f95-af49-2f21f7d94524%2Fimage.png)

🏃‍♂️보너스 과제 1: ID야 움직여라 얍1

  • 새로운 menu를 추가하는 POST 영역에서 id가 4로 고정되어있는 문제가 발생합니다.
  • POST 요청이 들어올 때마다 id가 하나씩 증가하여 menu 리스트에 추가될 수 있도록 코드를 수정해주세요.
  • 이 과제는 필수 과제 이후에 진행되어야 합니다.
next_id = len(menus) + 1

...

@app.route('/menus', methods=['POST'])
def create_menus():
    global next_id                                          # 수정

    request_data = request.get_json()

    new_menu = {
        "id": next_id,                                      # 수정
        "name": request_data['name'],
        "price": request_data['price'],
    }
    menus.append(new_menu)
    next_id += 1                                            # 수정
    return jsonify(new_menu)

![https://velog.velcdn.com/images%2Fleeyongjoo%2Fpost%2Ffebb0ce0-9886-4c33-9597-27d9a8ffa73c%2Fimage.png%5D(https%3A%2F%2Fimages.velog.io%2Fimages%2Fleeyongjoo%2Fpost%2Ffebb0ce0-9886-4c33-9597-27d9a8ffa73c%2Fimage.png)

profile
하나씩 정리하는 개발공부로그입니다.

0개의 댓글