### Launch Interactive PSQL Development Environment Source: https://supabase.github.io/pg_graphql/contributing Starts a PostgreSQL instance with pg_graphql installed, enabling interactive development and experimentation. ```bash cargo pgrx run pg16 ``` -------------------------------- ### Local Supabase Development Setup Source: https://supabase.github.io/pg_graphql/supabase The output of 'supabase start' provides essential URLs for interacting with your local Supabase project, including the GraphQL endpoint and Supabase Studio. ```bash >supabase start ... Started supabase local development setup. GraphQL URL: http://localhost:54321/graphql/v1 <-- GraphQL endpoint DB URL: ... Studio URL: http://localhost:54323 <-- Supabase Studio Inbucket URL: ... JWT secret: ... anon key: eyJhbGciOiJIUzI1... <-- API_KEY service_role key: ... ``` -------------------------------- ### Build, Install, and Test pg_graphql Source: https://supabase.github.io/pg_graphql/contributing Combines building, installing, and running all tests for pg_graphql in a single command. ```bash $ cargo pgrx install; ./bin/installcheck ``` -------------------------------- ### Install Documentation Dependencies Source: https://supabase.github.io/pg_graphql/contributing Installs the necessary Python packages for building and serving the project documentation. ```bash pip install -r docs/requirements_docs.txt ``` -------------------------------- ### Install pg_graphql with Cargo Source: https://supabase.github.io/pg_graphql/contributing Builds and installs pg_graphql from source into the specified Postgres instance. Run this after making Rust code changes. ```bash cargo pgrx install ``` -------------------------------- ### Serve Documentation Locally Source: https://supabase.github.io/pg_graphql/contributing Starts a local web server to preview the documentation. Visit http://127.0.0.1:8000/pg_graphql/ to view. ```bash mkdocs serve ``` -------------------------------- ### Example Table with totalCount Enabled Source: https://supabase.github.io/pg_graphql/configuration Defines a 'BlogPost' table and enables the `totalCount` field using a comment directive. This setup allows for efficient row counting. ```sql create table "BlogPost"( id serial primary key, email varchar(255) not null ); comment on table "BlogPost" is e'@graphql({"totalCount": {"enabled": true}});' ``` -------------------------------- ### Example GraphQL Query Source: https://supabase.github.io/pg_graphql/supabase A sample GraphQL query to fetch the first account and its ID. ```graphql { accountCollection(first: 1) { edges { node { id } } } } ``` -------------------------------- ### SQL Setup for BigFloat Example Source: https://supabase.github.io/pg_graphql/api Sets up a PostgreSQL table named 'GeneralLedger' with an 'amount' column of type numeric(10,2) and inserts a sample record. This demonstrates the SQL structure that would utilize the BigFloat scalar in GraphQL. ```sql create table "GeneralLedger"( id serial primary key, amount numeric(10,2) ); insert into "GeneralLedger"(amount) values (22.15); ``` -------------------------------- ### Blog Aggregate Query Response Example Source: https://supabase.github.io/pg_graphql/api Provides an example JSON response for a blog aggregate query, showing calculated counts, sums, averages, minimums, and maximums. ```json { "data": { "blogCollection": { "aggregate": { "count": 5, "sum": { "rating": 23, "visits": 1250 }, "avg": { "rating": 4.6 }, "min": { "createdAt": "2022-01-15T08:30:00Z", "title": "A Blog Post" }, "max": { "rating": 5, "updatedAt": "2023-04-22T14:15:30Z" } } } } } ``` -------------------------------- ### Basic Filtering Example Source: https://supabase.github.io/pg_graphql/api Demonstrates a basic filter to retrieve blog posts. ```graphql { blogCollection { edges { node { id name description createdAt } } } } ``` ```json { "data": { "blogCollection": { "edges": [ { "node": { "id": 1, "name": "A: Blog 1", "createdAt": "2023-07-24T04:01:09.882781", "description": "a desc1" }, "cursor": "WzFd" }, { "node": { "id": 2, "name": "A: Blog 2", "createdAt": "2023-07-24T04:01:09.882781", "description": "a desc2" }, "cursor": "WzJd" } ] } } } ``` -------------------------------- ### Keyset Pagination Example (Backward) Source: https://supabase.github.io/pg_graphql/api Demonstrates how to paginate backward through a collection. This is achieved by substituting `first` with `last` and `after` with `before` in the query arguments. ```APIDOC ## Query blogCollection with Keyset Pagination (Backward) ### Description Retrieves a collection of blogs, paginated backwards. Use `last` to specify the number of items and `before` with a cursor to fetch previous pages. ### Method POST ### Endpoint /graphql ### Parameters #### Query Parameters - **last** (Int) - Optional - Query the last `n` records in the collection. - **before** (Cursor) - Optional - Query values in the collection before the provided cursor. ### Request Example ```json { "query": "query BlogCollectionBackward($before: Cursor) {\n blogCollection(last: 2, before: $before) {\n pageInfo {\n startCursor\n endCursor\n hasNextPage\n hasPreviousPage\n }\n edges {\n cursor\n node {\n id\n }\n }\n }\n}", "variables": { "before": "WzJd" } } ``` ### Response #### Success Response (200) - **blogCollection** (BlogConnection!) - The connection object containing edges and page info. - **pageInfo** (PageInfo!) - Metadata about the current page of results. - **startCursor** (String) - The unique identifier of the first record within the query. - **endCursor** (String) - The unique identifier of the last record within the query. - **hasNextPage** (Boolean!) - Indicates if another page of content is available. - **hasPreviousPage** (Boolean!) - Indicates if another page of content is available. - **edges** (BlogEdge!) - A list of blog edges, each containing a cursor and a node. - **cursor** (String!) - The cursor for the blog edge. - **node** (Blog!) - The blog node. - **id** (ID!) - The unique identifier of the blog. #### Response Example ```json { "data": { "blogCollection": { "edges": [ { "node": { "id": 1 }, "cursor": "WzFd" }, { "node": { "id": 2 }, "cursor": "WzJd" } ], "pageInfo": { "startCursor": "WzFd", "endCursor": "WzJd", "hasNextPage": false, "hasPreviousPage": true } } } } ``` ``` -------------------------------- ### Launch the Demo Environment Source: https://supabase.github.io/pg_graphql/quickstart Use docker-compose to launch the demo environment, which includes a database, webserver, and the GraphiQL IDE. Ensure you have git and docker-compose installed. ```bash docker-compose up ``` -------------------------------- ### SQL Setup for BigInt Data Type Source: https://supabase.github.io/pg_graphql/api Creates a 'Person' table with a 'bigserial' primary key and inserts sample data. ```sql create table "Person"( id bigserial primary key, name text ); insert into "Person"(name) values ('J. Bazworth'); ``` -------------------------------- ### Clone and Install pg_graphql Source: https://supabase.github.io/pg_graphql/installation Clone the pg_graphql repository and install it using cargo pgrx. Ensure compatibility with the pgrx version used by pg_graphql. ```bash git clone https://github.com/supabase/pg_graphql.git cd pg_graphql cargo pgrx install --release ``` -------------------------------- ### Example GraphQL Variables Source: https://supabase.github.io/pg_graphql/supabase An example of an empty JSON object for GraphQL query variables. ```json {} ``` -------------------------------- ### Start PostgreSQL 17 Database Source: https://supabase.github.io/pg_graphql/installation Start the PostgreSQL 17 database managed by pgrx. This command is used to run the database instance. ```bash cargo pgrx start pg17 ``` -------------------------------- ### GraphQL Query for User Collection Source: https://supabase.github.io/pg_graphql/api Example GraphQL query to fetch user configurations. ```graphql { userCollection { edges { node { config } } } } ``` -------------------------------- ### Usage Example for graphql.resolve Source: https://supabase.github.io/pg_graphql/sql_interface Demonstrates how to use the graphql.resolve function to query data from a PostgreSQL table after creating the pg_graphql extension. ```sql -- Create the extension graphqldb= create extension pg_graphql; CREATE EXTENSION -- Create an example table graphqldb= create table book(id int primary key, title text); CREATE TABLE -- Insert a record graphqldb= insert into book(id, title) values (1, 'book 1'); INSERT 0 1 -- Query the table via GraphQL graphqldb= select graphql.resolve($$ query { bookCollection { edges { node { id } } } }$$ ); resolve ---------------------------------------------------------------------- {"data": {"bookCollection": {"edges": [{"node": {"id": 1}}]}, "errors": []} ``` -------------------------------- ### GraphQL Node Query Response Example Source: https://supabase.github.io/pg_graphql/api Example JSON response when querying the 'node' interface, showing the retrieved fields for a 'Blog' record. ```json { "data": { "node": { "name": "Some Blog", "nodeId": "WyJwdWJsaWMiLCAiYmxvZyIsIDFd", "description": "Description of Some Blog" } } } ``` -------------------------------- ### SQL Setup for One-to-One Relationship Source: https://supabase.github.io/pg_graphql/api Defines 'EmailAddress' and 'Employee' tables with a unique foreign key constraint for a one-to-one relationship. ```sql create table "EmailAddress"( id serial primary key, address text unique not null ); create table "Employee"( id serial primary key, name text not null, email_address_id int unique references "EmailAddress"(id) ); ``` -------------------------------- ### GraphQL Query Example with Null Default Arguments Source: https://supabase.github.io/pg_graphql/functions Example of a GraphQL query calling the function where one argument is provided and the other defaults to null. ```graphql query { addNums(a: 42) } ``` -------------------------------- ### GraphQL Authorization Header Source: https://supabase.github.io/pg_graphql/supabase Example of how to pass an Authorization header for user authentication with the GraphQL API. ```bash -H 'Authorization: Bearer ' ``` -------------------------------- ### GraphQL Query Example with Default Arguments Source: https://supabase.github.io/pg_graphql/functions Example of a GraphQL query calling the function, omitting one argument to use its default value. ```graphql query { addNums(b: 20) } ``` -------------------------------- ### SQL Setup for One-to-Many Relationship (Blog to BlogPost) Source: https://supabase.github.io/pg_graphql/api SQL to create 'Blog' and 'BlogPost' tables, establishing a one-to-many relationship where 'BlogPost' has a foreign key referencing 'Blog'. ```sql create table "Blog"( id serial primary key, name varchar(255) not null ); create table "BlogPost"( id serial primary key, "blogId" integer not null references "Blog"(id), title varchar(255) not null, body varchar(10000) ); ``` -------------------------------- ### Example JSON Response for Ordered Blog Collection Source: https://supabase.github.io/pg_graphql/api Shows the expected JSON response when querying the blog collection with a specified order. ```json { "data": { "blogCollection": { "edges": [ { "node": { "id": 4 } }, { "node": { "id": 3 } }, { "node": { "id": 2 } }, { "node": { "id": 1 } } ] } } } ``` -------------------------------- ### Example JSON Response for Blog by Primary Key Source: https://supabase.github.io/pg_graphql/api Shows the expected JSON response when a blog record is found by its primary key. ```json { "data": { "blogByPk": { "id": 1, "name": "Some Blog", "description": "Description of Some Blog" } } } ``` -------------------------------- ### Example GraphQL Query for Non-existent Blog by Primary Key Source: https://supabase.github.io/pg_graphql/api Demonstrates querying for a blog with an ID that does not exist in the database. ```graphql { blogByPk( id: 999 ) { id name description } } ``` -------------------------------- ### Run All Tests Source: https://supabase.github.io/pg_graphql/contributing Executes all defined tests to ensure the integrity of pg_graphql. This command should be run after installation. ```bash ./bin/installcheck ``` -------------------------------- ### SQL Setup for JSONB Data Type Source: https://supabase.github.io/pg_graphql/api Creates a 'User' table with a 'config' column of type jsonb and inserts sample data. ```sql create table "User"( id bigserial primary key, config jsonb ); insert into "User"(config) values (jsonb_build_object('palette', 'dark-mode')); ``` -------------------------------- ### Run a Single Test Source: https://supabase.github.io/pg_graphql/contributing Executes a specific test case by providing its name to the installcheck command. For example, to run the test in './test/sql/aliases.sql'. ```bash ./bin/installcheck aliases ``` -------------------------------- ### Keyset Pagination Example (Forward) Source: https://supabase.github.io/pg_graphql/api Demonstrates how to paginate forward through a collection using `first` and `after` arguments. The first page query has `after` as null or absent. Subsequent pages use the `endCursor` from the previous response as the `after` argument. ```APIDOC ## Query blogCollection with Keyset Pagination (Forward) ### Description Retrieves a collection of blogs, paginated forwards. Use `first` to specify the number of items and `after` with a cursor to fetch subsequent pages. ### Method POST ### Endpoint /graphql ### Parameters #### Query Parameters - **first** (Int) - Optional - Query the first `n` records in the collection. - **after** (Cursor) - Optional - Query values in the collection after the provided cursor. ### Request Example ```json { "query": "query BlogCollectionForward($after: Cursor) {\n blogCollection(first: 2, after: $after) {\n pageInfo {\n startCursor\n endCursor\n hasNextPage\n hasPreviousPage\n }\n edges {\n cursor\n node {\n id\n }\n }\n }\n}", "variables": { "after": null } } ``` ### Response #### Success Response (200) - **blogCollection** (BlogConnection!) - The connection object containing edges and page info. - **pageInfo** (PageInfo!) - Metadata about the current page of results. - **startCursor** (String) - The unique identifier of the first record within the query. - **endCursor** (String) - The unique identifier of the last record within the query. - **hasNextPage** (Boolean!) - Indicates if another page of content is available. - **hasPreviousPage** (Boolean!) - Indicates if another page of content is available. - **edges** (BlogEdge!) - A list of blog edges, each containing a cursor and a node. - **cursor** (String!) - The cursor for the blog edge. - **node** (Blog!) - The blog node. - **id** (ID!) - The unique identifier of the blog. #### Response Example ```json { "data": { "blogCollection": { "edges": [ { "node": { "id": 1 }, "cursor": "WzFd" }, { "node": { "id": 2 }, "cursor": "WzJd" } ], "pageInfo": { "startCursor": "WzFd", "endCursor": "WzJd", "hasNextPage": true, "hasPreviousPage": false } } } } ``` ``` -------------------------------- ### Example GraphQL Query for Blog by Primary Key Source: https://supabase.github.io/pg_graphql/api Demonstrates how to query for a specific blog record using its primary key (id). ```graphql { blogByPk( id: 1 ) { id name description } } ``` -------------------------------- ### GraphQL Query Response Example Source: https://supabase.github.io/pg_graphql/functions The expected JSON response from the GraphQL query when using default arguments. ```json { "data": { "addNums": 21 } } ``` -------------------------------- ### Example Type-Safe GraphQL Query with Apollo Source: https://supabase.github.io/pg_graphql/usage_with_apollo Fetch a list of todos using a type-safe GraphQL query document generated by GraphQL Code Generator. This example demonstrates using Apollo's `useQuery` hook and handling pagination with `fetchMore`. ```typescript import { useQuery } from '@apollo/client' import { graphql } from './gql' const allTodosQueryDocument = graphql(/* GraphQL */ ` query AllTodos($cursor: Cursor) { todosCollection(first: 10, after: $cursor) { edges { node { nodeId title } } pageInfo { endCursor hasNextPage } } } `) const TodoList = () => { const { data, fetchMore } = useQuery(allTodosQueryDocument) return ( <> {data?.thingsCollection?.edges.map(({ node }) => ( ))} {data?.thingsCollection?.pageInfo.hasNextPage && ( )} ) } export default TodoList ``` -------------------------------- ### Offset Pagination Example Source: https://supabase.github.io/pg_graphql/api Demonstrates how to paginate through a collection using `first` and `offset`. This method is similar to SQL's `limit` and `offset` but is less efficient for large offsets. ```APIDOC ## Query blogCollection with Offset Pagination ### Description Retrieves a collection of blogs using offset pagination. Use `first` to specify the number of items and `offset` to skip a certain number of records from the beginning of the result set. ### Method POST ### Endpoint /graphql ### Parameters #### Query Parameters - **first** (Int) - Optional - Query the first `n` records in the collection. - **offset** (Int) - Optional - Skip `offset` number of records in the results. ### Request Example ```json { "query": "query BlogCollectionOffset($first: Int, $offset: Int) {\n blogCollection(first: $first, offset: $offset) {\n pageInfo {\n startCursor\n endCursor\n hasNextPage\n hasPreviousPage\n }\n edges {\n cursor\n node {\n id\n }\n }\n }\n}", "variables": { "first": 2, "offset": 2 } } ``` ### Response #### Success Response (200) - **blogCollection** (BlogConnection!) - The connection object containing edges and page info. - **pageInfo** (PageInfo!) - Metadata about the current page of results. - **startCursor** (String) - The unique identifier of the first record within the query. - **endCursor** (String) - The unique identifier of the last record within the query. - **hasNextPage** (Boolean!) - Indicates if another page of content is available. - **hasPreviousPage** (Boolean!) - Indicates if another page of content is available. - **edges** (BlogEdge!) - A list of blog edges, each containing a cursor and a node. - **cursor** (String!) - The cursor for the blog edge. - **node** (Blog!) - The blog node. - **id** (ID!) - The unique identifier of the blog. #### Response Example ```json { "data": { "blogCollection": { "edges": [ { "node": { "id": 3 }, "cursor": "WzNd" }, { "node": { "id": 4 }, "cursor": "WzRd" } ], "pageInfo": { "startCursor": "WzNd", "endCursor": "WzRd", "hasNextPage": false, "hasPreviousPage": true } } } } ``` ``` -------------------------------- ### SQL Setup for Blog Table Source: https://supabase.github.io/pg_graphql/api SQL to create a 'Blog' table with an auto-incrementing primary key and a name field. This is a prerequisite for defining GraphQL types. ```sql create table "Blog"( id serial primary key, name varchar(255) not null ); ``` -------------------------------- ### GraphQL Query for First Page of Blog Collection Source: https://supabase.github.io/pg_graphql/api Example query to fetch the first page of the blog collection using the 'first' and 'after' arguments. 'after' is null for the initial request. ```graphql { blogCollection( first: 2, after: null ) { pageInfo { startCursor endCursor hasPreviousPage hasNextPage } edges { cursor node { id } } } } ``` -------------------------------- ### GraphQL Node Query Example Source: https://supabase.github.io/pg_graphql/api Demonstrates how to query the 'node' interface using inline fragments to specify fields for a particular type, such as 'Blog'. ```graphql { node( nodeId: "WyJwdWJsaWMiLCAiYmxvZyIsIDFd" ) { nodeId # Inline fragment for `Blog` type ... on Blog { name description } } } ``` -------------------------------- ### Example Table with aggregate Enabled Source: https://supabase.github.io/pg_graphql/configuration Creates a 'BlogPost' table and enables the `aggregate` field via a comment directive. This configuration supports performing aggregate calculations on the table's data. ```sql create table "BlogPost"( id serial primary key, title varchar(255) not null, rating int not null ); comment on table "BlogPost" is e'@graphql({"aggregate": {"enabled": true}});' ``` -------------------------------- ### GraphQL Query for Person Collection Source: https://supabase.github.io/pg_graphql/api Example GraphQL query to fetch person IDs and names. ```graphql { personCollection { edges { node { id name } } } } ``` -------------------------------- ### Example GraphQL Query for Ordering Blog Collection Source: https://supabase.github.io/pg_graphql/api Demonstrates how to query the blog collection with a specific ordering, in this case, by ID in descending order with nulls last. ```graphql { blogCollection( orderBy: [{id: DescNullsLast}] ) { edges { node { id } } } } ``` -------------------------------- ### Example Response for Non-Introspection Query Source: https://supabase.github.io/pg_graphql/configuration Shows the expected JSON response for a non-introspection query, illustrating the structure of the returned data. ```json { "data": { "accountCollection": { "edges": [ { "node": { "id": 1, "email": "alice@example.com" } } ] } } } ``` -------------------------------- ### Example of Inflection in Action Source: https://supabase.github.io/pg_graphql/configuration Demonstrates how enabling name inflection affects generated GraphQL type names from SQL table names. ```sql comment on schema public is e'@graphql({"inflect_names": true}); create table blog_post( id int primary key, ... ); ``` -------------------------------- ### Blog Aggregate Query Example Source: https://supabase.github.io/pg_graphql/api Demonstrates how to query aggregate functions (count, sum, avg, min, max) on a collection of 'Blog' records filtered by rating. ```graphql { blogCollection( filter: { rating: { gt: 3 } } ) { aggregate { count sum { rating visits } avg { rating } min { createdAt title } max { rating updatedAt } } } } ``` -------------------------------- ### Example JSON Response for Non-existent Blog by Primary Key Source: https://supabase.github.io/pg_graphql/api Shows the expected JSON response when a blog record is not found by its primary key (returns null). ```json { "data": { "blogByPk": null } } ``` -------------------------------- ### Example GraphQL Query for Item by Composite Primary Key Source: https://supabase.github.io/pg_graphql/api Demonstrates how to query for a specific item record using both parts of its composite primary key. ```graphql { itemByPk( itemId: 1, productId: 2 ) { itemId productId quantity price } } ``` -------------------------------- ### Create Blog Table with Primary Key Source: https://supabase.github.io/pg_graphql/api Example of a PostgreSQL table definition that includes a primary key, making it eligible for GraphQL schema exposure. ```sql create table "Blog"( id serial primary key, name varchar(255) not null, description varchar(255), "createdAt" timestamp not null, "updatedAt" timestamp not null ); ``` -------------------------------- ### SQL Setup for Item Table with Composite Primary Key Source: https://supabase.github.io/pg_graphql/api Defines the SQL schema for the 'item' table, featuring a composite primary key consisting of 'item_id' and 'product_id'. ```sql create table item( item_id int, product_id int, quantity int, price numeric(10,2), primary key(item_id, product_id) ); ``` -------------------------------- ### GraphQL Query for Blog Collection using Offset Pagination Source: https://supabase.github.io/pg_graphql/api Example query demonstrating Offset Pagination, using 'first' and 'offset' to limit results and skip records, similar to SQL's limit and offset. ```graphql { blogCollection( first: 2, offset: 2 ) { ...truncated... } } ``` -------------------------------- ### Upgrade pg_graphql Version Source: https://supabase.github.io/pg_graphql/supabase Use these SQL commands to drop the current pg_graphql extension and install the default (latest) version. This process aims for zero downtime. ```sql drop extension pg_graphql; -- drop version 1.1.0 create extension pg_graphql; -- install default version 1.2.0 ``` -------------------------------- ### GraphQL Query for Next Page of Blog Collection Source: https://supabase.github.io/pg_graphql/api Example query to fetch the subsequent page of the blog collection by providing the 'endCursor' from the previous response to the 'after' argument. ```graphql { blogCollection( first: 2, after: "WzJd" ) { ...truncated... } } ``` -------------------------------- ### Example JSON Response for Item by Composite Primary Key Source: https://supabase.github.io/pg_graphql/api Shows the expected JSON response when an item record is found using its composite primary key. ```json { "data": { "itemByPk": { "itemId": 1, "productId": 2, "quantity": 1, "price": "24.99" } } } ``` -------------------------------- ### GraphQL Query for Blog and its BlogPosts Source: https://supabase.github.io/pg_graphql/api Example GraphQL query to fetch the names of blogs and the IDs and titles of their associated blog posts. Demonstrates traversing a one-to-many relationship. ```graphql { blogCollection { edges { node { name blogPostCollection { edges { node { id title } } } } } } } ``` -------------------------------- ### GraphQL Query Result for User with JSON String Source: https://supabase.github.io/pg_graphql/api Example JSON response showing the 'config' field serialized as a string due to the JSON scalar. ```json { "data": { "userCollection": { "edges": [ { "node": { "config": "{\"palette\": \"dark-mode\"}" } } ] } } } ``` -------------------------------- ### Basic GraphQL Query with cURL Source: https://supabase.github.io/pg_graphql/supabase Example of making a POST request to the Supabase GraphQL API using cURL to fetch data. Requires project reference and API key. ```bash curl -X POST https://.supabase.co/graphql/v1 \ -H 'apiKey: ' \ -H 'Content-Type: application/json' \ --data-raw '{"query": "{ accountCollection(first: 1) { edges { node { id } } } }", "variables": {}}' ``` -------------------------------- ### GraphQL Query for BlogPost and its Blog Source: https://supabase.github.io/pg_graphql/api Example GraphQL query to fetch blog post titles and the names of their associated blogs. Demonstrates traversing a many-to-one relationship. ```graphql { blogPostCollection { edges { node { title blog { name } } } } } ``` -------------------------------- ### Example JSON Response for Item Query with Missing Composite Key Part Source: https://supabase.github.io/pg_graphql/api Shows the expected JSON response, including an error message, when a composite primary key is incomplete. ```json { "data": null, "errors": [ { "message": "Missing primary key column(s): product_id" } ] } ``` -------------------------------- ### Example GraphQL Query for Item with Missing Composite Key Part Source: https://supabase.github.io/pg_graphql/api Demonstrates querying for an item with only one part of its composite primary key provided, which will result in an error. ```graphql { itemByPk( itemId: 1 ) { itemId productId quantity price } } ``` -------------------------------- ### Create and Populate a Table Source: https://supabase.github.io/pg_graphql/contributing Sets up a 'book' table and inserts sample data within the interactive PostgreSQL environment. ```sql graphqldb= create extension pg_graphql cascade; CREATE EXTENSION graphqldb= create table book(id int primary key, title text); CREATE TABLE graphqldb= insert into book(id, title) values (1, 'book 1'); INSERT 0 1 ``` -------------------------------- ### Insert Blog Records Response Source: https://supabase.github.io/pg_graphql/api Example JSON response after successfully inserting blog records. It shows the affected count and the details of the inserted records, including their IDs and names. ```json { "data": { "insertIntoBlogCollection": { "records": [ { "id": 1, "name": "foo" }, { "id": 2, "name": "bar" } ], "affectedCount": 2 } } } ``` -------------------------------- ### GraphQL Query Result for Blog and its BlogPosts Source: https://supabase.github.io/pg_graphql/api Example JSON response for a GraphQL query fetching blog names and their associated blog post IDs and titles. Illustrates the structure of returned data for a one-to-many relationship. ```json { "data": { "blogCollection": { "edges": [ { "node": { "name": "pg_graphql blog", "blogPostCollection": { "edges": [ { "node": { "id": 2, "title": "fIr3t p0sT" } }, { "node": { "id": 3, "title": "graphql with postgres" } } ] } } } ] } } } ``` -------------------------------- ### GraphQL Query Result for BlogPost and its Blog Source: https://supabase.github.io/pg_graphql/api Example JSON response for a GraphQL query fetching blog post titles and their associated blog names. Illustrates the structure of returned data for a many-to-one relationship. ```json { "data": { "blogPostCollection": { "edges": [ { "node": { "blog": { "name": "pg_graphql blog" }, "title": "fIr3t p0sT" } }, { "node": { "blog": { "name": "pg_graphql blog" }, "title": "graphql with postgres" } } ] } } } ``` -------------------------------- ### Example Response for Accounts Query Source: https://supabase.github.io/pg_graphql/functions This JSON object represents the successful response from the 'accountsByIds' GraphQL query, showing the structure of the returned account data including IDs and emails. ```json { "data": { "accountsByIds": { "edges": [ { "node": { "id": 1, "email": "a@example.com" } }, { "node": { "id": 2, "email": "b@example.com" } } ] } } } ``` -------------------------------- ### Insert Blog Records Mutation Source: https://supabase.github.io/pg_graphql/api Example GraphQL mutation to insert new blog records into the 'Blog' collection. It demonstrates how to provide multiple objects and retrieve affected count and record details. ```graphql mutation { insertIntoBlogCollection( objects: [ {name: "foo"}, {name: "bar"}, ] ) { affectedCount records { id name } } } ``` -------------------------------- ### Clone the pg_graphql Repository Source: https://supabase.github.io/pg_graphql/quickstart Clone the official pg_graphql repository to your local machine. This is the first step to setting up the demo environment. ```bash git clone https://github.com/supabase/pg_graphql.git cd pg_graphql ``` -------------------------------- ### Initialize pgrx with PostgreSQL 17 Source: https://supabase.github.io/pg_graphql/installation Initialize pgrx to manage its own version of PostgreSQL. This command downloads and sets up PostgreSQL 17 for pgrx. ```bash cargo pgrx init --pg17=download ``` -------------------------------- ### Introspection Disabled Error Source: https://supabase.github.io/pg_graphql/configuration Example of the error returned when introspection is disabled and __schema or __type selections are attempted. ```json { "errors": [{ "message": "Unknown field \"__schema\" on type Query" }] } ``` -------------------------------- ### GraphQL Query Result for Employee Source: https://supabase.github.io/pg_graphql/api Example JSON response for the employee collection query, showing nested data. ```json { "data": { "employeeCollection": { "edges": [ { "node": { "name": "Foo Barington", "emailAddress": { "address": "foo@bar.com", "employee": { "name": "Foo Barington" } } } } ] } } } ``` -------------------------------- ### Implicit AND Filtering Source: https://supabase.github.io/pg_graphql/api Multiple column filters at the same level are implicitly combined with boolean AND. This example shows filtering by both id and name. ```graphql { blogCollection( filter: { # Equivalent to not: { and: [{id: {eq: 1}}, {name: {eq: "A: Blog 1"}}] } not: { id: {eq: 1} name: {eq: "A: Blog 1"} } } ) { edges { cursor node { id name description createdAt } } } } ``` -------------------------------- ### accountById Source: https://supabase.github.io/pg_graphql/functions Example of a PostgreSQL function returning a single row, exposed as a GraphQL query field. It fetches an account by its ID. ```APIDOC ## GET accountById ### Description Fetches a single account record by its ID. ### Method GET ### Endpoint `/graphql ### Parameters #### Query Parameters - **accountId** (Int!) - Required - The ID of the account to retrieve. ### Request Example ```graphql query { accountById(accountId: 1) { id email nodeId } } ``` ### Response #### Success Response (200) - **id** (Int) - The account ID. - **email** (String) - The account email address. - **nodeId** (String) - The Node ID for the account. #### Response Example ```json { "data": { "accountById": { "id": 1, "email": "a@example.com", "nodeId": "WyJwdWJsaWMiLCAiYWNjb3VudCIsIDFd" } } } ``` ``` -------------------------------- ### Configure Relay Environment Source: https://supabase.github.io/pg_graphql/usage_with_relay Set up the Relay environment, including the fetch function for making GraphQL requests to your Supabase endpoint. Ensure 'getDataID' is configured for correct cache storage and consider 'missingFieldHandlers' for partially cached data. ```javascript import { Environment, FetchFunction, Network, RecordSource, Store, } from 'relay-runtime' import supabase, { SUPABASE_ANON_KEY, SUPABASE_URL } from './supabase' const fetchQuery: FetchFunction = async (operation, variables) => { const { data: { session }, } = await supabase.auth.getSession() const response = await fetch(`${SUPABASE_URL}/graphql/v1`, { method: 'POST', headers: { 'Content-Type': 'application/json', apikey: SUPABASE_ANON_KEY, Authorization: `Bearer ${session?.access_token ?? SUPABASE_ANON_KEY}`, }, body: JSON.stringify({ query: operation.text, variables, }), }) return await response.json() } const network = Network.create(fetchQuery) const store = new Store(new RecordSource()) const environment = new Environment({ network, store, getDataID: (node) => node.nodeId, missingFieldHandlers: [ { handle(field, _record, argValues) { if (field.name === 'node' && 'nodeId' in argValues) { // If field is node(nodeId: $nodeId), look up the record by the value of $nodeId return argValues.nodeId } return undefined }, kind: 'linked', }, ], }) export default environment ``` -------------------------------- ### AND Filter Query Source: https://supabase.github.io/pg_graphql/api Combine multiple filters using the `and` operator to ensure all conditions are met. This example filters for a specific ID and name. ```graphql { blogCollection( filter: { and: [ {id: {eq: 1}} {name: {eq: "A: Blog 1"}} ] } ) { edges { cursor node { id name description createdAt } } } } ``` -------------------------------- ### GraphQL Query Response Example with Null Default Source: https://supabase.github.io/pg_graphql/functions The expected JSON response from the GraphQL query when using a null default argument. ```json { "data": { "addNums": 42 } } ``` -------------------------------- ### GraphQL Response for First Page of Blog Collection Source: https://supabase.github.io/pg_graphql/api Sample JSON response for the first page query, showing edges with nodes and cursors, and pageInfo with cursor details and pagination flags. ```json { "data": { "blogCollection": { "edges": [ { "node": { "id": 1 }, "cursor": "WzFd" }, { "node": { "id": 2 }, "cursor": "WzJd" } ], "pageInfo": { "startCursor": "WzFd", "endCursor": "WzJd", "hasNextPage": true, "hasPreviousPage": false } } } } ``` -------------------------------- ### Remove Table from API Source: https://supabase.github.io/pg_graphql/supabase Revoke all permissions on a specific table for a role to remove it from the GraphQL API. This example removes 'public.foo' for anonymous users. ```sql revoke all on table public.foo from anon; ``` -------------------------------- ### GraphQL Query Result for Person with BigInt String Source: https://supabase.github.io/pg_graphql/api Example JSON response showing the 'id' field serialized as a string due to the BigInt scalar. ```json { "data": { "personCollection": { "edges": [ { "node": { "id": "1", "name": "Foo Barington" } } ] } } } ``` -------------------------------- ### GraphQL Query for Employee Collection Source: https://supabase.github.io/pg_graphql/api Example GraphQL query to fetch employee names and their associated email addresses, including nested employee names. ```graphql { employeeCollection { edges { node { name emailAddress { address employee { name } } } } } } ``` -------------------------------- ### GraphQL Response for Second Page of Blog Collection Source: https://supabase.github.io/pg_graphql/api Sample JSON response for the second page query, demonstrating the continuation of the collection with new edges and updated pageInfo. ```json { "data": { "blogCollection": { "edges": [ { "node": { "id": 3 }, "cursor": "WzNd" }, { "node": { "id": 4 }, "cursor": "WzRd" } ], "pageInfo": { "startCursor": "WzNd", "endCursor": "WzRd", "hasNextPage": false, "hasPreviousPage": true } } } } ``` -------------------------------- ### Create Blog Table Without Primary Key Source: https://supabase.github.io/pg_graphql/api Example of a PostgreSQL table definition lacking a primary key, which prevents it from being exposed in the GraphQL schema. ```sql create table "Blog"( id int, name varchar(255) not null ); ``` -------------------------------- ### Example Non-Introspection Query Source: https://supabase.github.io/pg_graphql/configuration Demonstrates a non-introspection query for account collection. This query is unaffected by disabling introspection as long as the role has the necessary SQL privileges. ```graphql { accountCollection { edges { node { id email } } } } ``` -------------------------------- ### accountsByEmail Source: https://supabase.github.io/pg_graphql/functions Example of a PostgreSQL function returning a set of rows (a collection), exposed as a paginated GraphQL connection. Supports filtering, sorting, and pagination arguments. ```APIDOC ## GET accountsByEmail ### Description Fetches a collection of accounts filtered by email, with support for pagination and sorting. ### Method GET ### Endpoint `/graphql ### Parameters #### Query Parameters - **emailToSearch** (String!) - Required - The email address to search for. - **first** (Int) - Optional - Query the first `n` records in the collection. - **last** (Int) - Optional - Query the last `n` records in the collection. - **before** (Cursor) - Optional - Query values before the provided cursor. - **after** (Cursor) - Optional - Query values after the provided cursor. - **filter** (AccountFilter) - Optional - Filters to apply to the results set. - **orderBy** (AccountOrderBy!) - Optional - Sort order to apply to the collection. ### Request Example ```graphql query { accountsByEmail(emailToSearch: "a@example.com", first: 1) { edges { node { id email } } } } ``` ### Response #### Success Response (200) - **edges** (Array) - A list of edges, where each edge contains a node. - **node** (Account) - The account record. - **id** (Int) - The account ID. - **email** (String) - The account email address. #### Response Example ```json { "data": { "accountsByEmail": { "edges": [ { "node": { "id": 1, "email": "a@example.com" } } ] } } } ``` ``` -------------------------------- ### Blog Order By Input Type Source: https://supabase.github.io/pg_graphql/api Specifies the possible directions for ordering results based on the 'Blog' table's fields. ```graphql input BlogOrderBy { id: OrderByDirection name: OrderByDirection description: OrderByDirection createdAt: OrderByDirection updatedAt: OrderByDirection } ``` -------------------------------- ### Filtering with empty operators Source: https://supabase.github.io/pg_graphql/api This example demonstrates that empty filters for 'and', 'or', and 'not' operators are ignored and do not affect the query results, behaving as if the operator was not specified. ```APIDOC ## Query blogCollection with empty filters ### Description Retrieves a collection of blogs, demonstrating that empty 'and', 'or', and 'not' filters are ignored. ### Method POST ### Endpoint /graphql ### Parameters #### Query Parameters None #### Request Body ```json { "query": "query ($blogCollectionFilter: BlogCollectionFilter!) { blogCollection(filter: $blogCollectionFilter) { edges { cursor node { id name description createdAt } } } }", "variables": { "blogCollectionFilter": { "and": [], "or": [], "not": {} } } } ``` ### Response #### Success Response (200) Returns all blog nodes as the empty filters have no effect. #### Response Example ```json { "data": { "blogCollection": { "edges": [ { "node": { "id": 1, "name": "A: Blog 1", "createdAt": "2023-07-24T04:01:09.882781", "description": "a desc1" }, "cursor": "WzFd" }, { "node": { "id": 2, "name": "A: Blog 2", "createdAt": "2023-07-24T04:01:09.882781", "description": "a desc2" }, "cursor": "WzJd" }, { "node": { "id": 3, "name": "A: Blog 3", "createdAt": "2023-07-24T04:01:09.882781", "description": "a desc3" }, "cursor": "WzNd" }, { "node": { "id": 4, "name": "B: Blog 3", "createdAt": "2023-07-24T04:01:09.882781", "description": "b desc1" }, "cursor": "WzRd" } ] } } } ``` ``` -------------------------------- ### Blog Insert Input Source: https://supabase.github.io/pg_graphql/example_schema Defines the input structure for inserting a new blog, specifying fields like ownerId, name, description, and timestamps. ```APIDOC ## Blog Insert Input ### Description Specifies the data required to insert a new blog record. ### Fields - **ownerId** (Int) - Optional - The ID of the account that owns the blog. - **name** (String) - Optional - The name of the blog. - **description** (String) - Optional - A description for the blog. - **createdAt** (Datetime) - Optional - The timestamp when the blog was created. - **updatedAt** (Datetime) - Optional - The timestamp when the blog was last updated. ```