Description
Problem
Currently we allow handling raw input for application/json
, text/xml
, text/plain
, application/octet-stream
on functions(ref).
However it's inflexible, no other custom media types can be handled. It also doesn't work for tables/views.
Solution
Use a domain-based media type as a function unnamed parameter to do custom conversion. Unlike ref this can work for both functions and tables/views.
Functions interface
CREATE DOMAIN "application/json" as json;
CREATE DOMAIN "application/octet-stream" as bytea;
CREATE FUNCTION mult_them("application/json") RETURNS int AS $$
SELECT ($1->>'x')::int * ($1->>'y')::int
$$ LANGUAGE SQL;
CREATE FUNCTION upload_binary("application/octet-stream") RETURNS void AS $$
INSERT INTO files(blob) VALUES ($1);
$$ LANGUAGE SQL;
Tables/views interface
CREATE FUNCTION convert_projects("application/json") RETURNS projects AS $$
-- ...
$$ LANGUAGE SQL;
CREATE FUNCTION convert_projects("text/plain") RETURNS projects AS $$
-- ...
$$ LANGUAGE SQL;
CREATE FUNCTION convert_projects("text/xml") RETURNS projects AS $$
-- ...
$$ LANGUAGE SQL;
e.g. the first function will be used when doing:
POST /projects
Content-Type: application/json
This means we'll use the unnamed parameter + return type to apply a conversion function for a particular table/view.
Inside the function a json_to_recordset
can be used (this is what we do internally). With this interface the user can override our default behavior.
Thanks to overloaded functions the same function name can be used to handle different media types.
Notes
- Consider dropping Functions with a single unnamed parameter after solving this. Advantages:
- This new interface is more intuitive and less magical.
- Simplify error messages.
- Simplify searching the rpc function.
- It will also be consistent with SQL handlers for custom media types #2825.
- The forward migration is relatively simple - changing a parameter type.
- The domain-based media types idea comes from Add
pgrst.accept
setting to RPC #1582 and Data Representations #2523. (long threads) .