53
Creating a GraphQL API for Notion with Hasura Actions
Notion launched their REST API recently letting you connect your pages and databases with any tool to create powerful workflows. In this post, we will leverage the Notion API to create a GraphQL wrapper for their pages API endpoint. This will use Hasura Actions to define GraphQL types and we will be writing an Action webhook handler that will make the call to Notion's API.
Let's get started by setting up things on Notion's side for the API integration.
You need to be an admin of a workspace to be able to use the APIs. If you are an admin in an existing workspace, you can skip this step.
Let's get started by creating a new personal workspace by following the docs on Creating a personal workspace.
The next step is to create an integration. Head to My integrations and create a new integration with relevant name and workspace.
After submitting the above form, note down the Internal Integration secret. This will be used during the API integration. The integration type will be internal. There's also the option of making it external so that the API is public and can be used by anyone. For this example, we will stick to internal since the Hasura Action will be used only for one private workspace.
According to Notion docs,
Integrations don't have access to any pages (or databases) in the workspace at first. A user must share specific pages with an integration in order for those pages to be accessed using the API
This means, the API can be used only for those pages that already exist and has the right permissions (sharing) added to be used by the API.
Note that, you need to create a database as a full page to be able to use the API. You can do this by typing in /database
and selecting Table - Full Page
.
Head to Share on the top menu and click on Copy link
. Paste this somewhere to identify the ID of the newly created database.
For example, it will look something along the lines of
https://www.notion.so/0664caf380ec482d92b74b01730480f9?v=8b0f9cba5e72499380fcb251369f5b4b
where the database ID is the one before the query parameter. Note down the database ID because we will reference that in the API request for making changes.
- Click on the following button to deploy GraphQL engine on Hasura Cloud. <!--kg-card-begin: markdown-->
Open the Hasura console by clicking on the button "Launch console".
Head to the Data tab and click on
Create Heroku Database
to create a new Postgres database. Note that this is an optional step. We will not use the database in this example since we are writing an Action to create a GraphQL wrapper over Notion.
Now let's create an Action. Head to
Actions
tab from the top menu and click onCreate
to create a new action.We will add a custom mutation to add a new item to the DB.
The mutation type would look something like this:
type Mutation {
addNotionItem (
databaseId: String!
properties: jsonb!
children: jsonb
): ItemOutput
}
and the output type for ItemOutput
would look something like this:
type ItemOutput {
id : String!
object : String!
created_time : timestamptz!
last_edited_time : timestamptz!
}
Note: You can modify the above type defintions to include more fields as required or return a more generic JSON so that everything from Notion's response can be returned back as output.
Leave the other inputs as it is and we will come back to modifying the handler URL later.
To add an item to the DB, we can make use of the following API
- API Endpoint - https://api.notion.com/v1/pages
- Headers -
Authorization: Bearer <integration_token>
- Request Body
{
"parent": { "database_id": <database_id> },
"properties": {
"Name": {
"title": [
{
"text": {
"content": "iPhone 12"
}
}
]
}
}
}
The above request body assumes you have the default Name
field in your table.
Once the Action is created with the above types, head to the Codegen tab and click on Try on glitch
. This will create an app on Glitch platform with the Node.js boilerplate. We need to add an env
variable in the .env
file. Add the env NOTION_TOKEN
and paste the Integration token that we obtained at the beginning of this post.
Here's the code for the new endpoint that you can paste in the Glitch app source code under src/server.js.
Once this Action code is updated on the Glitch app, copy the Glitch app URL and add the /addNotionItem
to that and modify the Action URL to point to the glitch endpoint.
An example glitch endpoint would look something like this https://lovely-bustling-environment.glitch.me/addNotionItem
Head to Hasura Console API Explorer and make the following GraphQL mutation:
mutation addNotionItem ($databaseId: String!, $properties: jsonb!) {
addNotionItem(databaseId: $databaseId, properties: $properties) {
id
object
created_time
last_edited_time
}
}
With the following variables:
{
"databaseId": "<database_id>",
"properties": {
"Name": {
"title": [
{
"text": {
"content": "iPhone 12"
}
}
]
}
}
}
Replace the <database_id>
with your own database ID.
You should get a response which looks something like:
You can also define permissions for this Action so that you can restrict or allow access only to certain roles.
Head to the Permissions
tab of the created Action and allow access for specific roles.
We have written a GraphQL wrapper for Notion's Create a page
API. Now of course you can repeat this for any of the Notion's REST API by defining custom types appropriately and writing the webhook handler.
53