TOP
class="layout-aside-left paging-number">
본문 바로가기
[파이썬 Projects]/<파이썬 웹개발>

[파이썬] 플라스크(Flask) - 요청과 응답

by 기록자_Recordian 2024. 7. 14.
728x90
반응형
시작에 앞서
해당 내용은 <가장 빠른 풀스택을 위한 Flask & FastAPI>, Dave Lee 지음. BJ Public 출판.
내용을 토대로 작성되었습니다. 보다 자세한 사항은 해당 교재를 참고하시기 바랍니다.

요청과 응답

 

요청: 웹 브라우저나 다른 클라이언트가 웹 서버에 정보를 요청하는 것.

이 정보에는 여러 가지 데이터가 포함될 수 있으며, 이를 처리하여 적절한 응답을 클라이언트에게 전달하는 것이 웹 애플리케이션의 역할이다.


플라스크에서의 요청 처리

 

플라스크에서는 request 객체를 통해 요청 데이터에 접근할 수 있다.

이 객체는 클라이언트에게 받은 여러 가지 정보를 포함하고 있다. (URL, 헤더, 쿠키, 쿼리 매개변수 등)

from flask import Flask, request

app = Flask(__name__)

@app.route('/query')
def query_example():
    langguage = request.args.get('language')
    return f"Requested Language: {langguage}"

http://127.0.0.1:5000/query?language=Python 라는 주소로 접속하면 'Requested Language: Python' 이라고 응답하는데, 여기서 language=Python 부분이 쿼리 매개변수이다.

※ 쿼리 매개변수(Query Parameters)
URL의 ? 이후에 나오는 키-값 쌍의 데이터.

웹 서버에 추가 정보를 제공하기 위해 사용된다. 이 정보는 주로 폼 데이터의 전송, 페이지 정렬, 검색 필터 등에서 사용되며 URL에 직접 표함되기 때문에 사용자 또는 웹 서비스가 생성한 링크를 통해 쉽게 공유할 수 있다.

 

플라스크에서는 request.args 딕셔너리를 통해 이 쿼리 매개변수에 접근할 수 있으며, GET 메서드를 사용해 특정 키에 해당하는 값들을 추출할 수 있다.

쿼리 매개변수가 없을 경우 None을 반환하거나, GET 메서드의 두 번째 인자로 기본값을 설정하여 해당 키가 없을 때 반환할 값을 지정할 수도 있다.

 

[예제 링크]

- 검색 쿼리를 포함한 URL

example.com/search?query=flask

▶ 해당 URL은 example.com의 search 페이지로, 검색 쿼리로 'flask'를 전달

 

- 여러 쿼리 매개변수를 포함한 URL

example.com/items?page=2&sort=asc

▶ 해당 URL은 page=2와 sort=asc는 서버에 현재 페이지 번호와 정렬 순서(오름차순)를 알리는 데 사용

 

- 필터 옵션을 포함한 URL

example.com/products?category=book&price=under10

▶ 해당 URL은 category가 'book'이고, price가 'under10'인 상품을 필터링하기 위해 사용


플라스크에서의 응답 처리

 

응답은 클라이언트의 요청을 처리한 후 웹 서버가 되돌려 보내는 데이터 패키지이다.

이 패키지에는 요청이 성공적이었는지, 에러가 밸생했는지를 나타내는 HTTP 상태 코드(status code), 데이터 타입이나 캐시 제어 같은 추가적인 정보를 제공하는 헤더(header), 실제 전송하려는 데이터인 바디(body)가 포함된다.

 

클라이언트의 요청에 대한 응답을 개발자는 리턴(return)문을 통해 직접 문자열을 통해 반환하거나, 더 복잡한 데이터 구조를 반환하기 위해 플라스크의 헬퍼 함수(helper functions)를 사용할 수 있다.

※  헬퍼 함수(helper functions)
개발자가 일반적인 웹 개발 작업을 쉽게 처리할 수 있도록 돕는 미리 정의된 함수들.
예) url_for(): 라우트 이름과 매개변수를 기반으로 URL을 동적으로 생성
jsonify(): 파이썬의 딕셔너리를 JSON 응답으로 변환하여 반환하는 데 사용

 

