Merge branch 'master' of github.com:supabase/supabase

This commit is contained in:
Terry Sutton committed 2022-10-26 11:04:55 -02:30
commit d8168bf613
4 files changed
+431 -1

No files matched your search

@@ -0,0 +1,74 @@
---
id: webhooks
title: 'Database Webhooks'
description: Trigger external payloads on database events.
---
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
Database Webhooks allow you to send real-time data from your database to another system whenever a table event occurs.
You can hook into three table events: `INSERT`, `UPDATE`, and `DELETE`. All events are fired _after_ a database row is changed.
Database Webhooks are very similar to triggers, and that's because Database Webhooks are just a convenience wrapper around triggers
using the [pg_net](/docs/guides/database/extensions/pgnet) extension. This extension is asynchronous, and therefore will not block your database changes for long-running network requests.
This video demonstrates how you can create a new customer in Stripe each time a row is inserted into a `profiles` table:
:::note
Database Webhooks were previously known as Function Hooks.
:::
<div class="video-container">
<iframe
src="https://www.youtube-nocookie.com/embed/codAs9-NeHM"
frameBorder="1"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
## Creating a webhook
1. Create a new [Database Webhook](https://app.supabase.com/project/_/database/hooks) in the Dashboard.
1. Give your Webhook a name.
1. Select the table you want to hook into.
1. Select one or more events (table inserts, updates, or deletes) you want to hook into.
We currently support HTTP webhooks. These are sent as a `POST` request with a JSON payload.
## Payload
The payload is automatically generated from the underlying table record:
```typescript
type InsertPayload = {
type: 'INSERT'
table: string
schema: string
record: TableRecord<T>
old_record: null
}
type UpdatePayload = {
type: 'UPDATE'
table: string
schema: string
record: TableRecord<T>
old_record: TableRecord<T>
}
type DeletePayload = {
type: 'DELETE'
table: string
schema: string
record: null
old_record: TableRecord<T>
}
```
## Resources
- [pg_net](/docs/guides/database/extensions/pgnet): an async networking extension for PostgreSQL
@@ -0,0 +1,99 @@
---
id: pgcron
title: 'pg_cron: Job Scheduling'
description: 'pgnet: a simple cron-based job scheduler for PostgreSQL that runs inside the database.'
---
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
The `pg_cron` extension is a simple cron-based job scheduler for PostgreSQL that runs inside the database.
## Usage
### Enable the extension
<Tabs
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard.
2. Click on **Extensions** in the sidebar.
3. Search for "pg_cron" and enable the extension.
</TabItem>
<TabItem value="sql">
```sql
-- Example: enable the "pg_cron" extension
create extension pg_cron with schema extensions;
-- If you're planning to use a non-superuser role to schedule jobs,
-- ensure that they are granted access to the cron schema and its underlying objects beforehand.
-- Failure to do so would result in jobs by these roles to not run at all.
grant usage on schema cron to {{DB user}};
grant all privileges on all tables in schema cron to {{DB user}};
-- Example: disable the "pg_cron" extension
drop extension if exists pg_cron;
```
</TabItem>
</Tabs>
### Syntax
The schedule uses the standard cron syntax, in which \* means "run every time period", and a specific number means "but only at this time":
```bash
┌───────────── min (0 - 59)
│ ┌────────────── hour (0 - 23)
│ │ ┌─────────────── day of month (1 - 31)
│ │ │ ┌──────────────── month (1 - 12)
│ │ │ │ ┌───────────────── day of week (0 - 6) (0 to 6 are Sunday to
│ │ │ │ │ Saturday, or use names; 7 is also Sunday)
│ │ │ │ │
│ │ │ │ │
* * * * *
```
## Examples
### Delete data every week
Delete old data on Saturday at 3:30am (GMT):
```sql
select cron.schedule (
'webhook-every-minute', -- name of the cron job
'* * * * *', -- every minute
$$ delete from events where event_time < now() - interval '1 week' $$
);
```
### Run a vacuum every day
Vacuum every day at 3:00am (GMT)
```sql
SELECT cron.schedule('nightly-vacuum', '0 3 * * *', 'VACUUM');
```
### Unschedule a job
Unschedules a job called `'nightly-vacuum'`
```sql
SELECT cron.unschedule('nightly-vacuum');
```
## Resources
- [pg_cron GitHub Repository](https://github.com/citusdata/pg_cron)
@@ -0,0 +1,254 @@
---
id: pgnet
title: 'pg_net: Async Networking'
description: 'pg_net: an async networking extension for PostgreSQL.'
---
import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
:::caution
The pg_net API is in beta. Functions signatures may change.
:::
[pg_net](https://github.com/supabase/pg_net/) is a PostgreSQL extension exposing a SQL interface for async networking with a focus on scalability and UX.
It differs from the `http` extension in that it is asynchronous by default. This makes it useful in blocking functions (like triggers).
## Usage
### Enable the extension
<Tabs
defaultValue="dashboard"
values={[
{label: 'Dashboard', value: 'dashboard'},
{label: 'SQL', value: 'sql'},
]}>
<TabItem value="dashboard">
1. Go to the [Database](https://app.supabase.com/project/_/database/tables) page in the Dashboard.
2. Click on **Extensions** in the sidebar.
3. Search for "pg_net" and enable the extension.
</TabItem>
<TabItem value="sql">
```sql
-- Example: enable the "pg_net" extension
create schema if not exists net;
create extension pg_net with schema net;
-- Example: disable the "plv8" extension
drop extension if exists pg_net;
drop schema net;
```
Even though the SQL code is `create extension`, this is the equivalent of "enabling the extension".
To disable an extension, call `drop extension`.
Procedural languages are automatically installed within `pg_catalog`, so you don't need to specify a schema.
</TabItem>
</Tabs>
## `http_get` {#http_get}
Creates an HTTP GET request returning the request's ID. HTTP requests are not started until the transaction is committed.
### Signature
:::caution
This is a Postgres SECURITY DEFINER function.
:::
```sql
net.http_get(
-- url for the request
url text,
-- key/value pairs to be url encoded and appended to the `url`
params jsonb default '{}'::jsonb,
-- key/values to be included in request headers
headers jsonb default '{}'::jsonb,
-- WARNING: this is currently ignored, so there is no timeout
-- the maximum number of milliseconds the request may take before being cancelled
timeout_milliseconds int default 1000
)
-- request_id reference
returns bigint
strict
volatile
parallel safe
language plpgsql
```
### Usage
```sql
select net.http_get('https://news.ycombinator.com') as request_id;
request_id
----------
1
(1 row)
```
After triggering `http_get`, use [`http_get_result`](#http_get_result) to get the result of the request.
## `http_post` {#http_post}
Creates an HTTP POST request with a JSON body, returning the request's ID. HTTP requests are not started until the transaction is committed.
The body's character set encoding matches the database's `server_encoding` setting.
### Signature
:::caution
This is a Postgres SECURITY DEFINER function
:::
```sql
net.http_post(
-- url for the request
url text,
-- body of the POST request
body jsonb default '{}'::jsonb,
-- key/value pairs to be url encoded and appended to the `url`
params jsonb default '{}'::jsonb,
-- key/values to be included in request headers
headers jsonb default '{"Content-Type": "application/json"}'::jsonb,
-- WARNING: this is currently ignored, so there is no timeout
-- the maximum number of milliseconds the request may take before being cancelled
timeout_milliseconds int default 1000
)
-- request_id reference
returns bigint
volatile
parallel safe
language plpgsql
```
### Usage
```sql
select
net.http_post(
url:='https://httpbin.org/post',
body:='{"hello": "world"}'::jsonb
) as request_id;
request_id
----------
1
(1 row)
```
After triggering `http_post`, use [`http_get_result`](#http_get_result) to get the result of the request.
## `http_collect_response` {#http_collect_response}
Given a `request_id` reference, retrieves the response.
When `async:=false` is set it is recommended that [statement_timeout](https://www.postgresql.org/docs/13/runtime-config-client.html) is set for the maximum amount of time the caller is willing to wait in case the response is slow to populate.
### Signature
:::caution
This is a Postgres SECURITY DEFINER function
:::
```sql
net.http_collect_response(
-- request_id reference
request_id bigint,
-- when `true`, return immediately. when `false` wait for the request to complete before returning
async bool default true
)
-- http response composite wrapped in a result type
returns net.http_response_result
strict
volatile
parallel safe
```
### Usage
:::caution
`net.http_collect_response` must be in a separate transaction from the calls to `net.http_<method>`
:::
```sql
select
net.http_post(
url:='https://httpbin.org/post',
body:='{"hello": "world"}'::jsonb
) as request_id;
request_id
----------
1
(1 row)
select * from net.http_collect_response(1, async:=false);
status | message | response
--------+---------+----------
SUCCESS ok (
status_code := 200,
headers := '{"date": ...}',
body := '{"args": ...}'
)::net.http_response_result
select
(response).body::json
from
net.http_collect_response(request_id:=1);
body
-------------------------------------------------------------------
{
"args": {},
"data": "{\"hello\": \"world\"}",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Content-Length": "18",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "pg_net/0.2",
"X-Amzn-Trace-Id": "Root=1-61031a5c-7e1afeae69bffa8614d8e48e"
},
"json": {
"hello": "world"
},
"origin": "135.63.38.488",
"url": "https://httpbin.org/post"
}
(1 row)
```
Where `response` is a composite:
```sql
status_code integer
headers jsonb
body text
```
Possible values for `net.http_response_result.status` are `('PENDING', 'SUCCESS', 'ERROR')`
## Resources
- Source code: [github.com/supabase/pg_net](https://github.com/supabase/pg_net/)
- Official Docs: [supabase.github.io/pg_net](https://supabase.github.io/pg_net/)
+4 -1
View File
@@ -124,6 +124,7 @@ const sidebars = {
'guides/database/connecting-to-postgres',
'guides/database/tables',
'guides/database/functions',
'guides/database/webhooks',
'guides/database/full-text-search',
'guides/database/migrating-between-projects',
// 'guides/database/json',
@@ -135,9 +136,11 @@ const sidebars = {
collapsed: true,
items: [
'guides/database/extensions',
'guides/database/extensions/plv8',
'guides/database/extensions/http',
'guides/database/extensions/pgcron',
'guides/database/extensions/pgnet',
'guides/database/extensions/pgtap',
'guides/database/extensions/plv8',
'guides/database/extensions/uuid-ossp',
],
},