Cloud Run requests triggers error 400 without reaching deployed service

3.4k views Asked by At

I am currently using Google Cloud Run to deploy an API and although everything was working fine I am now having quite a hard time understanding an error I get.

I created the API on python3 using FastAPI, the Location model is based on Pydantic's BaseModel.

To illustrate it I have defined a test route as follow :

class Location(BaseModel):
    lat: float
    lng: float


@router.get('/test_404')
async def test_404(origin: Location = Body(...),
                   destination: Location = Body(...)):
    print(origin)
    print(destination)
    return {'res': 'ok'}

The route should take two arguments in the request's body : origin and destination, and it does but only when I deploy it locally. This :

url_local = "http://0.0.0.0:8080/test_404"
data = {
    'origin': {'lat': 104, 'lng': 342},
    'destination': {'lat': 104, 'lng': 342}
}
resp = requests.get(url_local, json = data)
print(resp.text)

Outputs :

'{"res":"ok"}'

The issue arises when I deploy the same service on Cloud Run. All of my other routes work fine but here is the output I get when I use the code above with the container url :

    <!DOCTYPE html>\n
    <html lang=en>
    <meta charset=utf-8>
    \n
    <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
    \n <title>Error 400 (Bad Request)!!1</title>\n
    \n <a href=//www.google.com/><span id=logo aria-label=Google></span></a>\n
    <p><b>400.</b>
        <ins>That’s an error.</ins>
        \n
    <p>Your client has issued a malformed or illegal request.
        <ins>That’s all we know.</ins>

This is an error triggered by google and that does not let my request reach the service (no log entry)

I've searched online but did not find what causes this error. What am I missing ?

Thank you very much

1

There are 1 answers

1
Cloudkollektiv On BEST ANSWER

It might be related to this post, where a user experiences a similar message. After some reading, and seeing your example, I think the solution lies in the REST best practices.

Strictly speaking, a GET request should not send any data when doing the request, other than anything incorporated within the URI. Technically, everything is possible, but you should use query parameters instead of sending a body.

Some API wrappers (like Cloud Run), may not accept this behaviour, while in your local test it may seem to work. Other API wrappers may just accept a body with a GET request. I would recommend sticking to the REST best practices and you are fine.