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.
Create a workspace in Notion
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.
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.
Sharing a page / database
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
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.
Deploy Hasura to get a GraphQL API
Click on the following button to deploy GraphQL engine on Hasura Cloud.
2. Open the Hasura console by clicking on the button "Launch console".
3. 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.
4. Now let's create an Action. Head to Actions tab from the top menu and click on Create to create a new action.
5. We will add a custom mutation to add a new item to the DB.
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.
Notion API to add item to DB
Notion's API reference gives the various endpoints and the request body that can be sent to make changes.
To add an item to the DB, we can make use of the following API
The above request body assumes you have the default Name field in your table.
Writing and Deploying Action Code
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
Test the GraphQL API
Head to Hasura Console API Explorer and make the following GraphQL mutation:
Replace the <database_id> with your own database ID.
You should get a response which looks something like:
Adding Permissions
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.