2025/09/23 Flask-2

김기훈·2025년 9월 23일

TIL

목록 보기
24/191

REST API

자원(Resource, 데이터) 중심으로 설계되며, HTTP 프로토콜의 메소드(GET, POST, PUT, DELETE 등)를 사용하여 해당 자원에 대한 CRUD(Create, Read, Update, Delete) 작업을 수행

  • GET (자원 읽기), POST (자원 생성), PUT (자원 업데이트), DELETE (자원 삭제).

REST API의 핵심 원칙

    1. 자원 기반의 URL
    • 데이터베이스의 레코드, 문서, 이미지 등 인터넷에서 접근 가능한 모든 것을 "자원"
    • 사용자 정보를 나타내는 자원이 존재한다면,
      • 이 자원은 일반적으로 /users라는 URL로 표현
      • 특정 사용자를 나타내려면, /users/123과 같이 고유 식별자(ID)를 URL에 추가
    1. 상태 없음 (Statelessness)
    • 서버가 클라이언트의 상태(예: 로그인 상태, 이전 페이지 기록 등)를 기억하지 않는 것을 의미
    • 각 요청은 독립적이며, 필요한 모든 정보(예: 사용자 인증 정보)를 포함해야 함
      • 독립적인 요청: 각 API 요청은 다른 요청과 독립적으로 처리 , 이전의 요청 정보 기억X
      • 서버의 상태 저장 없음: 이전 행동에 관한 정보를 저장X
      • 세션 관리의 부재: 세션 상태(예: 로그인 상태, 이전 작업 등)를 기억하거나 관리X
    1. 표준화된 메소드 사용
    • GET: 자원을 조회합니다. 예를 들어, /users로 GET 요청을 보내면 사용자 목록을 가져옵니다.
    • POST: 새로운 자원을 생성합니다. 예를 들어, /users에 POST 요청을 보내면 새 사용자를 만듭니다.
    • PUT: 기존 자원을 업데이트합니다.
    • DELETE: 자원을 삭제합니다.
    1. 통신을 위한 표현 (Representation)
    • 클라이언트와 서버 간에 데이터를 주고받을 때, 특정 형식을 사용
      • JSON 형식은 REST API에서 매우 일반적으로 사용되는 데이터 표현 방식

Jsonify

JSON : 컴퓨터 간 상호작용을 할 때 주로 사용하는 형식{key:value} 형태로 이루어진 데이터 포맷

  • Python 데이터를 JSON 형식으로 변환하여 HTTP 응답으로 반환하는 간편한 방법을 제공
    • Python의 기본 데이터 타입(딕셔너리, 리스트 등)을 JSON 문자열로 변환
      • 리스트나 객체의 형태 반환은 자동 변환이 안되기 때문에 jsonify 사용

  • body
    • id=1, name=kim, age=25 값을 보냈음.
    • 그런데 GET 요청은 원래 body를 안 읽고 URL의 쿼리스트링으로 데이터를 주는 게 일반적
    • 지금은 Flask 코드에서 body 데이터를 사용하지 않고 있기 때문에, 저 값들이 무시

Json 응답

  • return 에 딕셔너리 형태로 반환하면 됨
    • return {"message":"Hello"}
    • return jsonify(message="Hello") 이걸 권장

HTTP 메서드 (GET/POST 등)

  • GET
    • 데이터를 가져올 때 사용
    • 주소창에 입력하거나 링크 클릭 시 자동으로 GET 요청
    • 예: GET /user/1 → “id=1인 사용자 정보 달라”
  • POST
    • 데이터를 서버에 보낼 때 사용
    • 보통 폼 제출, 로그인, 회원가입에 쓰임
    • 예: POST /user + {name:"홍길동"} → “홍길동이라는 사용자 추가해줘”
  • (참고) 그 외 PUT, DELETE도 있음 → REST API에서 CRUD(Create, Read, Update, Delete) 동작 표현할 때 사용
from flask import Flask, request

app = Flask(__name__)

# GET 요청 예시
@app.route("/hello", methods=["GET"])
def hello():
    return "안녕하세요!"

# POST 요청 예시
@app.route("/submit", methods=["POST"])
def submit():
    data = request.form["name"]  # 사용자가 보낸 데이터 읽기
    return f"{data}님, 접수 완료!"


/hello : 주소를 브라우저에 치면 바로 응답 (GET)
/submit : 폼 전송 같은 걸로 요청해야 동작 (POST)

Swagger

from flask import Flask, jsonify

from flasgger import Swagger

app = Flask(__name__)
swagger = Swagger(app) # Swagger 세팅
# http://127.0.0.1:5000/apidocs

