การเขียนและ Invoke Function
ไอเดียในหนึ่งประโยค
หัวข้อที่มีชื่อว่า “ไอเดียในหนึ่งประโยค”Edge Function คือ Deno.serve handler ธรรมดาที่รับ HTTP request แล้วคืน response กลับไป เรียกใช้จาก client ด้วย supabase.functions.invoke()
function จริงแบบขั้นต่ำ
หัวข้อที่มีชื่อว่า “function จริงแบบขั้นต่ำ”Deno.serve เป็น global ที่ Deno runtime มีให้ในตัว ไม่ต้อง import อะไรเพิ่ม คุณส่ง callback ที่รับ Request ที่เข้ามาแล้วคืน Response กลับไป เหมือน Fetch API ที่คุณคุ้นเคยจากฝั่ง browser อยู่แล้ว
Deno.serve(async (req) => { const { name } = await req.json() return new Response(JSON.stringify({ message: `Hello ${name}!` }), { headers: { 'Content-Type': 'application/json' }, })})ไฟล์นี้อยู่ที่ supabase/functions/hello-world/index.ts เมื่อ deploy แล้วจะเรียกได้ที่ https://<project-ref>.supabase.co/functions/v1/hello-world แต่ปกติคุณไม่ต้องประกอบ URL นี้เอง เพราะ client library จัดการให้
การเรียกใช้จาก client
หัวข้อที่มีชื่อว่า “การเรียกใช้จาก client”supabase-js มี method functions.invoke() แยกออกมาแทนที่จะใช้ fetch เปล่า ๆ เพราะทำงานที่เป็นประโยชน์ให้อัตโนมัติ
const { data, error } = await supabase.functions.invoke('hello-world', { body: { name: 'World' },})นอกจากจะ serialize body เป็น JSON ให้แล้ว invoke() ยังแนบ header Authorization ให้อัตโนมัติ เป็น access token ของ user ที่ล็อกอินอยู่ตอนนั้น หรือเป็น anon key ของโปรเจกต์ถ้าไม่มีใครล็อกอิน นั่นแปลว่า function ของคุณตรวจสอบได้ว่าใครเป็นคนเรียก (หรือยืนยันว่าไม่มีการยืนยันตัวตนเลย) โดยไม่ต้องต่อ header นี้เองในทุกครั้งที่เรียก
Secrets และ environment variables
หัวข้อที่มีชื่อว่า “Secrets และ environment variables”function มักต้องใช้ credential ที่ห้ามให้ client เห็นเด็ดขาด เช่น API key ของ third-party หรือ signing secret ตั้งค่าให้ deployed function ด้วย CLI
supabase secrets set MY_API_KEY=sk_live_examplekey123อ่านค่าในฟังก์ชันด้วย Deno.env.get
const apiKey = Deno.env.get('MY_API_KEY')สำหรับ local development supabase functions serve จะอ่านไฟล์ .env ที่วางไว้ใต้ supabase/functions/ ดังนั้นโค้ด Deno.env.get เดิมทำงานเหมือนกันไม่ว่าจะรัน local หรือรันบน function ที่ deploy แล้ว ต่างกันแค่ค่านั้นมาจากไหน
flowchart LR
client["supabase.functions.invoke('hello-world', { body })"] -->|"HTTP request + Authorization header"| edge["Deployed Deno function (Deno.serve)"]
edge -->|"Response"| client