chore: added a guide for edge functions routing (#20616)

This commit is contained in:
Lakshan Perera authored and GitHub committed 2024-01-23 03:46:13 +11:00
1 parent 42ca8be75b
commit 6912865aa6
2 files changed
+496 -87

No files matched your search

@@ -239,12 +239,27 @@ export const gettingstarted: NavMenuConstant = {
{ name: 'NuxtJS', url: '/guides/getting-started/quickstarts/nuxtjs' },
{ name: 'Vue', url: '/guides/getting-started/quickstarts/vue' },
{ name: 'Flutter', url: '/guides/getting-started/quickstarts/flutter' },
{ name: 'Android Kotlin', url: '/guides/getting-started/quickstarts/kotlin' },
{ name: 'SvelteKit', url: '/guides/getting-started/quickstarts/sveltekit' },
{ name: 'Laravel PHP', url: '/guides/getting-started/quickstarts/laravel' },
{ name: 'Ruby on Rails', url: '/guides/getting-started/quickstarts/ruby-on-rails' },
{
name: 'Android Kotlin',
url: '/guides/getting-started/quickstarts/kotlin',
},
{
name: 'SvelteKit',
url: '/guides/getting-started/quickstarts/sveltekit',
},
{
name: 'Laravel PHP',
url: '/guides/getting-started/quickstarts/laravel',
},
{
name: 'Ruby on Rails',
url: '/guides/getting-started/quickstarts/ruby-on-rails',
},
{ name: 'SolidJS', url: '/guides/getting-started/quickstarts/solidjs' },
{ name: 'RedwoodJS', url: '/guides/getting-started/quickstarts/redwoodjs' },
{
name: 'RedwoodJS',
url: '/guides/getting-started/quickstarts/redwoodjs',
},
{ name: 'refine', url: '/guides/getting-started/quickstarts/refine' },
],
},
@@ -496,7 +511,11 @@ export const auth = {
items: [
{ name: 'Next.js', url: '/guides/auth/quickstarts/nextjs', items: [] },
{ name: 'React', url: '/guides/auth/quickstarts/react', items: [] },
{ name: 'React Native', url: '/guides/auth/quickstarts/react-native', items: [] },
{
name: 'React Native',
url: '/guides/auth/quickstarts/react-native',
items: [],
},
],
},
{
@@ -508,8 +527,14 @@ export const auth = {
name: 'Passwordless Login',
url: '/guides/auth/passwordless-login',
items: [
{ name: 'Email Magic Link', url: '/guides/auth/passwordless-login/auth-magic-link' },
{ name: 'Email OTP', url: '/guides/auth/passwordless-login/auth-email-otp' },
{
name: 'Email Magic Link',
url: '/guides/auth/passwordless-login/auth-magic-link',
},
{
name: 'Email OTP',
url: '/guides/auth/passwordless-login/auth-email-otp',
},
{ name: 'Phone OTP', url: '/guides/auth/phone-login' },
],
},
@@ -578,7 +603,10 @@ export const auth = {
{ name: 'Managing User Data', url: '/guides/auth/managing-user-data' },
{ name: 'Multi-Factor Authentication', url: '/guides/auth/auth-mfa' },
{ name: 'Row Level Security', url: '/guides/auth/row-level-security' },
{ name: 'Column Level Security', url: '/guides/auth/column-level-security' },
{
name: 'Column Level Security',
url: '/guides/auth/column-level-security',
},
],
},
{
@@ -586,7 +614,10 @@ export const auth = {
url: undefined,
items: [
{ name: 'Overview', url: '/guides/auth/server-side/overview' },
{ name: 'Creating a client', url: '/guides/auth/server-side/creating-a-client' },
{
name: 'Creating a client',
url: '/guides/auth/server-side/creating-a-client',
},
{
name: 'Email Auth with PKCE flow',
url: '/guides/auth/server-side/email-based-auth-with-pkce-flow-for-ssr',
@@ -595,7 +626,10 @@ export const auth = {
name: 'OAuth with PKCE flow',
url: '/guides/auth/server-side/oauth-with-pkce-flow-for-ssr',
},
{ name: 'Server-side Rendering', url: '/guides/auth/server-side-rendering' },
{
name: 'Server-side Rendering',
url: '/guides/auth/server-side-rendering',
},
{
name: 'Migrating from Auth Helpers',
url: '/guides/auth/server-side/migrating-to-ssr-from-auth-helpers',
@@ -607,7 +641,10 @@ export const auth = {
url: undefined,
items: [
{ name: 'Auth UI', url: '/guides/auth/auth-helpers/auth-ui' },
{ name: 'Flutter Auth UI', url: '/guides/auth/auth-helpers/flutter-auth-ui' },
{
name: 'Flutter Auth UI',
url: '/guides/auth/auth-helpers/flutter-auth-ui',
},
],
},
{
@@ -622,7 +659,10 @@ export const auth = {
name: 'Part Two: Row Level Security',
url: '/learn/auth-deep-dive/auth-row-level-security',
},
{ name: 'Part Three: Policies', url: '/learn/auth-deep-dive/auth-policies' },
{
name: 'Part Three: Policies',
url: '/learn/auth-deep-dive/auth-policies',
},
{ name: 'Part Four: GoTrue', url: '/learn/auth-deep-dive/auth-gotrue' },
{
name: 'Part Five: Google OAuth',
@@ -643,7 +683,10 @@ export const database: NavMenuConstant = {
name: 'Fundamentals',
url: undefined,
items: [
{ name: 'Connecting to your database', url: '/guides/database/connecting-to-postgres' },
{
name: 'Connecting to your database',
url: '/guides/database/connecting-to-postgres',
},
{ name: 'Importing data', url: '/guides/database/import-data' },
{ name: 'Securing your data', url: '/guides/database/secure-data' },
],
@@ -652,7 +695,10 @@ export const database: NavMenuConstant = {
name: 'Working with your database (basics)',
url: undefined,
items: [
{ name: 'Managing tables, views, and data', url: '/guides/database/tables' },
{
name: 'Managing tables, views, and data',
url: '/guides/database/tables',
},
{ name: 'Managing indexes', url: '/guides/database/postgres/indexes' },
{
name: 'Querying joins and nested tables',
@@ -665,21 +711,45 @@ export const database: NavMenuConstant = {
name: 'Working with your database (intermediate)',
url: undefined,
items: [
{ name: 'Implementing cascade deletes', url: '/guides/database/postgres/cascade-deletes' },
{
name: 'Implementing cascade deletes',
url: '/guides/database/postgres/cascade-deletes',
},
{ name: 'Managing enums', url: '/guides/database/postgres/enums' },
{ name: 'Managing database functions', url: '/guides/database/functions' },
{ name: 'Managing database triggers', url: '/guides/database/postgres/triggers' },
{ name: 'Managing database webhooks', url: '/guides/database/webhooks' },
{ name: 'Using Full Text Search', url: '/guides/database/full-text-search' },
{ name: 'Partitioning your tables', url: '/guides/database/partitions' },
{
name: 'Managing database functions',
url: '/guides/database/functions',
},
{
name: 'Managing database triggers',
url: '/guides/database/postgres/triggers',
},
{
name: 'Managing database webhooks',
url: '/guides/database/webhooks',
},
{
name: 'Using Full Text Search',
url: '/guides/database/full-text-search',
},
{
name: 'Partitioning your tables',
url: '/guides/database/partitions',
},
],
},
{
name: 'Access and security',
url: undefined,
items: [
{ name: 'Row Level Security', url: '/guides/database/postgres/row-level-security' },
{ name: 'Managing Postgres Roles', url: '/guides/database/postgres/roles' },
{
name: 'Row Level Security',
url: '/guides/database/postgres/row-level-security',
},
{
name: 'Managing Postgres Roles',
url: '/guides/database/postgres/roles',
},
{ name: 'Managing secrets with Vault', url: '/guides/database/vault' },
],
},
@@ -687,11 +757,23 @@ export const database: NavMenuConstant = {
name: 'Configuration, optimization, and testing',
url: undefined,
items: [
{ name: 'Database configuration', url: '/guides/database/postgres/configuration' },
{ name: 'Managing database replication', url: '/guides/database/replication' },
{ name: 'Query optimization', url: '/guides/database/query-optimization' },
{
name: 'Database configuration',
url: '/guides/database/postgres/configuration',
},
{
name: 'Managing database replication',
url: '/guides/database/replication',
},
{
name: 'Query optimization',
url: '/guides/database/query-optimization',
},
{ name: 'Debugging and monitoring', url: '/guides/database/inspect' },
{ name: 'Debugging performance issues', url: '/guides/database/debugging-performance' },
{
name: 'Debugging performance issues',
url: '/guides/database/debugging-performance',
},
{ name: 'Testing your database', url: '/guides/database/testing' },
],
},
@@ -708,7 +790,10 @@ export const database: NavMenuConstant = {
name: 'plv8: Javascript Language',
url: '/guides/database/extensions/plv8',
},
{ name: 'http: RESTful Client', url: '/guides/database/extensions/http' },
{
name: 'http: RESTful Client',
url: '/guides/database/extensions/http',
},
{
name: 'index_advisor: Query optimization',
url: '/guides/database/extensions/index_advisor',
@@ -777,7 +862,10 @@ export const database: NavMenuConstant = {
name: 'pgsodium: Encryption Features',
url: '/guides/database/extensions/pgsodium',
},
{ name: 'pgTAP: Unit Testing', url: '/guides/database/extensions/pgtap' },
{
name: 'pgTAP: Unit Testing',
url: '/guides/database/extensions/pgtap',
},
{
name: 'plpgsql_check: PL/pgSQL Linter',
url: '/guides/database/extensions/plpgsql_check',
@@ -800,17 +888,38 @@ export const database: NavMenuConstant = {
name: 'Foreign Data Wrappers',
url: undefined,
items: [
{ name: 'Overview', url: '/guides/database/extensions/wrappers/overview' },
{ name: 'Connecting to Airtable', url: '/guides/database/extensions/wrappers/airtable' },
{ name: 'Connecting to AWS S3', url: '/guides/database/extensions/wrappers/s3' },
{ name: 'Connecting to BigQuery', url: '/guides/database/extensions/wrappers/bigquery' },
{
name: 'Overview',
url: '/guides/database/extensions/wrappers/overview',
},
{
name: 'Connecting to Airtable',
url: '/guides/database/extensions/wrappers/airtable',
},
{
name: 'Connecting to AWS S3',
url: '/guides/database/extensions/wrappers/s3',
},
{
name: 'Connecting to BigQuery',
url: '/guides/database/extensions/wrappers/bigquery',
},
{
name: 'Connecting to ClickHouse',
url: '/guides/database/extensions/wrappers/clickhouse',
},
{ name: 'Connecting to Firebase', url: '/guides/database/extensions/wrappers/firebase' },
{ name: 'Connecting to Logflare', url: '/guides/database/extensions/wrappers/logflare' },
{ name: 'Connecting to Stripe', url: '/guides/database/extensions/wrappers/stripe' },
{
name: 'Connecting to Firebase',
url: '/guides/database/extensions/wrappers/firebase',
},
{
name: 'Connecting to Logflare',
url: '/guides/database/extensions/wrappers/logflare',
},
{
name: 'Connecting to Stripe',
url: '/guides/database/extensions/wrappers/stripe',
},
],
},
{
@@ -841,9 +950,21 @@ export const api: NavMenuConstant = {
items: [
{ name: 'Overview', url: '/guides/api', items: [] },
{ name: 'Quickstart', url: '/guides/api/quickstart', items: [] },
{ name: 'Client Libraries', url: '/guides/api/rest/client-libs', items: [] },
{ name: 'Auto-generated Docs', url: '/guides/api/rest/auto-generated-docs', items: [] },
{ name: 'Generating TypeScript Types', url: '/guides/api/rest/generating-types', items: [] },
{
name: 'Client Libraries',
url: '/guides/api/rest/client-libs',
items: [],
},
{
name: 'Auto-generated Docs',
url: '/guides/api/rest/auto-generated-docs',
items: [],
},
{
name: 'Generating TypeScript Types',
url: '/guides/api/rest/generating-types',
items: [],
},
{
name: 'Guides',
url: '/guides/api',
@@ -881,7 +1002,10 @@ export const api: NavMenuConstant = {
name: 'Debugging performance issues',
url: '/guides/api/data-apis#debugging-performance-issues',
},
{ name: 'Using custom schemas', url: '/guides/api/using-custom-schemas' },
{
name: 'Using custom schemas',
url: '/guides/api/using-custom-schemas',
},
],
},
],
@@ -896,7 +1020,11 @@ export const graphql: NavMenuConstant = {
{ name: 'API', url: '/guides/graphql/api', items: [] },
{ name: 'Views', url: '/guides/graphql/views', items: [] },
{ name: 'Functions', url: '/guides/graphql/functions', items: [] },
{ name: 'Configuration & Customization', url: '/guides/graphql/configuration', items: [] },
{
name: 'Configuration & Customization',
url: '/guides/graphql/configuration',
items: [],
},
{ name: 'Security', url: '/guides/graphql/security', items: [] },
{
name: 'Integrations',
@@ -929,7 +1057,10 @@ export const functions: NavMenuConstant = {
name: 'Deploy to Production',
url: '/guides/functions/deploy',
},
{ name: 'Setting up your editor', url: '/guides/functions/local-development' },
{
name: 'Setting up your editor',
url: '/guides/functions/local-development',
},
],
},
{
@@ -937,8 +1068,14 @@ export const functions: NavMenuConstant = {
url: undefined,
items: [
{ name: 'Managing dependencies', url: '/guides/functions/import-maps' },
{ name: 'Managing environment variables', url: '/guides/functions/secrets' },
{ name: 'Integrating with Supabase Auth', url: '/guides/functions/auth' },
{
name: 'Managing environment variables',
url: '/guides/functions/secrets',
},
{
name: 'Integrating with Supabase Auth',
url: '/guides/functions/auth',
},
{
name: 'Integrating with Postgres',
url: '/guides/functions/connect-to-postgres',
@@ -947,37 +1084,74 @@ export const functions: NavMenuConstant = {
name: 'Integrating with Supabase Storage',
url: '/guides/functions/storage-caching',
},
{ name: 'Regional invocations', url: '/guides/functions/regional-invocation' },
{ name: 'Deploying with GitHub Actions', url: '/guides/functions/cicd-workflow' },
{
name: 'Handling Routing in Functions',
url: '/guides/functions/routing',
},
{
name: 'Regional invocations',
url: '/guides/functions/regional-invocation',
},
{
name: 'Deploying with GitHub Actions',
url: '/guides/functions/cicd-workflow',
},
],
},
{
name: 'Debugging',
url: undefined,
items: [
{ name: 'Debugging Edge Functions', url: '/guides/functions/debugging' },
{ name: 'Testing your Edge Functions', url: '/guides/functions/unit-test' },
{
name: 'Debugging Edge Functions',
url: '/guides/functions/debugging',
},
{
name: 'Testing your Edge Functions',
url: '/guides/functions/unit-test',
},
],
},
{
name: 'Examples',
url: '/guides/functions/examples',
items: [
{ name: 'CORS support for invoking from the browser', url: '/guides/functions/cors' },
{ name: 'Scheduling Functions', url: '/guides/functions/schedule-functions' },
{
name: 'CORS support for invoking from the browser',
url: '/guides/functions/cors',
},
{
name: 'Scheduling Functions',
url: '/guides/functions/schedule-functions',
},
{
name: 'Sending Push Notifications',
url: '/guides/functions/examples/push-notifications',
},
{ name: 'Generating OG images ', url: '/guides/functions/examples/og-image' },
{
name: 'Generating OG images ',
url: '/guides/functions/examples/og-image',
},
{
name: 'CAPTCHA support with Cloudflare Turnstile',
url: '/guides/functions/examples/cloudflare-turnstile',
},
{ name: 'Building a Discord Bot', url: '/guides/functions/examples/discord-bot' },
{ name: 'Building a Telegram Bot', url: '/guides/functions/examples/telegram-bot' },
{ name: 'Handling Stripe Webhooks ', url: '/guides/functions/examples/stripe-webhooks' },
{ name: 'Rate-limiting with Redis', url: '/guides/functions/examples/rate-limiting' },
{
name: 'Building a Discord Bot',
url: '/guides/functions/examples/discord-bot',
},
{
name: 'Building a Telegram Bot',
url: '/guides/functions/examples/telegram-bot',
},
{
name: 'Handling Stripe Webhooks ',
url: '/guides/functions/examples/stripe-webhooks',
},
{
name: 'Rate-limiting with Redis',
url: '/guides/functions/examples/rate-limiting',
},
{
name: 'Taking Screenshots with Puppeteer',
url: '/guides/functions/examples/screenshots',
@@ -993,12 +1167,27 @@ export const functions: NavMenuConstant = {
url: undefined,
items: [
{ name: 'Dart Edge on Supabase', url: '/guides/functions/dart-edge' },
{ name: 'Browserless.io', url: '/guides/functions/examples/screenshots' },
{ name: 'Hugging Face', url: '/guides/ai/examples/huggingface-image-captioning' },
{
name: 'Browserless.io',
url: '/guides/functions/examples/screenshots',
},
{
name: 'Hugging Face',
url: '/guides/ai/examples/huggingface-image-captioning',
},
{ name: 'OpenAI API', url: '/guides/ai/examples/openai' },
{ name: 'Sending Emails with Resend', url: '/guides/functions/examples/send-emails' },
{ name: 'Upstash Redis', url: '/guides/functions/examples/upstash-redis' },
{ name: 'Type-Safe SQL with Kysely', url: '/guides/functions/kysely-postgres' },
{
name: 'Sending Emails with Resend',
url: '/guides/functions/examples/send-emails',
},
{
name: 'Upstash Redis',
url: '/guides/functions/examples/upstash-redis',
},
{
name: 'Type-Safe SQL with Kysely',
url: '/guides/functions/kysely-postgres',
},
],
},
],
@@ -1076,20 +1265,34 @@ export const storage: NavMenuConstant = {
url: undefined,
items: [
{ name: 'Fundamentals', url: '/guides/storage/buckets/fundamentals' },
{ name: 'Creating Buckets', url: '/guides/storage/buckets/creating-buckets' },
{
name: 'Creating Buckets',
url: '/guides/storage/buckets/creating-buckets',
},
],
},
{
name: 'Security',
url: undefined,
items: [{ name: 'Access Control', url: '/guides/storage/security/access-control' }],
items: [
{
name: 'Access Control',
url: '/guides/storage/security/access-control',
},
],
},
{
name: 'Uploads',
url: undefined,
items: [
{ name: 'Standard Uploads', url: '/guides/storage/uploads/standard-uploads' },
{ name: 'Resumable Uploads', url: '/guides/storage/uploads/resumable-uploads' },
{
name: 'Standard Uploads',
url: '/guides/storage/uploads/standard-uploads',
},
{
name: 'Resumable Uploads',
url: '/guides/storage/uploads/resumable-uploads',
},
{ name: 'Limits', url: '/guides/storage/uploads/file-limits' },
],
},
@@ -1098,7 +1301,10 @@ export const storage: NavMenuConstant = {
url: undefined,
items: [
{ name: 'Serving assets', url: '/guides/storage/serving/downloads' },
{ name: 'Image Transformations', url: '/guides/storage/serving/image-transformations' },
{
name: 'Image Transformations',
url: '/guides/storage/serving/image-transformations',
},
],
},
{
@@ -1123,7 +1329,10 @@ export const storage: NavMenuConstant = {
url: undefined,
items: [
{ name: 'Database Design', url: '/guides/storage/schema/design' },
{ name: 'Helper Functions', url: '/guides/storage/schema/helper-functions' },
{
name: 'Helper Functions',
url: '/guides/storage/schema/helper-functions',
},
],
},
{
@@ -1161,11 +1370,24 @@ export const ai = {
url: undefined,
items: [
{ name: 'Vector columns', url: '/guides/ai/vector-columns' },
{ name: 'Vector indexes', url: '/guides/ai/vector-indexes', items: vectorIndexItems },
{ name: 'Engineering for scale', url: '/guides/ai/engineering-for-scale' },
{ name: 'Choosing Compute Add-on', url: '/guides/ai/choosing-compute-addon' },
{
name: 'Vector indexes',
url: '/guides/ai/vector-indexes',
items: vectorIndexItems,
},
{
name: 'Engineering for scale',
url: '/guides/ai/engineering-for-scale',
},
{
name: 'Choosing Compute Add-on',
url: '/guides/ai/choosing-compute-addon',
},
{ name: 'Going to Production', url: '/guides/ai/going-to-prod' },
{ name: 'RAG with Permissions', url: '/guides/ai/rag-with-permissions' },
{
name: 'RAG with Permissions',
url: '/guides/ai/rag-with-permissions',
},
],
},
{
@@ -1211,11 +1433,23 @@ export const ai = {
name: 'Python Examples',
url: undefined,
items: [
{ name: 'Developing locally with Vecs', url: '/guides/ai/vecs-python-client' },
{ name: 'Creating and managing collections', url: '/guides/ai/quickstarts/hello-world' },
{
name: 'Developing locally with Vecs',
url: '/guides/ai/vecs-python-client',
},
{
name: 'Creating and managing collections',
url: '/guides/ai/quickstarts/hello-world',
},
{ name: 'Text Deduplication', url: '/guides/ai/quickstarts/text-deduplication' },
{ name: 'Face similarity search', url: '/guides/ai/quickstarts/face-similarity' },
{
name: 'Text Deduplication',
url: '/guides/ai/quickstarts/text-deduplication',
},
{
name: 'Face similarity search',
url: '/guides/ai/quickstarts/face-similarity',
},
{
name: 'Image search with OpenAI CLIP',
url: '/guides/ai/examples/image-search-openai-clip',
@@ -1274,7 +1508,10 @@ export const supabase_cli: NavMenuConstant = {
url: undefined,
items: [
{ name: 'Local Development', url: '/guides/cli/local-development' },
{ name: 'Managing environments', url: '/guides/cli/managing-environments' },
{
name: 'Managing environments',
url: '/guides/cli/managing-environments',
},
{
name: 'Managing config and secrets',
url: '/guides/cli/managing-config',
@@ -1334,10 +1571,16 @@ export const platform: NavMenuConstant = {
url: undefined,
items: [
{ name: 'Access Control', url: '/guides/platform/access-control' },
{ name: 'Custom Postgres Config', url: '/guides/platform/custom-postgres-config' },
{
name: 'Custom Postgres Config',
url: '/guides/platform/custom-postgres-config',
},
{ name: 'Database Size', url: '/guides/platform/database-size' },
{ name: 'Fly Postgres', url: '/guides/platform/fly-postgres' },
{ name: 'HTTP Status Codes', url: '/guides/platform/http-status-codes' },
{
name: 'HTTP Status Codes',
url: '/guides/platform/http-status-codes',
},
{ name: 'Logging', url: '/guides/platform/logs' },
{ name: 'Metrics', url: '/guides/platform/metrics' },
{
@@ -1352,7 +1595,10 @@ export const platform: NavMenuConstant = {
name: 'Transfer Project',
url: '/guides/platform/project-transfer',
},
{ name: 'Network Restrictions', url: '/guides/platform/network-restrictions' },
{
name: 'Network Restrictions',
url: '/guides/platform/network-restrictions',
},
{ name: 'Performance Tuning', url: '/guides/platform/performance' },
{ name: 'Permissions', url: '/guides/platform/permissions' },
{ name: 'SSL Enforcement', url: '/guides/platform/ssl-enforcement' },
@@ -1363,9 +1609,18 @@ export const platform: NavMenuConstant = {
name: 'Billing',
url: undefined,
items: [
{ name: 'How billing works', url: '/guides/platform/org-based-billing' },
{ name: 'Spend caps and cost-controls', url: '/guides/platform/spend-cap' },
{ name: 'Enterprise Billing', url: '/guides/platform/enterprise-billing' },
{
name: 'How billing works',
url: '/guides/platform/org-based-billing',
},
{
name: 'Spend caps and cost-controls',
url: '/guides/platform/spend-cap',
},
{
name: 'Enterprise Billing',
url: '/guides/platform/enterprise-billing',
},
],
},
{
@@ -1396,7 +1651,10 @@ export const platform: NavMenuConstant = {
name: 'Maturity Model',
url: '/guides/platform/maturity-model',
},
{ name: 'Production Checklist', url: '/guides/platform/going-into-prod' },
{
name: 'Production Checklist',
url: '/guides/platform/going-into-prod',
},
],
},
{
@@ -1515,28 +1773,46 @@ export const self_hosting: NavMenuConstant = {
{
name: 'Storage Server',
items: [
{ name: 'Reference', url: '/reference/self-hosting-storage/introduction' },
{
name: 'Reference',
url: '/reference/self-hosting-storage/introduction',
},
{ name: 'Configuration', url: '/guides/self-hosting/storage/config' },
],
},
{
name: 'Realtime Server',
items: [
{ name: 'Reference', url: '/reference/self-hosting-realtime/introduction' },
{
name: 'Reference',
url: '/reference/self-hosting-realtime/introduction',
},
{ name: 'Configuration', url: '/guides/self-hosting/realtime/config' },
],
},
{
name: 'Analytics Server',
items: [
{ name: 'Reference', url: '/reference/self-hosting-analytics/introduction', items: [] },
{ name: 'Configuration', url: '/guides/self-hosting/analytics/config', items: [] },
{
name: 'Reference',
url: '/reference/self-hosting-analytics/introduction',
items: [],
},
{
name: 'Configuration',
url: '/guides/self-hosting/analytics/config',
items: [],
},
],
},
{
name: 'Functions Server',
items: [
{ name: 'Reference', url: '/reference/self-hosting-functions/introduction', items: [] },
{
name: 'Reference',
url: '/reference/self-hosting-functions/introduction',
items: [],
},
],
},
],
@@ -0,0 +1,133 @@
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'function-routing',
title: 'Handling Routing in Functions',
description: 'How to handle custom routing within Edge Functions.',
subtitle: 'How to handle custom routing within Edge Functions.',
}
Usually, an Edge Function is written to perform a single action (eg: write a record to the database). However, if your app's logic is split into multiple Edge Functions requests to each action may seem slower.
This is because each Edge Function needs to be booted before serving a request (known as cold starts). If an action is performed less frequently (eg: deleting a record), there is a high-chance of that function experiencing a cold-start.
One way to reduce the cold starts and increase performance of your app is to combine multiple actions into a single Edge Function. This way only one instance of the Edge Function needs to be booted and it can handle multiple requests to different actions.
For example, we can use a single Edge Function to create a typical CRUD API (create, read, update, delete records).
To combine multiple endpoints into a single Edge Function, you can use web application frameworks such as [Express](https://expressjs.com/) or [Oak](https://oakserver.github.io/oak/).
Let's dive into some examples.
## Routing with Express
Here's a simple hello world example using popular web framework Express.
Create a new function called `hello-world` using Supabase CLI:
```bash
supabase functions new hello-world
```
Copy and paste the following code:
```ts
import express from 'npm:express@4.18.2'
const app = express()
app.use(express.json())
const port = 3000
app.get('/hello-world', (req, res) => {
res.send('Hello World!')
})
app.post('/hello-world', (req, res) => {
const { name } = req.body
res.send(`Hello ${name}!`)
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
```
You will notice in the above example, we created two routes - `GET` and `POST`. The path for both routes are defined as `/hello-world`.
If you run an Express server outside of Edge Functions, you'd usually set the root path as `/` .
However, within Edge Functions, paths should always be prefixed with the function name (in this case `hello-world`).
You can deploy the function to Supabase via:
```bash
supabase deploy hello-world
```
Once the function is deployed, you can try to call the two ednpoints using cURL (or Postman).
```bash
# https://supabase.com/docs/guides/functions/deploy#invoking-remote-functions
curl --request GET 'https://<project_ref>.supabase.co/functions/v1/hello-world' \
--header 'Authorization: Bearer ANON_KEY' \
```
This should print the response as `Hello World!`, meaning it was handled by the `GET` route.
Similarly, we can make a request to the `POST` route.
```bash cURL
# https://supabase.com/docs/guides/functions/deploy#invoking-remote-functions
curl --request POST 'https://<project_ref>.supabase.co/functions/v1/hello-world' \
--header 'Authorization: Bearer ANON_KEY' \
--header 'Content-Type: application/json' \
--data '{ "name":"Foo" }'
```
We should see a response printing `Hello Foo!`.
## Using Route Parameters
We can use route parameters to capture values at specific URL segments (eg: `/tasks/:taskId/notes/:noteId`).
Here's an example Edge Function implemented using Express for managing tasks using route parameters.
Keep in mind paths must be prefixed by function name (ie. `tasks` in this example). Route parameters can only be used after the function name prefix.
```ts
import express from 'npm:express@4.18.2'
const app = express()
app.use(express.json())
app.get('/tasks', async (req, res) => {
// return all tasks
})
app.post('/tasks', async (req, res) => {
// create a task
})
app.get('/tasks/:id', async (req, res) => {
const id = req.params.id
const task = {} // get task
res.json(task)
})
app.patch('/tasks/:id', async (req, res) => {
const id = req.params.id
// modify task
})
app.delete('/tasks/:id', async (req, res) => {
const id = req.params.id
// delete task
})
```
## URL Patterns API
If you prefer not to use a web framework, you can directly use [URLPattern API](https://developer.mozilla.org/en-US/docs/Web/API/URL_Pattern_API) within your Edge Functions to implement routing.
This is ideal for small apps with only couple of routes and you want to have a custom matching algorithm.
Here is an example Edge Function using URL Patterns API: https://github.com/supabase/supabase/blob/master/examples/edge-functions/supabase/functions/restful-tasks/index.ts
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page