from flask import Flask, jsonify
app = Flask(__name__)

@app.route('/json')
def json_example():
    # jsonify를 사용하여 JSON 형식의 응답 반환
    return jsonify({"message": "Hello, World!"})

 

이 코드는 클라이언트가 http://127.0.0.1:5000/json 주소로 요청을 보낼 때,

서버가 JSON 형식의 {"message": "Hello, World!"} 데이터를 응답 바디에 담아 반환한다.

 

여기에서 jsonify() 함수는 Python 딕셔너리를 JSON 형식의 문자열로 변환하며, 클라이언트에게 해당 응답이 JSON 형식의 데이터를 포함하고 있다는 것을 명확히 알려주기 위해 HTTP 응답의 Content-Type을 application/JSON으로 자동 설정해준다.

 

응답 처리는 웹 개발의 핵심 요소이며, 플라스크에서는 이를 간편하게 만들어준다.

텍스트 기반의 JSON 형식은 웹에서 데이터를 교환하기에 매우 효율적이며, 플라스크의 jsonify() 함수는 이를 손쉽게 구현할 수 있도록 도와준다.


JSON이란?

 

JSON(JavaScript Object Notation)은 데이터를 저장하거나 전송할 때 사용하는 경량의 데이터 교환 형식이다.

사람과 기계가 모두 읽기 쉬운 텍스트를 기반으로 하며 자바스크립트 객체 문법을 따르지만, 프로그래밍 언어나 플랫폼에 구애받지 않고 사용할 수 있다.

 

[JSON의 기본 문법]

  • 데이터는 이름/값 쌍으로 이루어진다
  • 중괄호 {}는 객체를, 대괄호 []는 배열을 나타낸다
  • 이름과 값은 콜론(:)으로 구분된다
  • 각 이름은 문자열이어야 하며, 값은 다양한 타입이 될 수 있다. (문자열, 숫자, 배열, 객체, boolean, null)

[JSON 예제]

{
	"name":"Hong Gildong",
    "age":20,
    "isStudent": false,
    "courses": ["Mathmatics", "Literature"],
    "address": {
    	"city":"Seoul",
        "Country":"South Korea"
    }
}

 

★ API(Application Programming Interface)

API는 시스템과 시스템, 프로그램과 프로그램이 서로 소통하기 위한 중간 다리 같은 역할을 한다.

JSON으로 응답하는 API는 다음과 같은 이유로 필요하며, 널리 사용된다.

  • 언어 독립성: JSON은 대부분의 프로그래밍 언어에서 쉽게 파싱(parsing) 할 수 있고, 이를 통해 다양한 언어로 작성된 시스템들 사이에 데이터를 교환할 수 있다
  • 읽기 쉬움: 사람이 읽고 이해하기 쉬운 구조로 되어 있어 개발자가 직관적으로 데이터를 다룰 수 있다
  • 경량성: JSON은 데이터 구조를 간결하게 표현하기 때문에 네트워크를 통한 데이터 전송 시 부하를 최소화한다
  • 구조화된 데이터: JSON은 복잡한 데이터를 잘 구조화할 수 있어 중첩된 배열이나 객체를 사용하여 계층적 데이터를 표현하기에 적합하다
  • 웹 표준과의 호환성: JSON은 웹 표준인 자바스크립트와 밀접하게 연관되어 있어 웹 기반 통신에서 매끄럽게 작동한다.

▶ 실무에서 JSON은 웹 API를 통해 프런트엔드와 백엔드 간, 또는 서비스와 서비스 간에 데이터를 주고받는 데 기본적인 형식으로 자리잡았다. (모바일 애플리케이션, 웹 서비스, IOT 디바이스와의 통신 등)


상태 코드와 헤더 설정

 

응답을 할 때 상태 코드(status code)나 헤더(header) 설정을 할 수 있다.

상태 코드는 HTTP 상태 코드를 의미하며 서버가 클라언트의 요청을 처리한 결과를 나타내는 3자리 숫자이다.

 

