Supabase Functions

- Supabase has a concept of functions. These are code written in typescript, meant for deno code that gets deployed by supabase on their edge locations. - Each "function" is a standalone application, with it's own deployment, configuration, logs etc. - you create a new "function" using `supabase functions new the-name` - this command creates a folder named `supabase/functions/the-name`, with a file containing `index.ts` which looks like this:
import { serve } from "https://deno.land/[email protected]/http/server.ts"

console.log("Hello from Functions!")

serve(async (req) => {
const { name } = await req.json()
const data = {
message: `Hello ${name}!`,
}

return new Response(
JSON.stringify(data),
{ headers: { "Content-Type": "application/json" } },
)
})
- to test the function locally you have to start supabase using `supabase start` and then run functions, `supabase functions serve` - to call the function locally you have to do this:
curl --request POST 'http://localhost:54321/functions/v1/the-name' \n  --header 'Authorization: Bearer <anon key>' \n  --header 'Content-Type: application/json' \n  --data '{ "name": "Functions" }'
- on local the anon key header is optional - functions are deployed on multiple servers all around the world and supposedly have low latency benefits. - on each location, probably one instance of the "function server" runs, they auto restart the server when needed. - function server can be thought as a standlone server, written in deno, running somewhere. - the "Hello from Functions!" is printed when the "function server" starts. - the server probably starts on demand as there are many locations and there is no need to keep all of them running. In the logs I only saw one "hello from functions!" printed, so it probably started one even when there was no request, maybe to assure me, that it is indeed deployed. - the function passed to `serve()` is called on every function request.
connecting to db from function
import * as postgres from 'https://deno.land/x/[email protected]/mod.ts'
import { serve } from 'https://deno.land/[email protected]/http/server.ts'

// Get the connection string from the environment variable "SUPABASE_DB_URL"
const databaseUrl = Deno.env.get('SUPABASE_DB_URL')!

// Create a database pool with three connections that are lazily established
const pool = new postgres.Pool(databaseUrl, 3, true)

serve(async (_req) => {
try {
// Grab a connection from the pool
const connection = await pool.connect()

try {
// Run a query
const result = await connection.queryObject`SELECT * FROM animals`
const animals = result.rows // [{ id: 1, name: "Lion" }, ...]
console.log(animals)

// Encode the result as pretty printed JSON
const body = JSON.stringify(
animals,
(key, value) => (typeof value === 'bigint' ? value.toString() : value),
2
)

// Return the response with the correct content type header
return new Response(body, {
status: 200,
headers: {
'Content-Type': 'application/json; charset=utf-8',
},
})
} finally {
// Release the connection back into the pool
connection.release()
}
} catch (err) {
console.error(err)
return new Response(String(err?.message ?? err), { status: 500 })
}
})
Template strings for [safe query arguments](https://deno-postgres.com/#/?id=template-strings)
const min = 10;
const max = 20;
const result = await connection
.queryObject`SELECT ID, NAME FROM PEOPLE WHERE AGE > ${min} AND AGE < ${max}`;
console.log(result.rows);
- `connection.queryObject`SELECT * FROM animals`