PostgREST / postgrest

REST API for any Postgres database
https://postgrest.org
MIT License
23.27k stars 1.02k forks source link

Query parameters that aren't filters on a POST request shouldn't return 400 #3562

Open ThuGapy opened 3 months ago

ThuGapy commented 3 months ago

Currently, POST requests parameters seem to be fetched from the body. However, some HTTP integrations with 3rd party tools appends query parameters to the URL even if it is a POST request. As far as I can understand, currently, PostgREST will try to parse the query parameter as a filter instead of simply ignoring it, causing the POST request to return a HTTP error code of 400 (Bad Request).

One of the suggested solution is to use a reverse proxy like nginx to remove the query parameter. The problem with that is that it creates edge-cases and it is frankly a complicated solution to a simple problem.

My suggestion would be to simply ignore the bad filters on POST requests instead of returning 400. This would simplify integration with 3rd party tools significantly and eliminate the need of a reverse proxy for something as basic as a query parameter that you don't even need

If ignoring the bad filters on POST requests isn't something that is feasable, maybe being able to pass parameters from the URL to the PL/pgSQL function on a POST request could be an interesting solution.

wolfgangwalther commented 3 months ago

My suggestion would be to simply ignore the bad filters on POST requests instead of returning 400.

I don't think we want to do that. Silently ignoring stuff is not helpful, e.g. when mistyping things etc.

maybe being able to pass parameters from the URL to the PL/pgSQL function on a POST request could be an interesting solution.

That's better. But what would happen if you pass the same parameter in the body and in the URL?

ThuGapy commented 3 months ago

How it is currently is probably the worst possible way when were are talking about using PostgREST for integrations where we have no control over how the data is being sent.

To me, trying to get the data from the body for a POST request is fine. Getting parameters from the URL could be a fallback in case it's not found in the body. Realisticly, in an ideal world, most if not all data should be passed in the body, so I wouldn't have a problem with query parameters as fallback.

wolfgangwalther commented 3 months ago

But what would happen if you pass the same parameter in the body and in the URL?

One idea how we could support this: We already have support for "single unnamed json argument" functions, which get the full body in that argument. We could allow something like this:

CREATE FUNCTION rpc(json, query_arg text) ...

This would:

This would not have the problem of name collisions.

ThuGapy commented 3 months ago

Yeah, I would say I agree with your idea, we get the best of both worlds and it covers most cases