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
_10@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
_10create table "BlogPost"(_10 id int primary key,_10 ..._10);
results in GraphQL type names like
_10BlogPost_10BlogPostEdge_10BlogPostConnection_10...
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:
_10comment on schema <schema_name> is e'@graphql({"inflect_names": true})';
for example
_10comment on schema public is e'@graphql({"inflect_names": true})';_10_10create table blog_post(_10 id int primary key,_10 ..._10);
similarly would generated the GraphQL type names
_10BlogPost_10BlogPostEdge_10BlogPostConnection_10...
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:
_10comment 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.
_10type BlogPostConnection {_10 edges: [BlogPostEdge!]!_10 pageInfo: PageInfo!_10_10 """The total number of records matching the `filter` criteria"""_10 totalCount: Int! # this field_10}
to enable totalCount
for a table, use the directive
_10comment on table "BlogPost" is e'@graphql({"totalCount": {"enabled": true}})';
for example
_10create table "BlogPost"(_10 id serial primary key,_10 email varchar(255) not null_10);_10comment 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.
_10create table account(_10 id serial primary key_10);_10_10comment on table public.account is_10e'@graphql({"name": "AccountHolder"})';
results in:
_10type AccountHolder { # previously: "Account"_10 id: Int!_10}
Column's Field Name
Use the "name"
JSON key to override a column's field name.
_10create table public."Account"(_10 id serial primary key,_10 email text_10);_10_10comment on column "Account".email is_10e'@graphql({"name": "emailAddress"})';
results in:
_10type Account {_10 nodeId: ID!_10 id: Int!_10 emailAddress: String! # previously "email"_10}
Computed Field
Use the "name"
JSON key to override a computed field's name.
_18create table "Account"(_18 id serial primary key,_18 "firstName" varchar(255) not null,_18 "lastName" varchar(255) not null_18);_18_18-- Extend with function_18create function public."_fullName"(rec public."Account")_18 returns text_18 immutable_18 strict_18 language sql_18as $$_18 select format('%s %s', rec."firstName", rec."lastName")_18$$;_18_18comment on function public._full_name is_18e'@graphql({"name": "displayName"})';
results in:
_10type Account {_10 nodeId: ID!_10 id: Int!_10 firstName: String!_10 lastName: String!_10 displayName: String # previously "fullName"_10}
Relationship's Field
Use the "local_name"
and "foreign_name"
JSON keys to override a relationship's inbound and outbound field names.
_14create table "Account"(_14 id serial primary key_14);_14_14create table "Post"(_14 id serial primary key,_14 "accountId" integer not null references "Account"(id),_14 title text not null,_14 body text_14);_14_14comment on constraint post_owner_id_fkey_14 on "Post"_14 is E'@graphql({"foreign_name": "author", "local_name": "posts"})';
results in:
_20type Post {_20 nodeId: ID!_20 id: Int!_20 accountId: Int!_20 title: String!_20 body: String!_20 author: Account # was "account"_20}_20_20type Account {_20 id: Int!_20 posts( # was "postCollection"_20 after: Cursor,_20 before: Cursor,_20 filter: PostFilter,_20 first: Int,_20 last: Int,_20 orderBy: [PostOrderBy!]_20 ): PostConnection_20}
Description
Tables, Columns, and Functions accept a description
directive to populate user defined descriptions in the GraphQL schema.
_10create table "Account"(_10 id serial primary key_10);_10_10comment on table public.account_10is e'@graphql({"description": "A User Account"})';_10_10comment on column public.account.id_10is e'@graphql({"description": "The primary key identifier"})';
_10"""A User Account"""_10type Account implements Node {_10_10 """The primary key identifier"""_10 id: Int!_10}
Enum Variant
If a variant of a Postgres enum does not conform to GraphQL naming conventions, introspection returns an error:
For example:
_10create type "Algorithm" as enum ('aead-ietf');
causes the error:
_10{_10 "errors": [_10 {_10 "message": "Names must only contain [_a-zA-Z0-9] but \"aead-ietf\" does not.",_10 }_10 ]_10}
To resolve this problem, rename the invalid SQL enum variant to a GraphQL compatible name:
_10alter type "Algorithm" rename value 'aead-ietf' to 'AEAD_IETF';
or, add a comment directive to remap the enum variant in the GraphQL API
_10comment on type "Algorithm" is '@graphql({"mappings": {"aead-ietf": "AEAD_IETF"}})';
Which both result in the GraphQL enum:
_10enum Algorithm {_10 AEAD_IETF_10}