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:
_10create view "Person" as_10 select_10 id,_10 name_10 from_10 "Account";_10_10comment 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:
_10type Person {_10 nodeId: ID!_10 id: Int!_10 name: String!_10}
Values of the primary key column/s must be unique within the table. If they are not unique, you will experience inconsistent behavior with
ID!
types, sorting, and pagination.
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:
_25create table "Account"(_25 id serial primary key,_25 name text not null_25);_25_25create 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_25comment 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
_10alter table "EmailAddress"_10 add constraint fkey_email_address_to_account_10 foreign key ("accountId")_10 references "Account" ("id");_10_10comment on constraint fkey_email_address_to_account_10 on "EmailAddress"_10 is E'@graphql({"foreign_name": "account", "local_name": "addresses"})';
yielding the GraphQL types:
_22type 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_22type EmailAddress {_22 nodeId: ID!_22 id: Int!_22 isPrimary: Boolean!_22 address: String!_22 accountId: Int!_22 account: Account!_22}