@app.route('/hello')
def hello():
    """
    Hello API
    ---
    responses:
      200:
        description: 성공 응답
        schema:
          type: object
          properties:
            message:
              type: string
              example: "Hello, OZ BE14!"
    """

    return jsonify(message="Hello, World!")

if __name__ == '__main__':
    app.run(debug=True)
  • 200 응답에 {"message": "Hello, World!"} 반환
  • docstring 안의 YAML 구조에서 들여쓰기가 굉장히 중요


from flask import Flask, request, jsonify

app = Flask(__name__)

todos = {
    1: "flask 공부하기",
    2: "파이썬 공부하기",
}

# 1. 전체 목록 조회: GET
@app.route("/todos", methods=['GET'])
def get_todos():
    return jsonify(todos)


# 2. 특정 항목 조회: GET
@app.route("/todos/<int:todo_id>", methods=["GET"])
def get_todo(todo_id):
    task = todos.get(todo_id)
    if not task:
        return jsonify({"error" : "할 일이 없습니다."}), 404 # 404(not found) : 클래스이름
    return jsonify({todo_id: task})

if __name__ == '__main__':
    app.run(debug=True)


HTTP 메서드 (GET, POST, PUT, DELETE)

  • 서버에 어떤 행동을 하고 싶은지를 표시하는 약속
                                from flask import Flask, request

                                app = Flask(__name__)

# 가상의 데이터 (DB 대신 리스트 사용)
                                orders = [
                                    {"id": 1, "item": "불고기버거"},
                                    {"id": 2, "item": "치즈버거"}
                                ]

GET


POST


PUT


DELETE

  • HTTP 요청은 크게 Header + Body로 나뉘는데
    • Header: 요청 정보 (예: "나는 JSON 보낼 거야")
    • Body: 실제 데이터 내용 (예: {"item": "새우버거"})
      • 브라우저 주소창은 Header까지만 다루고, Body를 직접 넣을 수 없다.
        • 그래서 Postman 같은 툴이나 curl, 또는 프론트엔드 코드에서 Body를 작성해야 함

request

  • GET → request.args (URL 파라미터)
  • POST/PUT → request.json (Body) 또는 request.form (폼 데이터)
from flask import Flask, request

app = Flask(__name__)

@app.route("/example", methods=["GET", "POST"])
def example():
    if request.method == "GET":
        # URL 뒤에 ?name=홍길동
        name = request.args.get("name")
        return {"message": f"Hello {name}!"}
    
    if request.method == "POST":
        # Body JSON: {"item": "치즈버거"}
        data = request.json
        return {"received_item": data["item"]}
  • GET /example?name=홍길동 → 응답: {"message": "Hello 홍길동!"}
  • POST /example + Body {"item":"치즈버거"} → 응답: {"received_item":"치즈버거"}

클래스 기반으로 api를 작성했을때의 장점

    1. 관리 깔끔
    1. 상속이나 공통메서드로 사용하여 코드 재사용성이 좋아짐
    1. 유지보수에 유리
    1. 확장성이 높음
    • 자동 문서화(Swagger), 에러 처리, 데이터 검증 같은 기능을 쉽게 붙일 수 있음.

블루프린트 장점

  • Flask에서 코드를 모듈화(분리)하는 도구
    • 쉽게 말하자면, Flask 프로젝트를 기능별로 쪼개서 관리할 수 있게 해주는 설계도
    1. 구조 깔끔

    1. 협업하기 쉬움
    • 한 팀원이 회원 API, 다른 팀원이 상품 API를 각각 따로 블루프린트로 작성
      • 나중에 app.py에서 app.register_blueprint(...)만 하면 바로 합쳐짐
    1. 재사용 가능
    • 블루프린트는 독립적인 모듈이라 다른 프로젝트에서도 그대로 가져다 쓸 수 있음
    • 예: 인증 기능(로그인/회원가입) 블루프린트를 따로 만들어놓으면, 새 프로젝트에 그대로 붙여서 사용 가능
    1. 확장성 ↑ (대규모 프로젝트에 적합)
    • 규모가 커질수록 라우트 수가 수십~수백 개로 늘어나는데, 블루프린트로 모듈화하면 기능별로 관리 가능
    1. 공통 기능 묶기 가능
    • 블루프린트 단위로 URL prefix, 에러 핸들링, 미들웨어 등을 지정할 수 있음
    • 예: url_prefix="/api/v1/users" → 모든 엔드포인트 앞에 /api/v1/users 자동으로 붙음
profile
안녕하세요.

0개의 댓글