Configuration & Customization
Extra configuration options can be set on SQL entities using comment directives.
Extra configuration options can be set on SQL entities using comment directives.
Comment Directives
Comment directives are snippets of configuration associated with SQL entities that alter how those entities behave.
The format of a comment directive is
1@graphql(<JSON>)
Inflection
Inflection describes how SQL entities' names are transformed into GraphQL type and field names. By default, inflection is disabled and SQL names are literally interpolated such that
1234create table "BlogPost"( id int primary key, ...);
results in GraphQL type names like
1234BlogPostBlogPostEdgeBlogPostConnection...
Since snake case is a common casing structure for SQL types, pg_graphql
support basic inflection from snake_case
to PascalCase
for type names, and snake_case
to camelCase
for field names to match Javascript conventions.
The inflection directive can be applied at the schema level with:
1comment on schema <schema_name> is e'@graphql({"inflect_names": true})';
for example
123456comment on schema public is e'@graphql({"inflect_names": true})';create table blog_post( id int primary key, ...);
similarly would generated the GraphQL type names
1234BlogPostBlogPostEdgeBlogPostConnection...
For more fine grained adjustments to reflected names, see renaming.
Max Rows
The default page size for collections is 30 entries. To adjust the number of entries on each page, set a max_rows
directive on the relevant schema entity.
For example, to increase the max rows per page for each table in the public
schema:
1comment on schema public is e'@graphql({"max_rows": 100})';
totalCount
totalCount
is an opt-in field that extends a table's Connection type. It provides a count of the rows that match the query's filters, and ignores pagination arguments.
1234567type BlogPostConnection { edges: [BlogPostEdge!]! pageInfo: PageInfo! """The total number of records matching the `filter` criteria""" totalCount: Int! # this field}
to enable totalCount
for a table, use the directive
1comment on table "BlogPost" is e'@graphql({"totalCount": {"enabled": true}})';
for example
12345create table "BlogPost"( id serial primary key, email varchar(255) not null);comment on table "BlogPost" is e'@graphql({"totalCount": {"enabled": true}})';
Renaming
Table's Type
Use the "name"
JSON key to override a table's type name.
123456create table account( id serial primary key);comment on table public.account ise'@graphql({"name": "AccountHolder"})';
results in:
123type AccountHolder { # previously: "Account" id: Int!}
Column's Field Name
Use the "name"
JSON key to override a column's field name.
1234567create table public."Account"( id serial primary key, email text);comment on column "Account".email ise'@graphql({"name": "emailAddress"})';
results in:
12345type Account { nodeId: ID! id: Int! emailAddress: String! # previously "email"}
Computed Field
Use the "name"
JSON key to override a computed field's name.
123456789101112131415161718create table "Account"( id serial primary key, "firstName" varchar(255) not null, "lastName" varchar(255) not null);-- Extend with functioncreate function public."_fullName"(rec public."Account") returns text immutable strict language sqlas $$ select format('%s %s', rec."firstName", rec."lastName")$$;comment on function public._full_name ise'@graphql({"name": "displayName"})';
results in:
1234567type Account { nodeId: ID! id: Int! firstName: String! lastName: String! displayName: String # previously "fullName"}
Relationship's Field
Use the "local_name"
and "foreign_name"
JSON keys to override a relationship's inbound and outbound field names.
1234567891011121314create table "Account"( id serial primary key);create table "Post"( id serial primary key, "accountId" integer not null references "Account"(id), title text not null, body text);comment on constraint post_owner_id_fkey on "Post" is E'@graphql({"foreign_name": "author", "local_name": "posts"})';
results in:
1234567891011121314151617181920type Post { nodeId: ID! id: Int! accountId: Int! title: String! body: String! author: Account # was "account"}type Account { id: Int! posts( # was "postCollection" after: Cursor, before: Cursor, filter: PostFilter, first: Int, last: Int, orderBy: [PostOrderBy!] ): PostConnection}
Description
Tables, Columns, and Functions accept a description
directive to populate user defined descriptions in the GraphQL schema.
123456789create table "Account"( id serial primary key);comment on table public.accountis e'@graphql({"description": "A User Account"})';comment on column public.account.idis e'@graphql({"description": "The primary key identifier"})';
123456"""A User Account"""type Account implements Node { """The primary key identifier""" id: Int!}
Enum Variant
If a variant of a Postgres enum does not conform to GraphQL naming conventions, introspection returns an error:
For example:
1create type "Algorithm" as enum ('aead-ietf');
causes the error:
1234567{ "errors": [ { "message": "Names must only contain [_a-zA-Z0-9] but \"aead-ietf\" does not.", } ]}
To resolve this problem, rename the invalid SQL enum variant to a GraphQL compatible name:
1alter type "Algorithm" rename value 'aead-ietf' to 'AEAD_IETF';
or, add a comment directive to remap the enum variant in the GraphQL API
1comment on type "Algorithm" is '@graphql({"mappings": {"aead-ietf": "AEAD_IETF"}})';
Which both result in the GraphQL enum:
123enum Algorithm { AEAD_IETF}