Deno Edge Function Food Nutrition API Proxy
Published June 11, 2026
A Deno edge function food nutrition API proxy runs your secret key close to users worldwide. Deno runtime powers Supabase Edge Functions, Deno Deploy, and Netlify Edge. This guide shows one handler pattern you can deploy anywhere to proxy Calorie API for mobile and web clients.
Why Deno for Food API Proxies
| Feature | Benefit |
|---|---|
Native fetch | No axios dependency |
| TypeScript first | Safer query validation |
| Edge locations | Lower latency for search |
| Web Crypto | JWT verification built in |
If you use Supabase specifically, also read Supabase edge function proxy.
Universal Handler Pattern
main.ts (Deno Deploy example):
const UPSTREAM = 'https://api.calorieapi.com/api/v1';
const API_KEY = Deno.env.get('CALORIE_API_KEY');
function json(body: unknown, status = 200) {
return new Response(JSON.stringify(body), {
status,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
});
}
Deno.serve(async (req) => {
if (req.method === 'OPTIONS') {
return new Response(null, { headers: { 'Access-Control-Allow-Origin': '*' } });
}
if (!API_KEY) return json({ error: 'Misconfigured' }, 500);
const url = new URL(req.url);
const path = url.pathname;
if (path === '/search') {
const q = url.searchParams.get('q')?.trim() ?? '';
const limit = Math.min(parseInt(url.searchParams.get('limit') ?? '10', 10) || 10, 25);
if (q.length < 2 || q.length > 100) return json({ error: 'Invalid query' }, 400);
const upstream = await fetch(
`${UPSTREAM}/search/foods?q=${encodeURIComponent(q)}&limit=${limit}`,
{ headers: { 'X-API-Key': API_KEY } }
);
return new Response(await upstream.text(), {
status: upstream.status,
headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' },
});
}
if (path.startsWith('/barcode/')) {
const upc = path.replace('/barcode/', '');
if (!/^\d{8,14}$/.test(upc)) return json({ error: 'Invalid barcode' }, 400);
const upstream = await fetch(`${UPSTREAM}/search/barcode/${upc}`, {
headers: { 'X-API-Key': API_KEY },
});
return new Response(await upstream.text(), {
status: upstream.status,
headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' },
});
}
return json({ error: 'Not found' }, 404);
});
Deploy Targets
| Platform | Secret storage |
|---|---|
| Deno Deploy | Project environment variables |
| Supabase | supabase secrets set |
| Netlify Edge | Netlify env vars |
Security Checklist
- Validate
qlength and barcode regex - Restrict CORS to your app origin in production
- Optional JWT gate before upstream call
- Log status codes, never log API keys
- Add per-IP rate limits via Upstash on Deno Deploy
Client Usage
const res = await fetch('https://your-edge.example.com/search?q=oats&limit=10');
const { results } = await res.json();
Mobile apps (Flutter, SwiftUI, Kotlin) use the same URL.
Deno vs Node Firebase Functions
| Deno Edge | Firebase Node | |
|---|---|---|
| Cold start | Often faster at edge | Regional |
| Ecosystem | Smaller | Larger npm |
| Best for | Global search latency | Firebase-native apps |
Pick one proxy; do not duplicate keys across three backends.
Related Guides
Frequently Asked Questions
What is a Deno edge function food API proxy?
A Deno serverless function at the edge that receives mobile or web requests, adds your secret Calorie API key, and forwards to search or barcode endpoints.
Is Deno the same as Supabase Edge Functions?
Supabase Edge Functions run on Deno. You can deploy similar proxy code on Deno Deploy or Netlify Edge with the same fetch pattern.
How do I hide my API key with Deno?
Store CALORIE_API_KEY in Deno.env platform secrets. Never import keys from files committed to git.
Can one Deno proxy serve Flutter and SwiftUI apps?
Yes. All clients call the same HTTPS search and barcode URLs. The key stays on Deno only.
Should I use Deno or Next.js for a food API proxy?
Use Deno edge when you need global latency and no Node server. Use Next.js when your site and API already live on Vercel.
