[Flask]Json data 처리 오류

Aiden·2022년 4월 2일
0
post-thumbnail

Error


Flask 에서 Json 데이터를 받아오는 방법으로는 request.jsonrequest.get_json() 이 있다.

이 중에서 나는 request.json 을 사용하였고, 코드는 아래와 같다.

from flask import request

@app.route('/test/method/<id>')
def method_test(id):
	return jsonify({
    	'request.method': request.method,
        'request.args': request.args,
        'request.form': request.form,
        'request.json': request.json,
        })

이후, Postman 을 사용해 GET 요청을 전송하였고 400 Bad Request 를 응답으로 받았다.
어떠한 Json 데이터도 넘겨주지 않았기 때문에 빈 curly brackets 를 200 과 함께 반환할 것으로 예상했지만 실제로는 그렇지 않았던 것이다.

또한, Jsonify 를 사용하였음에도 Content-typeapplication/json 이 아닌 text/html 이었다.

Query String 을 넘겨주지 않을 경우, request.args 는 빈 curly brackets 를 반환하고, Body 를 넘겨주지 않을 경우 request.form 또한 빈 curly brackets 를 반환한다.

그렇다면 Json 을 넘겨주지 않을 경우, request.json 은 왜 빈 curly brackets 가 아닌 400 을 반환하는 것일까?

추가적으로, 어떻게 하면 200 과 함께 원하는 결과를 응답받을 수 있을까?



Solution


💡 on_json_loading_failed()

Flask 에서는 MIME typeapplication/json 일 때, 어떠한 Json 문자열도 전송하지 않을 경우 400 Bad Request 를 반환한다.

이는 Json 데이터를 parsing 하는 과정에서 빈 문자열로 인한 parsing fail 이 발생하여 on_json_loading_failed() 함수가 자동으로 실행되기 때문이다.

on_json_loading_failed() 함수는 Json 데이터에 대한 Decode 가 실패하게 될 경우, 400 Bad Request 를 반환하도록 구현되어 있다.

결국, 빈 Json 데이터에 대한 400 Bad Request 응답은, parsing fail 로 인한 on_json_loading_failed() 함수의 실행이 그 원인인 것이다.

💡 define

이는 다른 말로, 우리가 이 함수를 재정의하여 원하는 결과를 응답받을 수도 있음을 의미한다.
on_json_loading_failed() 함수를 재정의하여 빈 Json 데이터에 대한 내부 동작을 우리가 원하는 값을 반환하도록 수정해준다면, 빈 curly brackets 를 그대로 반환받을 수도 있고 로그를 남기는 데 활용할 수도 있을 것이다.

아래는 Json 데이터가 빈 문자열일 경우, 그대로 curly brackets 를 반환하도록 수정한 코드이다.

from flask import request

# 빈 curly brackets 를 반환하는 function
def on_json_loading_failed_return_dict(e):
	return {}

@app.route('/test/method/<id>')
def method_test(id):

	# request.on_json_loading_failed 와 연결
	request.on_json_loading_failed = on_json_loading_failed_return_dict
    
    return jsonify({
    'request.method': request.method,
    'request.args': request.args,
    'request.form': request.form,
    'request.json': request.json,
    })

빈 curly brackets 를 반환하는 함수인 on_json_loading_failed_return_dict 를 새롭게 정의하고, request 의 on_json_loading_failed 와 연결시켜주는 코드가 추가되었다.

이제 Json 데이터로 빈 문자열을 전송하더라도 200 OK 와 함께 curly brackets 를 반환받을 수 있다.

💡 silent=True

get_json() 을 사용하여 Json 데이터를 받아오는 경우에는, silent 파라미터를 활용하여 손쉽게 parsing fail 에 대한 예외처리를 수행할 수 있다.

silent 의 기본값은 False 이며 이를 True 로 설정해주게 되면, Json 데이터의 parsing fail 시에 에러없이 None 을 반환하게 된다.

print request.get_json(silent=True)

하지만 on_json_loading_failed() 함수를 재정의하는 방법과는 달리, 내부 동작을 원하는대로 커스터마이징할 수 없고, MIME typetext/html 이어야 한다는 차이점이 있다.

0개의 댓글