[주요 상태 코드]

  • 200 OK: 요청이 성공적으로 처리됨
  • 201 Created: 요청이 성공적으로 처리되어 새 리소스가 생성됨
  • 400 Bad Request: 서버가 요청을 이해하지 못함
  • 401 Unauthorized: 인증이 필요한 페이지를 요청함
  • 403 Forbidden: 서버가 요청을 거부함
  • 404 Not Found: 요청한 리소스를 찾을 수 없음
  • 500 Internal Server Error: 서버 내부 에러가 발생함

헤더는 HTTP 요청과 응답 메시지의 일부로, 클라이언트와 서버 간의 통신에 대한 추가적인 정보를 제공한다.

헤더는 요청 또는 응답의 바디와 별개로 전송되며 데이터의 타입, 캐시 관리, 인증 정보, 서버 정보, 클라이언트의 세션 관리 등 다양한 컨텍스트를 제공한다.

이 헤더들은 브라우저나 서버가 서로에게 어떤 작업을 해야 하는지 알려주는 중요한 역할을 하며, 웹 개발에서 필수적인 부분이다.

 

플라스크에서는 make_response() 함수를 사용해서 상태 코드와 헤더를 지정하는 헬퍼 함수를 제공한다.

from flask import Flask, make_response

app = Flask(__name__)

@app.route('/response')
def response_example():
    # 응답 객체 생성 "Hello with Header"는 응답 바디, 200은 HTTP 상태 코드
    resp = make_response("Hello with Header", 200)
    # 'Custom-Header' 라는 이름의 사용자 정이 헤더를 설정하고 'custom-value' 값 지정
    resp.headers['Custom-Header'] = 'custom-value'
    # 설정한 헤더와 함께 응답 객체 반환
    return resp

 

http://127.0.0.1:500/response 주소에 접속한 후 개발자도구 (F12 또는 Ctrl+Shift+I) 를 열어

네트워크(network) 탭을 선택한 뒤 새로고침(F5) 하면 페이지 로드와 관련된 HTTP 요청 목록을 볼 수 있다.

상태 코드(Status Code)는 200 OKCustom-Header 는 custom-value로 되어 있는 것을 확인할 수 있다

 

플라스크에서 make_response() 함수는 응답 객체를 생성할 때 사용되며 이 객체를 통해 개발자는 응답의 내용, 상태 코드, 헤더 등을 세밀하게 조정할 수 있다.

 

[함수의 기본 문법]

make_response(body=None, status=None, headers=None)
  • body: 클라이언트에게 보낼 응답 내용. 문자열, HTML, 또는 JSON 객체 등이 될 수 있다
  • status: HTTP 상태 코드
  • headers: 응답과 함께 클라이언트에 전달할 HTTP 헤더를 딕셔너리 형태로 설정할 수 있다. 직접 인자로 전달하는 것도 가능하고, 생성된 응답 객체에 나중에 헤더를 추가하는 것도 가능하다.

[예제 코드]

# make_response() 호출 시 세 번째 인자로 headers를 직접 딕셔너리 형태로 넘겨줌
from flask import Flask, make_response

app = Flask(__name__)

@app.route('/direct')
def direct_response():
	headers = {'X-Example': 'DirectHeader'}
    return make_response("Direct Response", 200, headers)

▶ make_response() 함수 호출 시 세 번째 인자로 headers를 직접 딕셔너리 형태로 넘겨주는 예제 코드

생성 시점에 모든 정보를 한 번에 넘길 때 유용.

 

# make_response() 호출하여 생성된 응답 객체에 .headers 속성을 사용하여 헤더 추가
from flask import Flask, make_response

app = Flask(__name__)

@app.route('/direct')
def custom_response():
	response = make_response("Custom Response", 202)
    response.headers['X-Example'] = 'CustomHeader'
    return response

 

make_response() 호출하여 생성된 응답 객체에 .headers 속성을 사용하여 헤더를 추가하는 예제 코드

응답 객체를 조금 더 유동적으로 다룰 필요가 있을 때 유용.

 

두 방법 모두 유효하며, 상황에 따라 선택해서 사용할 수 있다.

728x90
반응형