Skip to content

Commit

Permalink
Add common parameters to the Components Object
Browse files Browse the repository at this point in the history
  • Loading branch information
laurenceisla authored Dec 22, 2023
1 parent 997735a commit 81f5b64
Show file tree
Hide file tree
Showing 7 changed files with 308 additions and 3 deletions.
4 changes: 2 additions & 2 deletions sql/main.sql
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ select openapi_object(
servers := openapi_server_objects(),
paths := '{}',
components := openapi_components_object(
schemas := postgrest_tables_to_openapi_schema_components(schemas) || postgrest_composite_types_to_openapi_schema_components(schemas)
schemas := postgrest_tables_to_openapi_schema_components(schemas) || postgrest_composite_types_to_openapi_schema_components(schemas),
parameters := postgrest_get_query_params() || postgrest_get_headers()
)
)
from postgrest_get_schema_description(schemas[1]) sd;
$$;

37 changes: 36 additions & 1 deletion sql/openapi.sql
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
-- Functions to build the the OpenAPI output
-- Functions and types to build the the OpenAPI output

-- TODO: create enum for openapi type e.g. string, number, etc.
create type parameter_object_in as enum ('query', 'header', 'path', 'cookie');
create type parameter_object_style as enum ('simple', 'form');

create or replace function openapi_object(
openapi text,
Expand Down Expand Up @@ -180,3 +184,34 @@ select json_build_object(
'$ref', '#/components/schemas/' || ref
);
$$;

create or replace function openapi_parameter_object(
name text,
"in" parameter_object_in,
description text default null,
required boolean default null,
deprecated boolean default null,
allowEmptyValue boolean default null,
style parameter_object_style default null,
explode boolean default null,
"schema" jsonb default null,
example jsonb default null,
examples jsonb default null
)
returns jsonb language sql as
$$
-- TODO: Add missing logic between fields (e.g. example and examples are mutually exclusive)
select jsonb_build_object(
'name', name,
'in', "in",
'description', description,
'required', required,
'deprecated', deprecated,
'allowEmptyValue', allowEmptyValue,
'style', style,
'explode', explode,
'schema', "schema",
'example', example,
'examples', examples
)
$$;
225 changes: 225 additions & 0 deletions sql/postgrest.sql
Original file line number Diff line number Diff line change
Expand Up @@ -509,3 +509,228 @@ returns text language sql as
$$
select '11.0.1 (4197d2f)'
$$;

create or replace function postgrest_get_query_params ()
returns jsonb language sql as
$$
select jsonb_object_agg(name, param_object) from unnest(
array['select','order', 'limit', 'offset', 'on_conflict', 'columns', 'or', 'and', 'not.or', 'not.and'],
array[
openapi_parameter_object(
name := 'select',
"in" := 'query',
description := 'Vertical filtering of columns',
explode := false,
schema := openapi_schema_object(
type := 'array',
items := openapi_schema_object(type := 'string')
)
),
openapi_parameter_object(
name := 'order',
"in" := 'query',
description := 'Ordering by column',
explode := false,
schema := openapi_schema_object(
type := 'array',
items := openapi_schema_object(type := 'string')
)
),
openapi_parameter_object(
name := 'limit',
"in" := 'query',
description := 'Limit the number of rows returned',
explode := false,
schema := openapi_schema_object(
type := 'integer'
)
),
openapi_parameter_object(
name := 'offset',
"in" := 'query',
description := 'Skip a certain number of rows',
explode := false,
schema := openapi_schema_object(
type := 'integer'
)
),
openapi_parameter_object(
name := 'on_conflict',
"in" := 'query',
description := 'Columns that resolve the upsert conflict',
explode := false,
schema := openapi_schema_object(
type := 'string'
)
),
openapi_parameter_object(
name := 'columns',
"in" := 'query',
description := 'Specify which keys from the payload will be inserted',
explode := false,
schema := openapi_schema_object(
type := 'string'
)
),
openapi_parameter_object(
name := 'or',
"in" := 'query',
description := 'Logical operator to combine filters using OR',
explode := false,
schema := openapi_schema_object(
type := 'string'
)
),
openapi_parameter_object(
name := 'and',
"in" := 'query',
description := 'Logical operator to combine filters using AND (the default for query params)',
explode := false,
schema := openapi_schema_object(
type := 'string'
)
),
openapi_parameter_object(
name := 'not.or',
"in" := 'query',
description := 'Negate the logical operator to combine filters using OR',
explode := false,
schema := openapi_schema_object(
type := 'string'
)
),
openapi_parameter_object(
name := 'not.and',
"in" := 'query',
description := 'Negate the logical operator to combine filters using AND',
explode := false,
schema := openapi_schema_object(
type := 'string'
)
)
]
) as _(name, param_object);
$$;

create or replace function postgrest_get_headers ()
returns jsonb language sql as
$$
select jsonb_object_agg(name, param_object) from unnest(
array['preferParams', 'preferReturn', 'preferCount', 'preferResolution', 'preferTransaction', 'preferMissing', 'preferHandling', 'preferTimezone', 'preferMaxAffected', 'range'],
array[
openapi_parameter_object(
name := 'Prefer',
"in" := 'header',
description := 'Send JSON as a single parameter',
schema := openapi_schema_object(
type := 'string',
"enum" := jsonb_build_array(
'params=single-object'
)
)
),
openapi_parameter_object(
name := 'Prefer',
"in" := 'header',
description := 'Return information of the affected resource',
schema := openapi_schema_object(
type := 'string',
"enum" := jsonb_build_array(
'return=minimal',
'return=headers-only',
'return=representation'
)
)
),
openapi_parameter_object(
name := 'Prefer',
"in" := 'header',
description := 'Get the total size of the table',
schema := openapi_schema_object(
type := 'string',
"enum" := jsonb_build_array(
'count=exact',
'count=planned',
'count=estimated'
)
)
),
openapi_parameter_object(
name := 'Prefer',
"in" := 'header',
description := 'Handle duplicates in an upsert',
schema := openapi_schema_object(
type := 'string',
"enum" := jsonb_build_array(
'resolution=merge-duplicates',
'resolution=ignore-duplicates'
)
)
),
openapi_parameter_object(
name := 'Prefer',
"in" := 'header',
description := 'Specify how to end a transaction',
schema := openapi_schema_object(
type := 'string',
"enum" := jsonb_build_array(
'tx=commit',
'tx=rollback'
)
)
),
openapi_parameter_object(
name := 'Prefer',
"in" := 'header',
description := 'Handle null values in bulk inserts',
schema := openapi_schema_object(
type := 'string',
"enum" := jsonb_build_array(
'missing=default',
'missing=null'
)
)
),
openapi_parameter_object(
name := 'Prefer',
"in" := 'header',
description := 'Handle invalid preferences',
schema := openapi_schema_object(
type := 'string',
"enum" := jsonb_build_array(
'handling=strict',
'handling=lenient'
)
)
),
openapi_parameter_object(
name := 'Prefer',
"in" := 'header',
description := 'Specify the time zone',
example := '"timezone=UTC"',
schema := openapi_schema_object(
-- The time zones can be queried, but there are ~500 of them. It could slow down the UIs (unverified).
type := 'string'
)
),
openapi_parameter_object(
name := 'Prefer',
"in" := 'header',
description := 'Limit the number of affected resources',
example := '"max-affected=5"',
schema := openapi_schema_object(
type := 'string'
)
),
openapi_parameter_object(
name := 'Range',
"in" := 'header',
description := 'For limits and pagination',
example := '"5-10"',
schema := openapi_schema_object(
type := 'string'
)
)
]
) as _(name, param_object);
$$;
36 changes: 36 additions & 0 deletions test/expected/parameters.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
-- shows common query parameters
select *
from jsonb_each(get_postgrest_openapi_spec('{public}')->'components'->'parameters')
where key in ('select', 'order', 'limit', 'offset', 'on_conflict', 'columns', 'or', 'and', 'not.or', 'not.and');
key | value
-------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
or | {"in": "query", "name": "or", "schema": {"type": "string"}, "explode": false, "description": "Logical operator to combine filters using OR"}
and | {"in": "query", "name": "and", "schema": {"type": "string"}, "explode": false, "description": "Logical operator to combine filters using AND (the default for query params)"}
limit | {"in": "query", "name": "limit", "schema": {"type": "integer"}, "explode": false, "description": "Limit the number of rows returned"}
order | {"in": "query", "name": "order", "schema": {"type": "array", "items": {"type": "string"}}, "explode": false, "description": "Ordering by column"}
not.or | {"in": "query", "name": "not.or", "schema": {"type": "string"}, "explode": false, "description": "Negate the logical operator to combine filters using OR"}
offset | {"in": "query", "name": "offset", "schema": {"type": "integer"}, "explode": false, "description": "Skip a certain number of rows"}
select | {"in": "query", "name": "select", "schema": {"type": "array", "items": {"type": "string"}}, "explode": false, "description": "Vertical filtering of columns"}
columns | {"in": "query", "name": "columns", "schema": {"type": "string"}, "explode": false, "description": "Specify which keys from the payload will be inserted"}
not.and | {"in": "query", "name": "not.and", "schema": {"type": "string"}, "explode": false, "description": "Negate the logical operator to combine filters using AND"}
on_conflict | {"in": "query", "name": "on_conflict", "schema": {"type": "string"}, "explode": false, "description": "Columns that resolve the upsert conflict"}
(10 rows)

-- shows common headers
select *
from jsonb_each(get_postgrest_openapi_spec('{public}')->'components'->'parameters')
where key in ('preferParams', 'preferReturn', 'preferCount', 'preferResolution', 'preferTransaction', 'preferMissing', 'preferHandling', 'preferTimezone', 'preferMaxAffected', 'range');
key | value
-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
range | {"in": "header", "name": "Range", "schema": {"type": "string"}, "example": "5-10", "description": "For limits and pagination"}
preferCount | {"in": "header", "name": "Prefer", "schema": {"enum": ["count=exact", "count=planned", "count=estimated"], "type": "string"}, "description": "Get the total size of the table"}
preferParams | {"in": "header", "name": "Prefer", "schema": {"enum": ["params=single-object"], "type": "string"}, "description": "Send JSON as a single parameter"}
preferReturn | {"in": "header", "name": "Prefer", "schema": {"enum": ["return=minimal", "return=headers-only", "return=representation"], "type": "string"}, "description": "Return information of the affected resource"}
preferMissing | {"in": "header", "name": "Prefer", "schema": {"enum": ["missing=default", "missing=null"], "type": "string"}, "description": "Handle null values in bulk inserts"}
preferHandling | {"in": "header", "name": "Prefer", "schema": {"enum": ["handling=strict", "handling=lenient"], "type": "string"}, "description": "Handle invalid preferences"}
preferTimezone | {"in": "header", "name": "Prefer", "schema": {"type": "string"}, "example": "timezone=UTC", "description": "Specify the time zone"}
preferResolution | {"in": "header", "name": "Prefer", "schema": {"enum": ["resolution=merge-duplicates", "resolution=ignore-duplicates"], "type": "string"}, "description": "Handle duplicates in an upsert"}
preferMaxAffected | {"in": "header", "name": "Prefer", "schema": {"type": "string"}, "example": "max-affected=5", "description": "Limit the number of affected resources"}
preferTransaction | {"in": "header", "name": "Prefer", "schema": {"enum": ["tx=commit", "tx=rollback"], "type": "string"}, "description": "Specify how to end a transaction"}
(10 rows)

File renamed without changes.
9 changes: 9 additions & 0 deletions test/sql/parameters.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- shows common query parameters
select *
from jsonb_each(get_postgrest_openapi_spec('{public}')->'components'->'parameters')
where key in ('select', 'order', 'limit', 'offset', 'on_conflict', 'columns', 'or', 'and', 'not.or', 'not.and');

-- shows common headers
select *
from jsonb_each(get_postgrest_openapi_spec('{public}')->'components'->'parameters')
where key in ('preferParams', 'preferReturn', 'preferCount', 'preferResolution', 'preferTransaction', 'preferMissing', 'preferHandling', 'preferTimezone', 'preferMaxAffected', 'range');
File renamed without changes.

0 comments on commit 81f5b64

Please sign in to comment.