-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Feature request: allow user-defined function to handle application-specific Accept headers #1548
Comments
@W1M0R I think the rpc part could be handled by #1546 (comment). With that you could That PR also includes some thought for regular (The proposal of handling extra media types with a convention is interesting though, will have to think more about it). |
Not sure where to post this, as this topic seems to be spread across multiple issues and PR now. Posting it in here, because I think this is the best approach so far. I would like to suggest a couple of additions to that as well: Content Negotiation (RPC)I don't really like the whole "raw-media-endpoints config option" approach - I think it would be a lot better, if we could somehow pass the information about which accept headers a function might respond to in the function definition itself. The best I could come up with in this regard would be to do it like this: CREATE FUNCTION my_rpc_with_custom_accept_header (...) RETURNS bytea AS $$
[...]
$$ LANGUAGE SQL SET app.accept = 'application/msgpack'; The Handling TablesAs to handle the table case described in this issue, it would be cool if we didn't need to use just one generic handler for all possible tables, but have the ability to have multiple handlers, each specific to a table as well. One way to do it would be similar to the "accept" part above: something like I think overloading that handler would be cool - we could maybe achieve that by passing the table type as an argument to the function. So something like this: CREATE FUNCTION msgpack_handler (
handler_for accounts,
accept text, -- not sure if we need this at all, with the set app.accept stuff.
-- could be read out via request options as well, I think
result jsonb
) RETURNS bytea -- return types should probably only be bytea and text,
-- as those don't need further processing when sending to the client
AS $$
[...]
$$ LANGUAGE SQL SET app.accept='application/msgpack';
CREATE FUNCTION msgpack_handler (handler_for messages, accept text, result jsonb) RETURNS bytea
AS $$
[...]
$$ LANGUAGE SQL SET app.accept='application/msgpack'; Note the different type for the Now to determine which handler to call, the schema cache could just look up the argument type and app.accept configuration to find a match. |
That's really clever @wolfgangwalther. I think you've nailed the RPC case, querying |
I agree that But, I think neither
I think |
As for the tables: I think it's quite important to be able to somehow have different handler functions for different tables. Suppose one table should accept requests for Now as to my suggestion, I agree that the "NULL argument handler_for with table type" seems quite an odd use case for the argument. This would just add the benefit of overloading functions, which personally I would find nice - but might not work the effort required. The easier solution would of course be to just use Actually... while the wildcard could be achieved with the argument solution as well somehow, the multiple tables solution would probably not work. I tend to favour the |
Applying the same thoughts as in my 2nd to last comment about This would also keep In this case we could use a function like this to parse the body before executing the query: CREATE FUNCTION msgpack_request_handler (body BYTEA /* or TEXT */) RETURNS TABLE (...) AS $$
[...]
$$ LANGUAGE SQL SET request.handler = 'accounts', request.content_type='application/msgpack'; |
@wolfgangwalther Yes, the dot( Regarding Many great ideas on the table case here. I would have to experiment a bit to give more meaningful feedback(maybe our current json output could be a type of handler?). However design-wise I think that the RPC case is ready(if we agree on the setting name of course) and we would already satisfy many use cases with it. We could add the custom RPC accept as a first step and also take the chance to deprecate the A new release is close and it'd be awesome to include this feature :) |
Absolutely right about |
Thanks for all your hard work on this feature @steve-chavez and @wolfgangwalther! Your teamwork, consideration, direction and dedication is inspiring. |
Consider a request
/accounts
that returns a list of accounts and their details.Request header
Accept: application/json
will return the information as JSON. However, some clients might want the data returned in some other application-specific representation, e.g. protobuf base64, flatbuffer base64, msgpack base64, etc.Currently, one would have to implement a generic stored procedure (say
/rpc/msgpack
) that will parse the body to determine what content is requested (since we lose the/accounts
query url info), then to call the stored procedure that implements/accounts
, convert the result to json and then again to msgpack. However, with this approach we lose the benefit of having PostgREST handling filtering and resource selection with query parameters.Ideally, the client should be able to query
/accounts
but use an application-defined Accept header, let's sayAccept: application/msgpack
. PostgREST can be started with a configuration option that indicates the name of a user-defined Postgres function (e.g.myschema.myhandler(accept text, result jsonb)
) that will handle any unknown Accept headers. When PostgREST receives the/accounts
request, it should determine that the provided Accept header is not part of the default PostgREST supported headers, and having confirmed thatmyschema.myhandler)
exists, it will fulfill the/accounts
query, but before sending the result to the user, it will forward the results tomyschema.myhandler
and return the result of that function instead.The
myschema.myhandler
function will use itsaccept
parameter to determine that the user requestedapplication/msgpack
data, and then convert theresult
parameter to msgpack and return that instead.Concerning the return value of
myschema.myhandler
, it should probably also be a user-defined custom type.The text was updated successfully, but these errors were encountered: