Deno Deploy Nedir: Node.js’den Farkları ve Avantajları
Uzun süredir Node.js ile çalışan biri olarak şunu açıkça söyleyeyim: Deno Deploy’u ilk gördüğümde “bir yenisi daha” dedim ve geçtim. Ama birkaç ay sonra production’da gerçek bir edge deployment ihtiyacı çıktığında, tekrar baktım ve ciddi anlamda etkilendim. Bu yazıda Deno Deploy’un ne olduğunu, Node.js ile farkını ve gerçek dünya senaryolarında nasıl kullanıldığını aktaracağım.
Deno Deploy Nedir?
Deno Deploy, Ryan Dahl’ın (evet, Node.js’in yaratıcısı) kurduğu Deno şirketinin sunduğu bir sunucusuz edge computing platformudur. Ama sadece platform değil, arkasında bir runtime var: Deno.
Deno, Node.js’in “yeniden tasarlanmış hali” olarak düşünebilirsiniz. Ryan Dahl, 2018’deki ünlü JSConf konuşmasında Node.js’te yaptığı 10 hatayı açıkladı ve Deno’yu bu hataları düzelterek tasarladı. Deno Deploy ise bu runtime’ı alıp dünya genelinde 35’ten fazla edge lokasyonuna dağıtıyor.
Temel mantık şu: Kodunuzu bir kez yazıyorsunuz, Deno Deploy bunu Cloudflare Workers benzeri bir mimaride, kullanıcıya en yakın sunucuda çalıştırıyor. Geleneksel sunucu kurmanıza, ölçeklendirmenize veya yönetmenize gerek kalmıyor.
Node.js ile Temel Farklar
Güvenlik Modeli
Node.js’te bir script çalıştırdığınızda, o script sisteminize tam erişime sahip olur. Dosyaları okuyabilir, ağ bağlantısı kurabilir, ortam değişkenlerine ulaşabilir. Bu “güven problemi” production ortamlarında ciddi güvenlik açıklarına yol açabilir.
Deno’da ise tam tersi: varsayılan olarak hiçbir şeye erişim yoktur. İzin sistemi explicit olarak çalışır.
# Node.js - herhangi bir kısıt yok
node server.js
# Deno - sadece ağ erişimine izin ver
deno run --allow-net server.ts
# Deno - sadece belirli dosyalara ve ağa izin ver
deno run --allow-net --allow-read=/tmp server.ts
# Deno - ortam değişkenlerine de erişim gerekiyorsa
deno run --allow-net --allow-read --allow-env server.ts
Bu yaklaşım, supply chain saldırılarına karşı çok daha güçlü bir bariyer oluşturuyor. npm ekosisteminde kötü amaçlı paket sorunu düşünüldüğünde, bu fark gerçekten kritik.
Modül Sistemi ve Paket Yönetimi
Node.js’te npm install ile node_modules klasörü oluşturursunuz. Bu klasör bazen projenin kendisinden daha büyük olur. Deno ise tamamen farklı bir yaklaşım benimsiyor.
// Node.js - package.json ve node_modules gerektirir
import express from 'express';
import { v4 as uuidv4 } from 'uuid';
// Deno - URL ile direkt import, hiç kurulum yok
import { serve } from "https://deno.land/[email protected]/http/server.ts";
import { v4 } from "https://deno.land/[email protected]/uuid/mod.ts";
Deno modülleri URL’den import eder ve bunları global bir cache’de saklar. node_modules diye bir şey yoktur. İlk çalıştırmada indirir, sonraki çalıştırmalarda cache’den kullanır. Bu yaklaşım Deno Deploy’da da geçerlidir.
Ayrıca Deno, npm paketlerini de destekler artık. npm: prefix’i ile Node.js paketlerini kullanabilirsiniz:
// Deno'da npm paketi kullanmak
import express from "npm:express@4";
import { createServer } from "npm:http";
TypeScript Desteği
Node.js’te TypeScript kullanmak için ts-node, tsx veya build adımları gerekir. Deno ise TypeScript’i natively destekler, hiçbir yapılandırma gerekmez.
# Node.js için TypeScript setup
npm install -D typescript ts-node @types/node
npx ts-node server.ts
# Deno - direkt çalıştır
deno run --allow-net server.ts
Web API Uyumluluğu
Bu fark Deno Deploy açısından en kritik olanı. Node.js, browser API’larından bağımsız kendi API’larını geliştirdi. fetch, Request, Response, URL, crypto gibi web standartları Node.js’e sonradan eklendi.
Deno ise başından beri Web API uyumlu tasarlandı. Tarayıcıda çalışan bir fetch kodu, Deno’da da çalışır. Bu, Deno Deploy’un edge’de çalışmasını kolaylaştıran temel faktörlerden biridir.
Deno Deploy’un Mimarisi
Deno Deploy, V8 Isolate teknolojisini kullanır. Her fonksiyon çağrısı izole bir V8 context’inde çalışır. Bu, geleneksel container’lardan çok daha hafif ve hızlıdır.
Cold start süresi Deno Deploy’un en güçlü yanlarından biridir. Geleneksel Lambda fonksiyonları 100-500ms cold start yaşayabilirken, Deno Deploy genellikle 0-50ms arasında kalır.
Mimari şu şekilde çalışır:
- Kod, Deno Deploy’a push edilir
- Deploy sistemi kodu 35+ edge lokasyonuna dağıtır
- İstek geldiğinde kullanıcıya en yakın lokasyon devreye girer
- V8 Isolate başlatılır ve istek işlenir
- Sonuç kullanıcıya döndürülür
İlk Deno Deploy Uygulaması
Hadi gerçek bir şey yapalım. Basit bir REST API yazıp deploy edelim.
# Deno'yu kur (Linux/macOS)
curl -fsSL https://deno.land/x/install/install.sh | sh
# Windows için
irm https://deno.land/install.ps1 | iex
# Versiyon kontrolü
deno --version
// main.ts - Basit bir REST API
import { serve } from "https://deno.land/[email protected]/http/server.ts";
const kv = await Deno.openKv();
async function handler(req: Request): Promise<Response> {
const url = new URL(req.url);
const path = url.pathname;
// CORS headers
const headers = {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
};
if (req.method === "GET" && path === "/api/items") {
const items: unknown[] = [];
const iter = kv.list({ prefix: ["items"] });
for await (const entry of iter) {
items.push(entry.value);
}
return new Response(JSON.stringify({ items }), { headers });
}
if (req.method === "POST" && path === "/api/items") {
const body = await req.json();
const id = crypto.randomUUID();
await kv.set(["items", id], { id, ...body, createdAt: Date.now() });
return new Response(JSON.stringify({ success: true, id }), {
status: 201,
headers
});
}
return new Response(JSON.stringify({ error: "Not found" }), {
status: 404,
headers
});
}
serve(handler, { port: 8000 });
console.log("Server running on http://localhost:8000");
# Local'de test et
deno run --allow-net --allow-env main.ts
# Test et
curl -X POST http://localhost:8000/api/items
-H "Content-Type: application/json"
-d '{"name": "Test Item", "value": 42}'
curl http://localhost:8000/api/items
Deno KV: Edge’de Veritabanı
Deno Deploy’un en ilgi çekici özelliklerinden biri Deno KV‘dir. Global olarak dağıtılmış, key-value tabanlı bir veritabanıdır. SQLite üzerine kurulu ve Deno Deploy’da otomatik olarak global replikasyon yapar.
// deno_kv_example.ts
const kv = await Deno.openKv();
// Veri yaz
await kv.set(["users", "user123"], {
name: "Ahmet Yilmaz",
email: "[email protected]",
role: "admin"
});
// Veri oku
const user = await kv.get(["users", "user123"]);
console.log(user.value);
// Atomic transaction - race condition olmadan
const result = await kv.atomic()
.check({ key: ["counter"], versionstamp: null })
.set(["counter"], 0)
.commit();
// Sayaç artırma (atomic)
const current = await kv.get<number>(["counter"]);
await kv.atomic()
.check(current)
.set(["counter"], (current.value ?? 0) + 1)
.commit();
// TTL ile geçici veri saklama (session gibi)
await kv.set(["sessions", "abc123"], { userId: "user123" }, {
expireIn: 3600 * 1000 // 1 saat
});
Bu özellik, Redis veya harici bir cache servisi kurma ihtiyacını ortadan kaldırıyor. Özellikle session yönetimi, rate limiting veya geçici veri saklama için son derece pratik.
Gerçek Dünya Senaryosu: API Gateway
Diyelim ki şirketinizin birden fazla backend servisi var ve bunların önüne bir API gateway koymak istiyorsunuz. Geleneksel yaklaşımda Nginx veya bir Node.js servisi kurarsınız. Deno Deploy ile bunu edge’de yapabilirsiniz:
// api_gateway.ts
interface ServiceConfig {
path: string;
upstream: string;
requiresAuth: boolean;
}
const services: ServiceConfig[] = [
{ path: "/api/users", upstream: "https://users-service.internal.com", requiresAuth: true },
{ path: "/api/products", upstream: "https://products-service.internal.com", requiresAuth: false },
{ path: "/api/orders", upstream: "https://orders-service.internal.com", requiresAuth: true },
];
const kv = await Deno.openKv();
async function validateToken(token: string): Promise<boolean> {
const session = await kv.get(["sessions", token]);
return session.value !== null;
}
async function rateLimiter(ip: string): Promise<boolean> {
const key = ["ratelimit", ip];
const current = await kv.get<number>(key);
const count = current.value ?? 0;
if (count >= 100) return false;
await kv.atomic()
.check(current)
.set(key, count + 1, { expireIn: 60 * 1000 })
.commit();
return true;
}
export default async function handler(req: Request): Promise<Response> {
const clientIP = req.headers.get("x-forwarded-for") ?? "unknown";
// Rate limit kontrolü
const allowed = await rateLimiter(clientIP);
if (!allowed) {
return new Response("Too Many Requests", { status: 429 });
}
const url = new URL(req.url);
const service = services.find(s => url.pathname.startsWith(s.path));
if (!service) {
return new Response("Not Found", { status: 404 });
}
// Auth kontrolü
if (service.requiresAuth) {
const authHeader = req.headers.get("Authorization");
const token = authHeader?.replace("Bearer ", "");
if (!token || !(await validateToken(token))) {
return new Response("Unauthorized", { status: 401 });
}
}
// Upstream'e istek ilet
const upstreamUrl = service.upstream + url.pathname + url.search;
const upstreamResponse = await fetch(upstreamUrl, {
method: req.method,
headers: req.headers,
body: req.body,
});
return upstreamResponse;
}
Bu gateway, dünya genelinde otomatik olarak dağıtılır ve kullanıcılar her zaman en yakın edge node’una bağlanır.
GitHub ile CI/CD Entegrasyonu
Deno Deploy’un en pratik yanlarından biri GitHub entegrasyonu. Push yaparsınız, otomatik deploy olur.
# deployctl ile manuel deploy
deno install -gArf jsr:@deno/deployctl
# Production deploy
deployctl deploy --project=my-project main.ts
# Preview deploy (PR preview gibi)
deployctl deploy --project=my-project --no-static main.ts
GitHub Actions ile de entegre edebilirsiniz:
# .github/workflows/deploy.yml içeriği (YAML, bash değil)
# name: Deploy to Deno Deploy
# on:
# push:
# branches: [main]
# jobs:
# deploy:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v3
# - uses: denoland/deployctl@v1
# with:
# project: "my-project"
# entrypoint: "main.ts"
Deno Deploy vs Cloudflare Workers vs Vercel Edge Functions
Bu noktada “neden Deno Deploy?” diye sorabilirsiniz. Alternatifler var.
Cloudflare Workers açısından:
- Workers, Cloudflare’in kendi runtime’ını kullanır (V8 tabanlı ama Deno değil)
- Workers Script yazım tarzı biraz farklıdır
- Deno Deploy daha standart Web API’larına yakındır
- Cloudflare’in global ağı daha büyüktür (300+ lokasyon)
- Deno Deploy, TypeScript’i daha native destekler
Vercel Edge Functions açısından:
- Vercel, Next.js ekosistemiyle daha entegredir
- Deno Deploy framework agnostiktir
- Vercel’in ücretsiz tier’ı daha kısıtlıdır
- Deno Deploy, Deno KV ile built-in database sunar
Pratik karar kriterleri:
- Zaten Deno kullanıyorsanız Deno Deploy mantıklıdır
- Cloudflare ağından yararlanmak istiyorsanız Workers’a bakın
- Next.js uygulamasıysanız Vercel daha kolaydır
- Framework bağımsız, standart tabanlı bir platform istiyorsanız Deno Deploy güçlü bir seçenektir
Deno Deploy’da Ortam Değişkenleri ve Gizlilik
// secrets.ts - Deno Deploy'da environment variable kullanımı
const DATABASE_URL = Deno.env.get("DATABASE_URL");
const API_SECRET = Deno.env.get("API_SECRET");
const ENVIRONMENT = Deno.env.get("DENO_DEPLOYMENT_ID") ? "production" : "development";
if (!DATABASE_URL) {
throw new Error("DATABASE_URL environment variable is required");
}
// Harici veritabanına bağlantı (PlanetScale, Supabase, Neon, vs.)
import { createClient } from "npm:@supabase/supabase-js";
const supabase = createClient(
Deno.env.get("SUPABASE_URL") ?? "",
Deno.env.get("SUPABASE_ANON_KEY") ?? ""
);
export async function getUsers() {
const { data, error } = await supabase
.from("users")
.select("*")
.limit(100);
if (error) throw error;
return data;
}
# deployctl ile secret set etme
deployctl env set DATABASE_URL="postgresql://..." --project=my-project
deployctl env set API_SECRET="super-secret-key" --project=my-project
# Mevcut env değişkenlerini listele
deployctl env list --project=my-project
Limitler ve Dezavantajlar
Dürüst olmak gerekirse, Deno Deploy her şey için ideal değil. Sysadmin olarak şunları bilmeniz gerekiyor:
- CPU süresi sınırı: Her istek için 50ms CPU süresi var (wall time değil). Yoğun hesaplama işlemleri için uygun değil.
- Bellek sınırı: Isolate başına 512MB. Büyük veri işleme için yetmeyebilir.
- Filesystem erişimi yok: Edge ortamında dosya sistemi okuma/yazma yapamazsınız. Deno KV veya harici storage kullanmanız gerekir.
- Long-running process yok: WebSocket destekli ama uzun süren background job’lar için uygun değil.
- npm ekosistemi kısıtlı: Her npm paketi Deno Deploy’da çalışmaz. Native modüller kesinlikle çalışmaz.
- Cold start: Çok nadir de olsa cold start yaşanabilir, kritik latency gereksinimleri için test edin.
- Pricing: Free tier cömert (100K istek/gün) ama production kullanımda maliyet hesabı yapın.
Sonuç
Deno Deploy, sunucusuz edge computing dünyasında gerçekten özgün bir yer buluyor. Node.js’ten farkları sadece teknik değil, felsefi: güvenlik önce, standartlara uyum, sıfır konfigürasyon.
Eğer yeni bir edge API, webhook handler, authentication proxy veya global olarak dağıtılmış bir microservice kuruyorsanız, Deno Deploy ciddi şekilde değerlendirmeye değer. Özellikle Deno KV ile gelen built-in distributed database, pek çok senaryoda harici bir Redis veya cache katmanı ihtiyacını ortadan kaldırıyor.
Node.js’i silip Deno’ya geçin demiyorum. Production’da yıllardır çalışan Node.js uygulamalarını taşımak mantıksız olur. Ama yeni bir şey başlatıyorsanız ya da edge computing’i keşfetmek istiyorsanız, bir günlük yatırımla Deno Deploy’u deneyin. Ryan Dahl bu sefer Node.js’in yanlışlarından ders çıkararak işe başladı ve bu fark kodun her satırında hissediliyor.
