Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A question about request.json #2939

Open
1 task done
hulaime opened this issue Apr 12, 2024 · 1 comment
Open
1 task done

A question about request.json #2939

hulaime opened this issue Apr 12, 2024 · 1 comment

Comments

@hulaime
Copy link

hulaime commented Apr 12, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe.

I have an API about this, similar to fuzzy query,

@app.route('/list', methods=['POST',])
async def get_user_api(request):
    user_name = request.json.get('name', None)
    ...
   users = await get_users(name=user_name, ...)
   return response.json(users)

Expect all results returned:
curl -X POST -H "Content-Type: application/json" http://localhost:8080/user/list

Expect results related to test to be returned:
curl -X POST -H "Content-Type: application/json" -d '{ "name": "test"}' http://localhost:8080/user

However, the reality is that when using the first curl, the system reports an error message:

user_name = request.json.get('name', None)
                ^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get'

Describe the solution you'd like

When trying to process requst.json in middleware, it prompts: AttributeError: property 'json' of 'Request' object has no setter。

@app.middleware('request')
async def your_middleware(request):
    if request.json is None:
        request.json = {}

Is there any other good solution that does not require judging request.json to be None in app.route?

Additional context

No response

@kuchara
Copy link

kuchara commented Apr 16, 2024

tl;dr if you do not care on the below topics, you may use request.ctx in the middleware, and add json there, and use it in all your handlers.

@app.middleware('request')
async def your_middleware(request):
    if request.json is None:
        request.ctx.json = {}
    else:
        request.ctx.json = request.json

BUT

I think your HTTP request is improper as there is no data in body (empty string is not a valid JSON, according to my knowledge).
But then, why Sanic ever accepted such invalid request?

You should send valid JSON if content is set to application/json:

curl -X POST -H "Content-Type: application/json" --data '{}' http://localhost:8080/user/list
#or
curl -X POST -H "Content-Type: application/json" --data 'null' http://localhost:8080/user/list

However if you send null, it would generate the same issue (request.json == None).

Anyway, above shows that None != {} (that is, in JSON terms: null != {}), so I think it makes sense to have this distinction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants