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 a relationships 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}