2026'da Nuxt Nitro ve Server Routes: Full-Stack Vue ve API Endpoints

Full-stack Vue uygulamaları oluşturmak için Nuxt Nitro server routes konusunda uzmanlaşın. API endpoints, middleware, veritabanı entegrasyonu ve Nuxt 4 ile production deployment kalıplarını öğrenin.

API endpoints ve middleware akışını gösteren Nuxt Nitro server routes mimari diyagramı

Nuxt Nitro, frontend bileşenlerinin yanı sıra API routes, middleware ve sunucu tarafı mantığını yöneten evrensel bir sunucu motoru sağlayarak Vue uygulamalarını tam teşekküllü full-stack çözümlere dönüştürür. Nuxt 4.3 ve yaklaşan Nitro v3 ile production-ready backend'ler oluşturmak, Vue geliştirme süreciyle hiç bu kadar entegre olmamıştı.

Tek Repoda Full-Stack

Nitro, frontend ve backend arasında TypeScript tiplerinin paylaşılmasını sağlayarak API kontrat tutarsızlıklarını ortadan kaldırır ve boilerplate kodunu azaltır. Server routes server/api/ içinde bulunur ve otomatik olarak /api/* endpoints olarak erişilebilir hale gelir.

Nuxt Nitro Server Engine Mimarisi

Nitro, Nuxt'un server dizinini güçlendiren evrensel JavaScript sunucu çalışma zamanı olarak görev yapar. Geleneksel Node.js sunucularından farklı olarak Nitro, kod değişikliği gerektirmeden Vercel, Netlify, Cloudflare Workers ve standart Node.js ortamlarına sorunsuzca deploy edilen platforma özgü optimize edilmiş bundle'lar oluşturur.

Mimari, dizin kuralları aracılığıyla sorumlulukları ayırır:

server/api/users.get.tstypescript
export default defineEventHandler(async (event) => {
  // Nitro auto-serializes return values to JSON
  // HTTP method suffix (.get.ts) restricts to GET requests
  const users = await getUsersFromDatabase()
  return { users, count: users.length }
})

Nitro dört dizini tarar: /api öneki ile API routes için server/api, önek olmadan routes için server/routes, istek interceptor'ları için server/middleware ve paylaşılan sunucu yardımcı programları için server/utils. Bu dizinlerin dışındaki dosyalar sunucu çalışma zamanı tarafından görülmez.

defineEventHandler ile RESTful API Endpoints Oluşturma

Server routes, dosya adlarının doğrudan URL yollarına eşlendiği dosya tabanlı routing kurallarını takip eder. HTTP method son ekleri, her handler'ın hangi istekleri kabul edeceğini kontrol eder.

server/api/products/[id].get.tstypescript
// Handles GET /api/products/123
export default defineEventHandler(async (event) => {
  // Extract route parameter from URL
  const id = getRouterParam(event, 'id')
  
  if (!id) {
    throw createError({
      status: 400, // Nuxt 4 uses Web API naming (not statusCode)
      statusText: 'Product ID required' // Not statusMessage
    })
  }
  
  const product = await fetchProduct(id)
  
  if (!product) {
    throw createError({
      status: 404,
      statusText: 'Product not found'
    })
  }
  
  return product
})

Nuxt 4, Nitro v3'e hazırlık olarak Web API adlandırma kurallarını benimser. statusCode özelliği status olur ve statusMessage da statusText olur. Eski özellikler hala çalışsa da, yeni adlandırmaya geçiş Nuxt 5 ile uyumluluğu sağlar.

Body doğrulaması ile POST isteklerinin işlenmesi:

server/api/products/index.post.tstypescript
// Handles POST /api/products
import { z } from 'zod'

const ProductSchema = z.object({
  name: z.string().min(1).max(200),
  price: z.number().positive(),
  category: z.enum(['electronics', 'clothing', 'food'])
})

export default defineEventHandler(async (event) => {
  // readBody automatically parses JSON
  const body = await readBody(event)
  
  // Validate with Zod schema
  const result = ProductSchema.safeParse(body)
  
  if (!result.success) {
    throw createError({
      status: 422,
      statusText: 'Validation failed',
      data: result.error.flatten()
    })
  }
  
  const product = await createProduct(result.data)
  
  // Set 201 Created status for resource creation
  setResponseStatus(event, 201)
  return product
})

Kimlik Doğrulama ve Loglama için Server Middleware

Middleware dosyaları route handler'lardan önce çalışarak kimlik doğrulama, loglama ve istek dönüştürme gibi kesişen konuların ele alınmasını sağlar. Route handler'lardan farklı olarak, middleware doğrudan yanıt döndürmez.

server/middleware/auth.tstypescript
export default defineEventHandler(async (event) => {
  // Skip auth for public routes
  const publicRoutes = ['/api/health', '/api/auth/login']
  if (publicRoutes.includes(event.path)) {
    return // Continue to next handler
  }
  
  const authHeader = getHeader(event, 'authorization')
  
  if (!authHeader?.startsWith('Bearer ')) {
    throw createError({
      status: 401,
      statusText: 'Authentication required'
    })
  }
  
  const token = authHeader.slice(7)
  
  try {
    // Verify JWT and attach user to event context
    const user = await verifyToken(token)
    event.context.user = user
  } catch {
    throw createError({
      status: 401,
      statusText: 'Invalid or expired token'
    })
  }
})

event.context nesnesi, tek bir istek içinde middleware ve handler'lar arasında kalıcıdır ve veri paylaşımı için tip güvenli bir yol sağlar. Context tiplerini bir declaration dosyasında tanımlayın:

server/types/context.d.tstypescript
declare module 'h3' {
  interface H3EventContext {
    user?: {
      id: string
      email: string
      role: 'admin' | 'user'
    }
  }
}

Nuxt sunucu kavramları üzerine mülakat hazırlığı için Nuxt Server Routes mülakat soruları modülünü inceleyebilirsiniz.

Vue.js / Nuxt.js mülakatlarında başarılı olmaya hazır mısın?

İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.

Prisma ve Server Utils ile Veritabanı Entegrasyonu

server/utils/ içindeki sunucu yardımcı programları, tüm sunucu kodunda otomatik olarak import edilir ve veritabanı istemcileri ile paylaşılan mantığı açık import'lar olmadan erişilebilir kılar.

server/utils/db.tstypescript
import { PrismaClient } from '@prisma/client'

// Singleton pattern prevents multiple instances in development
const globalForPrisma = globalThis as unknown as {
  prisma: PrismaClient | undefined
}

export const prisma = globalForPrisma.prisma ?? new PrismaClient({
  log: process.env.NODE_ENV === 'development' 
    ? ['query', 'error', 'warn'] 
    : ['error']
})

if (process.env.NODE_ENV !== 'production') {
  globalForPrisma.prisma = prisma
}

Veritabanı istemcisi global olarak erişilebilir olduğunda, route handler'ları ona doğrudan erişir:

server/api/posts/index.get.tstypescript
export default defineEventHandler(async (event) => {
  // Query parameters for pagination
  const query = getQuery(event)
  const page = Number(query.page) || 1
  const limit = Math.min(Number(query.limit) || 10, 100)
  const skip = (page - 1) * limit
  
  // Parallel queries for data and count
  const [posts, total] = await Promise.all([
    prisma.post.findMany({
      skip,
      take: limit,
      orderBy: { createdAt: 'desc' },
      include: { author: { select: { name: true, avatar: true } } }
    }),
    prisma.post.count()
  ])
  
  return {
    posts,
    pagination: {
      page,
      limit,
      total,
      pages: Math.ceil(total / limit)
    }
  }
})

Runtime Başlatma için Server Plugins

server/plugins/ içindeki sunucu plugin'leri, sunucu başladığında bir kez çalışır ve bağlantıların başlatılması, görevlerin zamanlanması veya izlemenin kurulması için idealdir.

server/plugins/database.tstypescript
export default defineNitroPlugin(async (nitroApp) => {
  // Verify database connection on startup
  try {
    await prisma.$connect()
    console.log('Database connected successfully')
  } catch (error) {
    console.error('Database connection failed:', error)
    process.exit(1) // Fail fast if DB unavailable
  }
  
  // Graceful shutdown hook
  nitroApp.hooks.hook('close', async () => {
    await prisma.$disconnect()
    console.log('Database disconnected')
  })
})

Plugin sistemi, yaşam döngüsü yönetimi için Nitro hook'ları ile entegre olur. Hook'lar belirli noktalarda tetiklenir: işleme öncesi request, gönderme öncesi beforeResponse ve kapatma sırasında close.

Vue Bileşenlerinden Tip Güvenli API Çağrıları

Nuxt'un $fetch yardımcı programı, ~/server alias'ı kullanıldığında sunucu route'larından tip çıkarımı sağlar. useFetch composable ile birleştirildiğinde, bileşenler tam TypeScript desteği ile API'leri tüketir.

vue
<script setup lang="ts">
// Inferred return type from server/api/products/[id].get.ts
const route = useRoute()
const { data: product, status, error } = await useFetch(
  `/api/products/${route.params.id}`
)

// Mutation with optimistic updates
const { execute: updateProduct, status: updateStatus } = useFetch(
  `/api/products/${route.params.id}`,
  {
    method: 'PATCH',
    immediate: false, // Don't fetch on mount
    watch: false // Don't refetch on dependency change
  }
)

async function handleUpdate(updates: Partial<Product>) {
  await updateProduct({ body: updates })
  // Refetch to sync state
  await refreshNuxtData(`product-${route.params.id}`)
}
</script>

<template>
  <div v-if="status === 'pending'">Loading...</div>
  <div v-else-if="error">{{ error.message }}</div>
  <ProductDetail v-else :product="product" @update="handleUpdate" />
</template>

Server Routes için Önbellekleme Stratejileri

Nuxt 4.3, nuxt.config.ts içindeki routeRules aracılığıyla geliştirilmiş önbellekleme kontrolleri sunar. Server routes, sayfalarla aynı önbellekleme altyapısından yararlanır.

nuxt.config.tstypescript
export default defineNuxtConfig({
  routeRules: {
    // Cache product listings for 5 minutes
    '/api/products': { 
      cache: { 
        maxAge: 300,
        staleMaxAge: 600, // Serve stale while revalidating
        swr: true 
      } 
    },
    // No cache for user-specific data
    '/api/user/**': { cache: false },
    // Pre-render static API responses at build time
    '/api/categories': { prerender: true }
  }
})

Dinamik önbellek geçersiz kılma için defineCachedEventHandler wrapper'ını kullanın:

server/api/trending.get.tstypescript
export default defineCachedEventHandler(async (event) => {
  const trending = await calculateTrendingProducts()
  return trending
}, {
  maxAge: 60 * 5, // 5 minutes
  name: 'trending-products',
  getKey: () => 'trending', // Cache key for invalidation
  shouldBypassCache: (event) => {
    // Bypass for admin users
    return event.context.user?.role === 'admin'
  }
})

Hata Yönetimi ve Yanıt Biçimlendirme

Tutarlı hata yanıtları API kullanılabilirliğini artırır. Paylaşılan bir hata işleme yardımcı programı oluşturun:

server/utils/errors.tstypescript
import { H3Error } from 'h3'

export function handleDatabaseError(error: unknown): never {
  console.error('Database error:', error)
  
  // Prisma-specific error handling
  if (error instanceof Error && 'code' in error) {
    const prismaError = error as { code: string }
    
    if (prismaError.code === 'P2002') {
      throw createError({
        status: 409,
        statusText: 'Resource already exists'
      })
    }
    
    if (prismaError.code === 'P2025') {
      throw createError({
        status: 404,
        statusText: 'Resource not found'
      })
    }
  }
  
  throw createError({
    status: 500,
    statusText: 'Internal server error'
  })
}

Kapsamlı Vue.js kalıpları ve state yönetimi için Pinia vs Vuex karşılaştırması makalesine göz atabilirsiniz.

Production Kontrol Listesi

Nitro sunucularını deploy etmeden önce: Zod şemalarıyla ortam değişkenlerini doğrulayın, rate limiting middleware uygulayın, debugging için istek loglama ekleyin ve cross-origin API erişimi için CORS header'larını yapılandırın.

Farklı Platformlara Deployment

Nitro'nun preset sistemi her platform için optimize edilmiş build'ler oluşturur:

nuxt.config.tstypescript
export default defineNuxtConfig({
  nitro: {
    // Auto-detected on Vercel/Netlify, or specify manually
    preset: 'node-server', // 'vercel', 'netlify', 'cloudflare-workers'
    
    // Compress responses
    compressPublicAssets: true,
    
    // External packages not to bundle
    externals: {
      external: ['@prisma/client']
    }
  }
})

Node.js deployment'ları için çıktı bağımsız bir sunucu içerir:

bash
# Build for production
npm run build

# Start the server
node .output/server/index.mjs
Nuxt 3 Destek Sonu

Nuxt 3, 31 Temmuz 2026'da destek süresini tamamlıyor. Projeler resmi geçiş kılavuzunu kullanarak Nuxt 4'e geçiş yapmalıdır. Nitro v3 ile Nuxt 5 kısa süre sonra takip edecektir.

Pratik yapmaya başla!

Mülakat simülatörleri ve teknik testlerle bilgini test et.

Sonuç

  • server/api/ içindeki Server routes, HTTP method son ekleri (.get.ts, .post.ts) ile istek türlerini kontrol ederek otomatik olarak /api/* endpoint'lerine eşlenir
  • server/middleware/ içindeki Middleware, route'lar çalıştırılmadan önce kimlik doğrulama, loglama ve istek dönüşümünü yönetir
  • event.context nesnesi, bir istek içinde middleware ve handler'lar arasında tipli veri paylaşır
  • server/utils/ içindeki sunucu yardımcı programları, veritabanı istemcileri ve paylaşılan mantık için ideal olarak sunucu kodunda otomatik import edilir
  • Nuxt 4, Nitro v3'e hazırlık olarak Web API adlandırmasını (status/statusText) benimser
  • defineCachedEventHandler, geçersiz kılma kontrolleri ile route düzeyinde önbellekleme sağlar
  • Nitro preset'leri, Vercel, Netlify, Cloudflare ve Node.js sunucularına sıfır konfigürasyonla deployment sağlar

Etiketler

#nuxt
#nitro
#vue
#full-stack
#api
#server-routes

Paylaş

İlgili makaleler