Serverless APIs
Supabase auto-generates three types of API directly from your database schema.
- REST - interact with your database through a restful interface.
- Realtime - listen to database changes.
- GraphQL - in beta.
The APIs are:
- Instant and auto-generated.
As you update your database the changes are immediately accessible through your API. - Self documenting.
Supabase generates documentation in the Dashboard which updates as you make database changes. - Secure.
The API is configured to work with PostgreSQL's Row Level Security, provisioned behind an API gateway with key-auth enabled. - Fast.
Our benchmarks for basic reads are more than 300% faster than Firebase. The API is a very thin layer on top of Postgres, which does most of the heavy lifting. - Scalable.
The API can serve thousands of simultaneous requests, and works well for Serverless workloads.
REST API #
Supabase provides a RESTful API using PostgREST. This is a very thin API layer on top of Postgres. It provides everything you need from a CRUD API:
- Basic CRUD operations
- Deeply nested joins, allowing you to fetch data from multiple tables in a single fetch
- Works with Postgres Views
- Works with Postgres Functions
- Works with the Postgres security model - including Row Level Security, Roles, and Grants.
GraphQL API #
note
GraphQL is in Beta, and may have breaking changes. It is only available on self-hosted setups and Supabase projects created after 28th March 2022.
GraphQL in Supabase works through pg_graphql, an open source PostgreSQL extension for GraphQL.
Realtime API #
Supabase provides a Realtime API using Realtime. You can use this to listen to database changes over websockets. Realtime leverages PostgreSQL's built-in logical replication. You can manage your Realtime API simply by managing Postgres publications.
Getting started#
All APIs are auto-created from Database tables. After you have added tables or functions to your database, you can use the APIs provided.
Creating API Routes#
API routes are automatically created when you create Postgres Tables, Views, or Functions.
Let's create our first
API route by creating a table called todos
to store tasks.
This creates a corresponding route todos
which can accept GET
, POST
, PATCH
, & DELETE
requests.
- Go to the Table editor page in the Dashboard.
- Click New Table and create a table with the name
todos
. - Click Save.
- Click New Column and create a column with the name
task
and typetext
. - Click Save.
API URL and Keys#
Every Supabase project has a unique API URL. Your API is secured behind an API gateway which requires an API Key for every request.
- Go to the Settings page in the Dashboard.
- Click API in the sidebar.
- Find your API
URL
,anon
, andservice_role
keys on this page.
The REST API and the GraphQL API are both accessible through this URL:
- REST:
https://<project_ref>.supabase.co/rest/v1
- GraphQL:
https://<project_ref>.supabase.co/graphql/v1
Both of these routes require the anon
key to be passed through an apikey
header.
API Keys
You are provided with two keys:
- an
anon
key, which is safe to be used in a browser context. - a
service_role
key, which should only be used on a server. This key can bypass Row Level Security. NEVER use this key in a browser.
Accessing the docs in the Dashboard#
REST API {#rest-api-dashboard-docs}
Supabase generates documentation in the Dashboard which updates as you make database changes.
Let's view the documentation for a countries
table which we created in our database.
- Go to the API page in the Dashboard.
- Find the
countries
table under Tables and Views in the sidebar. - Switch between the JavaScript and the cURL docs using the tabs.
GraphQL
The GraphQL Endpoint that we provide (https://<project_ref>.supabase.co/graphql/v1
) is compatible with any GraphiQL implementation that can pass an apikey
header.
Some suggested applications:
- paw.cloud
- insomnia.rest
- postman.com/graphql
- Self-hosted GraphiQL: GraphiQL can be served through a simple HTML file. See this discussion for more details.
Using the API#
REST API#
You can interact with your API directly via HTTP requests, or you can use the client libraries which we provide.
Let's see how to make a request to the todos
table which we created in the first step,
using the API URL (SUPABASE_URL
) and Key (SUPABASE_ANON_KEY
) we provided:
1// Initialize the JS client
2import { createClient } from '@supabase/supabase-js'
3const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY)
4
5// Make a request
6const { data: todos, error } = await supabase.from('todos').select('*')
JS Reference: select(), insert(), update(), upsert(), delete(), rpc() (call Postgres functions).
GraphQL API#
You can use any GraphQL client with the Supabase GraphQL API. For our GraphQL example we will use urql.
1import { createClient, useQuery } from 'urql'
2
3// Prepare API key and Authorization header
4const headers = {
5 apikey: <SUPABASE_ANON_KEY>,
6 authorization: `Bearer ${<SUPABASE_ANON_KEY}`>
7}
8
9// Create GraphQL client
10// See: https://formidable.com/open-source/urql/docs/basics/react-preact/#setting-up-the-client
11const client = createClient({
12 url: '<SUPABASE_URL>/graphql/v1',
13 fetchOptions: function createFetchOptions() {
14 return { headers }
15 },
16})
17
18// Prepare our GraphQL query
19const TodosQuery = `
20 query {
21 todosCollection {
22 edges {
23 node {
24 id
25 title
26 }
27 }
28 }
29 }
30`
31
32// Query for the data (React)
33const [result, reexecuteQuery] = useQuery({
34 query: TodosQuery,
35})
36
37// Read the result
38const { data, fetching, error } = result
Realtime API#
By default Realtime is disabled on your database. Let's turn on Realtime for the todos
table.
- Go to the Database page in the Dashboard.
- Click on Replication in the sidebar.
- Control which database events are sent by toggling Insert, Update, and Delete.
- Control which tables broadcast changes by selecting Source and toggling each table.
From the client, we can listen to any new data that is inserted into the todos
table:
1// Initialize the JS client
2import { createClient } from '@supabase/supabase-js'
3const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY)
4
5// Create a function to handle inserts
6const handleInserts = (payload) => {
7 console.log('Change received!', payload)
8}
9
10// Listen to inserts
11const { data: todos, error } = await supabase.from('todos').on('INSERT', handleInserts).subscribe()
Use subscribe() to listen to database changes.
The Realtime API works through PostgreSQL's replication functionality. Postgres sends database changes to a publication
called supabase_realtime
, and by managing this publication you can control which data is broadcast.
API Security#
Securing your Routes#
Your API is designed to work with Postgres Row Level Security (RLS). If you use Supabase Auth, you can restrict data based on the logged-in user. To control access to your data, you can use Policies. When you create a table in Postgres, Row Level Security is disabled by default. To enable RLS:
- Go to the Authentication page in the Dashboard.
- Click on Policies in the sidebar.
- Select Enable RLS to enable Row Level Security.
The service_role
key#
Never expose the service_role
key in a browser or anywhere where a user can see it. This Key is designed to bypass Row Level Security - so it should only be used on a private server.
A common use case for the service_role
key is to run data analytics jobs on the backend. To support joins on user id, it is often useful to grant the service role read access to auth.users
table.
1grant select on table auth.users to service_role;
We have partnered with GitHub to scan for Supabase service_role
keys pushed to public repositories.
If they detect any keys with service_role privileges being pushed to GitHub, they will forward the API key to us, so that we can automatically revoke the detected secrets and notify you, protecting your data against malicious actors.
Safeguards towards accidental deletes and updates#
For all projects, by default, the Postgres extension safeupdate is enabled for all queries coming from the API.
This ensures that any delete()
or update()
would fail if there are no accompanying filters provided.
To confirm that safeupdate is enabled for queries going through the API of your project, the following query could be run:
1select usename,useconfig from pg_shadow where usename = 'authenticator' ;
The expected value for useconfig
should be:
1['session_preload_libraries=supautils, safeupdate']