Skip to content

Commit 81f5b64

Browse files
authored
Add common parameters to the Components Object
1 parent 997735a commit 81f5b64

File tree

7 files changed

+308
-3
lines changed

7 files changed

+308
-3
lines changed

sql/main.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ select openapi_object(
4646
servers := openapi_server_objects(),
4747
paths := '{}',
4848
components := openapi_components_object(
49-
schemas := postgrest_tables_to_openapi_schema_components(schemas) || postgrest_composite_types_to_openapi_schema_components(schemas)
49+
schemas := postgrest_tables_to_openapi_schema_components(schemas) || postgrest_composite_types_to_openapi_schema_components(schemas),
50+
parameters := postgrest_get_query_params() || postgrest_get_headers()
5051
)
5152
)
5253
from postgrest_get_schema_description(schemas[1]) sd;
5354
$$;
54-

sql/openapi.sql

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
-- Functions to build the the OpenAPI output
1+
-- Functions and types to build the the OpenAPI output
2+
3+
-- TODO: create enum for openapi type e.g. string, number, etc.
4+
create type parameter_object_in as enum ('query', 'header', 'path', 'cookie');
5+
create type parameter_object_style as enum ('simple', 'form');
26

37
create or replace function openapi_object(
48
openapi text,
@@ -180,3 +184,34 @@ select json_build_object(
180184
'$ref', '#/components/schemas/' || ref
181185
);
182186
$$;
187+
188+
create or replace function openapi_parameter_object(
189+
name text,
190+
"in" parameter_object_in,
191+
description text default null,
192+
required boolean default null,
193+
deprecated boolean default null,
194+
allowEmptyValue boolean default null,
195+
style parameter_object_style default null,
196+
explode boolean default null,
197+
"schema" jsonb default null,
198+
example jsonb default null,
199+
examples jsonb default null
200+
)
201+
returns jsonb language sql as
202+
$$
203+
-- TODO: Add missing logic between fields (e.g. example and examples are mutually exclusive)
204+
select jsonb_build_object(
205+
'name', name,
206+
'in', "in",
207+
'description', description,
208+
'required', required,
209+
'deprecated', deprecated,
210+
'allowEmptyValue', allowEmptyValue,
211+
'style', style,
212+
'explode', explode,
213+
'schema', "schema",
214+
'example', example,
215+
'examples', examples
216+
)
217+
$$;

sql/postgrest.sql

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,3 +509,228 @@ returns text language sql as
509509
$$
510510
select '11.0.1 (4197d2f)'
511511
$$;
512+
513+
create or replace function postgrest_get_query_params ()
514+
returns jsonb language sql as
515+
$$
516+
select jsonb_object_agg(name, param_object) from unnest(
517+
array['select','order', 'limit', 'offset', 'on_conflict', 'columns', 'or', 'and', 'not.or', 'not.and'],
518+
array[
519+
openapi_parameter_object(
520+
name := 'select',
521+
"in" := 'query',
522+
description := 'Vertical filtering of columns',
523+
explode := false,
524+
schema := openapi_schema_object(
525+
type := 'array',
526+
items := openapi_schema_object(type := 'string')
527+
)
528+
),
529+
openapi_parameter_object(
530+
name := 'order',
531+
"in" := 'query',
532+
description := 'Ordering by column',
533+
explode := false,
534+
schema := openapi_schema_object(
535+
type := 'array',
536+
items := openapi_schema_object(type := 'string')
537+
)
538+
),
539+
openapi_parameter_object(
540+
name := 'limit',
541+
"in" := 'query',
542+
description := 'Limit the number of rows returned',
543+
explode := false,
544+
schema := openapi_schema_object(
545+
type := 'integer'
546+
)
547+
),
548+
openapi_parameter_object(
549+
name := 'offset',
550+
"in" := 'query',
551+
description := 'Skip a certain number of rows',
552+
explode := false,
553+
schema := openapi_schema_object(
554+
type := 'integer'
555+
)
556+
),
557+
openapi_parameter_object(
558+
name := 'on_conflict',
559+
"in" := 'query',
560+
description := 'Columns that resolve the upsert conflict',
561+
explode := false,
562+
schema := openapi_schema_object(
563+
type := 'string'
564+
)
565+
),
566+
openapi_parameter_object(
567+
name := 'columns',
568+
"in" := 'query',
569+
description := 'Specify which keys from the payload will be inserted',
570+
explode := false,
571+
schema := openapi_schema_object(
572+
type := 'string'
573+
)
574+
),
575+
openapi_parameter_object(
576+
name := 'or',
577+
"in" := 'query',
578+
description := 'Logical operator to combine filters using OR',
579+
explode := false,
580+
schema := openapi_schema_object(
581+
type := 'string'
582+
)
583+
),
584+
openapi_parameter_object(
585+
name := 'and',
586+
"in" := 'query',
587+
description := 'Logical operator to combine filters using AND (the default for query params)',
588+
explode := false,
589+
schema := openapi_schema_object(
590+
type := 'string'
591+
)
592+
),
593+
openapi_parameter_object(
594+
name := 'not.or',
595+
"in" := 'query',
596+
description := 'Negate the logical operator to combine filters using OR',
597+
explode := false,
598+
schema := openapi_schema_object(
599+
type := 'string'
600+
)
601+
),
602+
openapi_parameter_object(
603+
name := 'not.and',
604+
"in" := 'query',
605+
description := 'Negate the logical operator to combine filters using AND',
606+
explode := false,
607+
schema := openapi_schema_object(
608+
type := 'string'
609+
)
610+
)
611+
]
612+
) as _(name, param_object);
613+
$$;
614+
615+
create or replace function postgrest_get_headers ()
616+
returns jsonb language sql as
617+
$$
618+
select jsonb_object_agg(name, param_object) from unnest(
619+
array['preferParams', 'preferReturn', 'preferCount', 'preferResolution', 'preferTransaction', 'preferMissing', 'preferHandling', 'preferTimezone', 'preferMaxAffected', 'range'],
620+
array[
621+
openapi_parameter_object(
622+
name := 'Prefer',
623+
"in" := 'header',
624+
description := 'Send JSON as a single parameter',
625+
schema := openapi_schema_object(
626+
type := 'string',
627+
"enum" := jsonb_build_array(
628+
'params=single-object'
629+
)
630+
)
631+
),
632+
openapi_parameter_object(
633+
name := 'Prefer',
634+
"in" := 'header',
635+
description := 'Return information of the affected resource',
636+
schema := openapi_schema_object(
637+
type := 'string',
638+
"enum" := jsonb_build_array(
639+
'return=minimal',
640+
'return=headers-only',
641+
'return=representation'
642+
)
643+
)
644+
),
645+
openapi_parameter_object(
646+
name := 'Prefer',
647+
"in" := 'header',
648+
description := 'Get the total size of the table',
649+
schema := openapi_schema_object(
650+
type := 'string',
651+
"enum" := jsonb_build_array(
652+
'count=exact',
653+
'count=planned',
654+
'count=estimated'
655+
)
656+
)
657+
),
658+
openapi_parameter_object(
659+
name := 'Prefer',
660+
"in" := 'header',
661+
description := 'Handle duplicates in an upsert',
662+
schema := openapi_schema_object(
663+
type := 'string',
664+
"enum" := jsonb_build_array(
665+
'resolution=merge-duplicates',
666+
'resolution=ignore-duplicates'
667+
)
668+
)
669+
),
670+
openapi_parameter_object(
671+
name := 'Prefer',
672+
"in" := 'header',
673+
description := 'Specify how to end a transaction',
674+
schema := openapi_schema_object(
675+
type := 'string',
676+
"enum" := jsonb_build_array(
677+
'tx=commit',
678+
'tx=rollback'
679+
)
680+
)
681+
),
682+
openapi_parameter_object(
683+
name := 'Prefer',
684+
"in" := 'header',
685+
description := 'Handle null values in bulk inserts',
686+
schema := openapi_schema_object(
687+
type := 'string',
688+
"enum" := jsonb_build_array(
689+
'missing=default',
690+
'missing=null'
691+
)
692+
)
693+
),
694+
openapi_parameter_object(
695+
name := 'Prefer',
696+
"in" := 'header',
697+
description := 'Handle invalid preferences',
698+
schema := openapi_schema_object(
699+
type := 'string',
700+
"enum" := jsonb_build_array(
701+
'handling=strict',
702+
'handling=lenient'
703+
)
704+
)
705+
),
706+
openapi_parameter_object(
707+
name := 'Prefer',
708+
"in" := 'header',
709+
description := 'Specify the time zone',
710+
example := '"timezone=UTC"',
711+
schema := openapi_schema_object(
712+
-- The time zones can be queried, but there are ~500 of them. It could slow down the UIs (unverified).
713+
type := 'string'
714+
)
715+
),
716+
openapi_parameter_object(
717+
name := 'Prefer',
718+
"in" := 'header',
719+
description := 'Limit the number of affected resources',
720+
example := '"max-affected=5"',
721+
schema := openapi_schema_object(
722+
type := 'string'
723+
)
724+
),
725+
openapi_parameter_object(
726+
name := 'Range',
727+
"in" := 'header',
728+
description := 'For limits and pagination',
729+
example := '"5-10"',
730+
schema := openapi_schema_object(
731+
type := 'string'
732+
)
733+
)
734+
]
735+
) as _(name, param_object);
736+
$$;

test/expected/parameters.out

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
-- shows common query parameters
2+
select *
3+
from jsonb_each(get_postgrest_openapi_spec('{public}')->'components'->'parameters')
4+
where key in ('select', 'order', 'limit', 'offset', 'on_conflict', 'columns', 'or', 'and', 'not.or', 'not.and');
5+
key | value
6+
-------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
7+
or | {"in": "query", "name": "or", "schema": {"type": "string"}, "explode": false, "description": "Logical operator to combine filters using OR"}
8+
and | {"in": "query", "name": "and", "schema": {"type": "string"}, "explode": false, "description": "Logical operator to combine filters using AND (the default for query params)"}
9+
limit | {"in": "query", "name": "limit", "schema": {"type": "integer"}, "explode": false, "description": "Limit the number of rows returned"}
10+
order | {"in": "query", "name": "order", "schema": {"type": "array", "items": {"type": "string"}}, "explode": false, "description": "Ordering by column"}
11+
not.or | {"in": "query", "name": "not.or", "schema": {"type": "string"}, "explode": false, "description": "Negate the logical operator to combine filters using OR"}
12+
offset | {"in": "query", "name": "offset", "schema": {"type": "integer"}, "explode": false, "description": "Skip a certain number of rows"}
13+
select | {"in": "query", "name": "select", "schema": {"type": "array", "items": {"type": "string"}}, "explode": false, "description": "Vertical filtering of columns"}
14+
columns | {"in": "query", "name": "columns", "schema": {"type": "string"}, "explode": false, "description": "Specify which keys from the payload will be inserted"}
15+
not.and | {"in": "query", "name": "not.and", "schema": {"type": "string"}, "explode": false, "description": "Negate the logical operator to combine filters using AND"}
16+
on_conflict | {"in": "query", "name": "on_conflict", "schema": {"type": "string"}, "explode": false, "description": "Columns that resolve the upsert conflict"}
17+
(10 rows)
18+
19+
-- shows common headers
20+
select *
21+
from jsonb_each(get_postgrest_openapi_spec('{public}')->'components'->'parameters')
22+
where key in ('preferParams', 'preferReturn', 'preferCount', 'preferResolution', 'preferTransaction', 'preferMissing', 'preferHandling', 'preferTimezone', 'preferMaxAffected', 'range');
23+
key | value
24+
-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
25+
range | {"in": "header", "name": "Range", "schema": {"type": "string"}, "example": "5-10", "description": "For limits and pagination"}
26+
preferCount | {"in": "header", "name": "Prefer", "schema": {"enum": ["count=exact", "count=planned", "count=estimated"], "type": "string"}, "description": "Get the total size of the table"}
27+
preferParams | {"in": "header", "name": "Prefer", "schema": {"enum": ["params=single-object"], "type": "string"}, "description": "Send JSON as a single parameter"}
28+
preferReturn | {"in": "header", "name": "Prefer", "schema": {"enum": ["return=minimal", "return=headers-only", "return=representation"], "type": "string"}, "description": "Return information of the affected resource"}
29+
preferMissing | {"in": "header", "name": "Prefer", "schema": {"enum": ["missing=default", "missing=null"], "type": "string"}, "description": "Handle null values in bulk inserts"}
30+
preferHandling | {"in": "header", "name": "Prefer", "schema": {"enum": ["handling=strict", "handling=lenient"], "type": "string"}, "description": "Handle invalid preferences"}
31+
preferTimezone | {"in": "header", "name": "Prefer", "schema": {"type": "string"}, "example": "timezone=UTC", "description": "Specify the time zone"}
32+
preferResolution | {"in": "header", "name": "Prefer", "schema": {"enum": ["resolution=merge-duplicates", "resolution=ignore-duplicates"], "type": "string"}, "description": "Handle duplicates in an upsert"}
33+
preferMaxAffected | {"in": "header", "name": "Prefer", "schema": {"type": "string"}, "example": "max-affected=5", "description": "Limit the number of affected resources"}
34+
preferTransaction | {"in": "header", "name": "Prefer", "schema": {"enum": ["tx=commit", "tx=rollback"], "type": "string"}, "description": "Specify how to end a transaction"}
35+
(10 rows)
36+
File renamed without changes.

test/sql/parameters.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-- shows common query parameters
2+
select *
3+
from jsonb_each(get_postgrest_openapi_spec('{public}')->'components'->'parameters')
4+
where key in ('select', 'order', 'limit', 'offset', 'on_conflict', 'columns', 'or', 'and', 'not.or', 'not.and');
5+
6+
-- shows common headers
7+
select *
8+
from jsonb_each(get_postgrest_openapi_spec('{public}')->'components'->'parameters')
9+
where key in ('preferParams', 'preferReturn', 'preferCount', 'preferResolution', 'preferTransaction', 'preferMissing', 'preferHandling', 'preferTimezone', 'preferMaxAffected', 'range');
File renamed without changes.

0 commit comments

Comments
 (0)