# Nuxt Nitro i Server Routes w 2026: Full-Stack Vue i API Endpoints > Opanuj Nuxt Nitro server routes do budowania aplikacji full-stack Vue. Poznaj API endpoints, middleware, integrację z bazą danych oraz wzorce wdrożeń produkcyjnych z Nuxt 4. - Published: 2026-07-16 - Updated: 2026-07-16 - Author: SharpSkill - Tags: nuxt, nitro, vue, full-stack, api, server-routes - Reading time: 12 min --- Nuxt Nitro przekształca aplikacje Vue w pełnoprawne rozwiązania full-stack, dostarczając uniwersalny silnik serwerowy obsługujący API routes, middleware oraz logikę serwerową obok komponentów frontendowych. Wraz z Nuxt 4.3 i nadchodzącym Nitro v3, budowanie produkcyjnych backendów nigdy nie było tak zintegrowane z rozwojem Vue. > **Full-Stack w jednym repozytorium** > > Nitro umożliwia współdzielenie typów TypeScript między frontendem a backendem, eliminując rozbieżności kontraktów API i redukując boilerplate. Server routes znajdują się w `server/api/` i automatycznie stają się dostępne jako endpointy `/api/*`. ## Architektura silnika Nuxt Nitro Server Nitro służy jako uniwersalne środowisko uruchomieniowe JavaScript zasilające katalog server w Nuxt. W przeciwieństwie do tradycyjnych serwerów Node.js, Nitro kompiluje do bundli zoptymalizowanych pod konkretne platformy, które wdrażają się bezproblemowo na [Vercel](https://vercel.com/docs/frameworks/nuxt), [Netlify](https://docs.netlify.com/frameworks/nuxt/), Cloudflare Workers oraz standardowe środowiska Node.js bez zmian w kodzie. Architektura rozdziela odpowiedzialności poprzez konwencje katalogów: ```typescript // server/api/users.get.ts 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 skanuje cztery katalogi: `server/api` dla API routes z prefiksem `/api`, `server/routes` dla routes bez prefiksu, `server/middleware` dla interceptorów żądań oraz `server/utils` dla współdzielonych narzędzi serwerowych. Pliki poza tymi katalogami pozostają niewidoczne dla środowiska serwerowego. ## Tworzenie RESTful API Endpoints z defineEventHandler Server routes podążają za konwencjami routingu opartymi na plikach, gdzie nazwy plików mapują bezpośrednio na ścieżki URL. Sufiksy metod HTTP kontrolują, które żądania akceptuje każdy handler. ```typescript // server/api/products/[id].get.ts // 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 przyjmuje konwencje nazewnictwa Web API w przygotowaniu do Nitro v3. Właściwość `statusCode` zmienia się na `status`, a `statusMessage` na `statusText`. Chociaż starsze właściwości nadal działają, migracja do nowego nazewnictwa zapewnia kompatybilność z Nuxt 5. Obsługa żądań POST z walidacją body: ```typescript // server/api/products/index.post.ts // 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 }) ``` ## Server Middleware dla uwierzytelniania i logowania Pliki middleware wykonują się przed handlerami tras, umożliwiając obsługę przekrojowych zagadnień takich jak uwierzytelnianie, logowanie i transformacja żądań. W przeciwieństwie do handlerów tras, middleware nie zwraca bezpośrednio odpowiedzi. ```typescript // server/middleware/auth.ts 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' }) } }) ``` Obiekt `event.context` utrzymuje się między middleware a handlerami w ramach pojedynczego żądania, zapewniając typowo-bezpieczny sposób współdzielenia danych. Typy kontekstu definiuje się w pliku deklaracji: ```typescript // server/types/context.d.ts declare module 'h3' { interface H3EventContext { user?: { id: string email: string role: 'admin' | 'user' } } } ``` Do przygotowań do rozmów kwalifikacyjnych dotyczących koncepcji serwera Nuxt warto zapoznać się z modułem [pytań rekrutacyjnych o Nuxt Server Routes](/technologies/vue-nuxt/interview-questions/nuxt-server-routes). ## Integracja bazy danych z Prisma i Server Utils Narzędzia serwerowe w `server/utils/` automatycznie importują się w całym kodzie serwerowym, czyniąc klienty baz danych i współdzieloną logikę dostępnymi bez jawnych importów. ```typescript // server/utils/db.ts 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 } ``` Z globalnie dostępnym klientem bazy danych, handlery tras uzyskują do niego bezpośredni dostęp: ```typescript // server/api/posts/index.get.ts 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) } } }) ``` ## Server Plugins dla inicjalizacji runtime Pluginy serwerowe w `server/plugins/` wykonują się raz podczas startu serwera, idealnie nadając się do inicjalizacji połączeń, planowania zadań lub konfiguracji monitoringu. ```typescript // server/plugins/database.ts 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') }) }) ``` System pluginów integruje się z [hookami Nitro](https://nitro.unjs.io/guide/plugins) do zarządzania cyklem życia. Hooki uruchamiają się w określonych momentach: `request` przed obsługą, `beforeResponse` przed wysłaniem i `close` podczas zamykania. ## Typowo-bezpieczne wywołania API z komponentów Vue Narzędzie `$fetch` w Nuxt zapewnia wnioskowanie typów z tras serwerowych przy użyciu aliasu `~/server`. W połączeniu z [composable useFetch](/technologies/vue-nuxt/interview-questions/nuxt-data-fetching), komponenty konsumują API z pełnym wsparciem TypeScript. ```vue ``` ## Strategie cachowania dla Server Routes Nuxt 4.3 wprowadza ulepszone kontrole cachowania poprzez `routeRules` w `nuxt.config.ts`. Server routes korzystają z tej samej infrastruktury cachowania co strony. ```typescript // nuxt.config.ts 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 } } }) ``` Dla dynamicznej inwalidacji cache należy użyć wrappera `defineCachedEventHandler`: ```typescript // server/api/trending.get.ts 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' } }) ``` ## Obsługa błędów i formatowanie odpowiedzi Spójne odpowiedzi błędów poprawiają użyteczność API. Należy utworzyć współdzielone narzędzie do obsługi błędów: ```typescript // server/utils/errors.ts 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' }) } ``` Dla kompleksowych wzorców Vue.js i zarządzania stanem warto zapoznać się z artykułem [porównanie Pinia vs Vuex](/blog/vue-nuxt/vue-3-pinia-vs-vuex-state-management). > **Checklista produkcyjna** > > Przed wdrożeniem serwerów Nitro należy: zwalidować zmienne środowiskowe schematami Zod, zaimplementować middleware rate limiting, dodać logowanie żądań do debugowania oraz skonfigurować nagłówki CORS dla cross-origin dostępu do API. ## Wdrożenie na różnych platformach System presetów Nitro generuje zoptymalizowane buildy dla każdej platformy: ```typescript // nuxt.config.ts 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'] } } }) ``` Dla wdrożeń Node.js, output zawiera samodzielny serwer: ```bash # Build for production npm run build # Start the server node .output/server/index.mjs ``` > **Koniec wsparcia dla Nuxt 3** > > Nuxt 3 osiąga koniec wsparcia 31 lipca 2026. Projekty powinny migrować do Nuxt 4 używając [oficjalnego przewodnika migracji](https://nuxt.com/docs/getting-started/upgrade). Nuxt 5 z Nitro v3 pojawi się wkrótce potem. ## Podsumowanie - Server routes w `server/api/` automatycznie mapują się na endpointy `/api/*` z sufiksami metod HTTP (`.get.ts`, `.post.ts`) kontrolującymi typy żądań - Middleware w `server/middleware/` obsługuje uwierzytelnianie, logowanie i transformację żądań przed wykonaniem tras - Obiekt `event.context` współdzieli typowane dane między middleware a handlerami w ramach żądania - Narzędzia serwerowe w `server/utils/` automatycznie importują się w kodzie serwerowym, idealnie dla klientów baz danych i współdzielonej logiki - Nuxt 4 przyjmuje nazewnictwo Web API (`status`/`statusText`) w przygotowaniu do Nitro v3 - `defineCachedEventHandler` zapewnia cachowanie na poziomie tras z kontrolami inwalidacji - Presety Nitro umożliwiają bezproblemowe wdrożenia na Vercel, Netlify, Cloudflare i serwery Node.js --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/pl/blog/vue-nuxt/nuxt-nitro-server-routes-2026