How to get GETted json data in Flask
Question: I am implementing a REST API in Python using Flask. I have to get parameters
to perform a query and return resources. To be aligned with `REST` principles,
I am going to use a `GET` request for this operation.

Given that there can be a lot of parameters, I want to send them through a
`conf.json` file, for instance:

    
    
    {"parameter": "xxx"}
    

I perform the request through `curl`:

> $ curl -H "Content-Type: application/json" --data @conf.json -G
> <http://localhost:8080/resources/>

The request is redirected to the route with these operations:

    
    
    @resources.route('/resources/', methods=['GET'])
    def discover():
    if request.get_json():
        json_data=request.get_json()
        return jsonify(json_data)
    

what I get back is:

    
    
    <head> 
    <title>Error response</title> 
    </head> 
    <body> 
    <h1>Error response</h1> 
    <p>Error code 400. 
    <p>Message: Bad request syntax ('GET /resources/?{"parameter": "xxx"} HTTP/1.1'). 
    <p>Error code explanation: 400 = Bad request syntax or unsupported method. </body>
    

Somebody knows how to get the json data and properly handle it in the request?


Answer: `request.get_json()` looks for JSON data in the request _body_ (e.g. what a
POST request would include). You put the JSON data in the _URL query string_
of a GET request instead.

Your `curl` command sends your JSON un-escaped, and produces an invalid URL,
so the server _rightly_ rejects that:

    
    
    http://localhost:8080/resources/?{"parameter": "xxx"}
    

You can't have spaces in a URL, for example. You'd have to use `--data-
urlencode` instead for this to be escaped properly:

    
    
    $ curl --data-urlencode @conf.json -G http://localhost:8080/resources/
    

Note that the `Content-Type` header is not needed here; you don't have any
request body to record the content _of_.

The adjusted `curl` command now sends a properly encoded URL:

    
    
    http://localhost:8080/resources/?%7B%22parameter%22%3A%20%22xxx%22%7D%0A%0A
    

Access that data with `request.query_string`. You will also have to _decode_
the URL encoding again before passing this to `json.loads()`:

    
    
    from urllib import unquote
    
    json_raw_data = unquote(request.query_string)
    json_data = json.loads(json_raw_data)
    

Take into account that many webservers put limits on how long a URL they'll
accept. If you are planning on sending more than 4k characters in a URL this
way, you really need to reconsider and use `POST` requests instead. That's 4k
with the JSON data _URL encoded_ , which adds a considerable overhead.

