GraphQL

Views

Using Postgres Views with GraphQL.

Views, materialized views, and foreign tables can be exposed with pg_graphql.

Primary Keys (Required)

A primary key is required for an entity to be reflected in the GraphQL schema. Tables can define primary keys with SQL DDL, but primary keys are not available for views, materialized views, or foreign tables. For those entities, you can set a "fake" primary key with a comment directive.


_10
{"primary_key_columns": [<column_name_1>, ..., <column_name_n>]}

For example:


_10
create view "Person" as
_10
select
_10
id,
_10
name
_10
from
_10
"Account";
_10
_10
comment on view "Person" is e'@graphql({"primary_key_columns": ["id"]})';

tells pg_graphql to treat "Person".id as the primary key for the Person entity resulting in the following GraphQL type:


_10
type Person {
_10
nodeId: ID!
_10
id: Int!
_10
name: String!
_10
}

Updatable views are reflected in the Query and Mutation types identically to tables. Non-updatable views are read-only and accessible via the Query type only.

Relationships

pg_graphql identifies relationships among entities by inspecting foreign keys. Views, materialized views, and foreign tables do not support foreign keys. For this reason, relationships can also be defined in comment directive using the structure:


_12
{
_12
"foreign_keys": [
_12
{
_12
"local_name": "foo", // optional
_12
"local_columns": ["account_id"],
_12
"foreign_name": "bar", // optional
_12
"foreign_schema": "public",
_12
"foreign_table": "account",
_12
"foreign_columns": ["id"]
_12
}
_12
]
_12
}

For example:


_25
create table "Account"(
_25
id serial primary key,
_25
name text not null
_25
);
_25
_25
create table "EmailAddress"(
_25
id serial primary key,
_25
"accountId" int not null, -- note: no foreign key
_25
"isPrimary" bool not null,
_25
address text not null
_25
);
_25
_25
comment on table "EmailAddress" is e'
_25
@graphql({
_25
"foreign_keys": [
_25
{
_25
"local_name": "addresses",
_25
"local_columns": ["accountId"],
_25
"foreign_name": "account",
_25
"foreign_schema": "public",
_25
"foreign_table": "Account",
_25
"foreign_columns": ["id"]
_25
}
_25
]
_25
})';

defines a relationship equivalent to the following foreign key


_10
alter table "EmailAddress"
_10
add constraint fkey_email_address_to_account
_10
foreign key ("accountId")
_10
references "Account" ("id");
_10
_10
comment on constraint fkey_email_address_to_account
_10
on "EmailAddress"
_10
is E'@graphql({"foreign_name": "account", "local_name": "addresses"})';

yielding the GraphQL types:


_22
type Account {
_22
nodeId: ID!
_22
id: Int!
_22
name: String!
_22
addresses(
_22
after: Cursor,
_22
before: Cursor,
_22
filter: EmailAddressFilter,
_22
first: Int,
_22
last: Int,
_22
orderBy: [EmailAddressOrderBy!]
_22
): EmailAddressConnection
_22
}
_22
_22
type EmailAddress {
_22
nodeId: ID!
_22
id: Int!
_22
isPrimary: Boolean!
_22
address: String!
_22
accountId: Int!
_22
account: Account!
_22
}