GraphQL

info

Powered by PostgREST and pg_graphql

GraphQL is a query language for APIs, as well as a server-side runtime for executing those queries by using a type system that you define for your data. It offers a more efficient, flexible, and powerful alternative to the traditional REST API. Instead of accessing multiple endpoints to fetch or modify data, GraphQL enables you to request exactly what you need and nothing more from a single endpoint. This minimizes over-fetching or under-fetching of data, which can lead to faster and more efficient applications.

The primary advantage of GraphQL is its flexibility. Clients can specify exactly what data they need. This allows developers to reduce the amount of data transferred over the network and thereby improve the performance of their applications. Additionally, GraphQL provides a clear description of available data, making it easier for both clients and servers to understand and evolve the data over time. This makes the development process more dynamic and adaptable to changing needs.

In Tembo Cloud, GraphQL is made possible by combining PostgREST to expose an HTTP interface with the pg_graphql extension to handle in-database inflection and query resolution.

Enabling GraphQL on Tembo Cloud

Via UI

You can enable the GraphQL app on your Tembo Cloud instance by navigating to “Apps”, then “GraphQL”. Click “Activate” to enable GraphQL on your instance.

Via API

First, you will need to generate an API token so that you can communicate with your Tembo instance. Navigate to cloud.tembo.io/generate-jwt and follow the instructions to generate a token. Alternatively, you can follow the instructions here.

Set your Tembo token as an environment variable, along with your organization id and the Tembo instance id. Fetch the TEMBO_DATA_DOMAIN from the “Host” parameter of your Tembo instance.

export TEMBO_TOKEN=<your token>
export TEMBO_ORG=<your organization id>
export TEMBO_INST=<your instance id>
export TEMBO_DATA_DOMAIN=<you Tembo domain>

Patch your existing Tembo instance using the Tembo Cloud Platform API to enable GraphQL. We’ll set the configurations to None in this example so that the defaults are assigned.

Python:

import requests

TEMBO_ORG = os.environ["TEMBO_ORG"]
TEMBO_INST = os.environ["TEMBO_INST"]
TEMBO_TOKEN = os.environ["TEMBO_TOKEN"]

resp = requests.patch(
    url=f"https://api.tembo.io/api/v1/orgs/{TEMBO_ORG}/instances/{TEMBO_INST}",
    headers={"Authorization": f"Bearer {TEMBO_TOKEN}"},
    json={
        "app_services": [
            {"http": None},  // default configuration
        ]
    }
)

Curl:

curl -X PATCH \
  -H "Authorization: Bearer ${TEMBO_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"app_services": [{"http": null}]}' \
  "https://api.tembo.io/api/v1/orgs/${TEMBO_ORG}/instances/${TEMBO_INST}"

Using GraphQL

GraphQL is served from an HTTP interface that lives within your data plane domain. This value is the same value as the host on your Tembo Postgres instance and can be found at cloud.tembo.io.

First, create a table in the database:

psql postgres://$yourUser:$yourPassword@${TEMBO_DATA_DOMAIN}:5432/postgres
CREATE TABLE products (
  uid int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  name text NOT NULL,
  category text NOT NULL,
  unit_price numeric NOT NULL,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

Then, let’s add a record to the table:

INSERT INTO products values (DEFAULT, 'pen', 'office-supplies', 0.75);

Insert a record with the GraphQL API using a mutation

To use a mutation, we must first define a function. Let’s add a function which will let us add products.

Run the following SQL in the database to create the function:

create function "addProduct"(name text, category text, unit_price numeric)
  returns int
  volatile
  language sql
as $$ insert into products (name, category, unit_price) values (name, category, unit_price) returning uid; $$;

Then we can call the function using the GraphQL API.

Python:

TEMBO_DATA_DOMAIN = os.environ["TEMBO_DATA_DOMAIN"]

resp = requests.post(
    url=f"https://{TEMBO_DATA_DOMAIN}/graphql/v1",
    headers={"Authorization": f"Bearer {TEMBO_TOKEN}"},
    json={
        "query": '''
            mutation {
                addProduct(name: "computer", category: "electronics", unit_price: "999.99") {
                    product {
                        name
                        category
                        unit_price
                    }
                }
            }
        ''',
    }
)

resp.json()

Curl:

curl -X POST \
  -H "Authorization: Bearer ${TEMBO_TOKEN}" \
  -H "Content-Type: application/json" \
     -d '{
           "query": "mutation { addProduct(name: \"computer\", category: \"electronics\", unit_price: \"999.99\") { product { name, category, unit_price } } }"
         }' \
  "https://${TEMBO_DATA_DOMAIN/graphql/v1"

You should see the following response. Note that the function we created simply returns the new product’s uid.

{
	"data": {
		"addProduct": 2
	}
}

Query the database with the GraphQL API

Now we can query the products table using GraphQL syntax.

If you’ve been following our examples, there should be two products in the database: a pen and a computer.

Let’s query the database and ask for products that have a unit price less than 2.

Python:

TEMBO_DATA_DOMAIN = os.environ["TEMBO_DATA_DOMAIN"]

resp = requests.post(
    url=f"https://{TEMBO_DATA_DOMAIN}/graphql/v1",
    headers={"Authorization": f"Bearer {TEMBO_TOKEN}"},
    json={
        "query": '''
        {
            productsCollection(filter: { unit_price: {lt: "2" }})
            {
                edges { node { uid, name, category, unit_price } }
            }
        }
        ''',
    }
)

resp.json()

Curl:

curl -X POST \
  -H "Authorization: Bearer ${TEMBO_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
           "query": "{ products1Collection(filter: { unit_price: {lt: \"2\" }}) { edges { node { uid, name, category, unit_price } } } }"
    }' \
  "https://${TEMBO_DATA_DOMAIN/graphql/v1"

And you should see the following response:

{
	"data": {
		"products1Collection": {
			"edges": [
				{
					"node": {
						"uid": 1,
						"name": "pen",
						"category": "office-supplies",
						"unit_price": "0.75"
					}
				}
			]
		}
	}
}

Advanced

For advanced configuration, refer to the PostgREST and pg_graphql projects and their respective docs for more information. Don’t forget to give them a star!

Next

chevron right arrow

pganalyze

Apps