← Back to Blog
APINext.jsBackend

Next.js API Routes: Best Practices for 2026

28 April 2026 · by Yunmin Shin

What Are Next.js API Routes in 2026?

Next.js provides two mechanisms for server-side logic: Route Handlers (files named route.ts in the App Router) and Server Actions (async functions marked with "use server"). Understanding when to use each is the first best practice.

Use Route Handlers when you need a proper HTTP endpoint — one that external services, mobile apps, or third-party integrations will call. Use Server Actions for form submissions and mutations that originate from your own Next.js frontend. Server Actions are simpler, require less boilerplate, and integrate naturally with React's form APIs.

How Should You Validate Incoming Data?

Never trust incoming request data. Validate everything with Zod before processing:

import { z } from "zod";

const schema = z.object({
  email: z.string().email(),
  amount: z.number().positive().max(100000),
});

export async function POST(request: Request) {
  const body = await request.json();
  const result = schema.safeParse(body);
  if (!result.success) {
    return Response.json({ error: result.error.flatten() }, { status: 400 });
  }
  // result.data is fully typed and validated
}

This pattern rejects malformed requests before they touch your database and gives clients a clear error response.

How Do You Handle Errors Consistently?

Create a centralized error handler that converts exceptions into consistent JSON responses. Define custom error classes (ValidationError, NotFoundError, UnauthorizedError) and map them to appropriate HTTP status codes in the handler.

Return error responses in a consistent shape across all routes:

{ "error": "Not found", "code": "ORDER_NOT_FOUND" }

This makes it straightforward for frontend code and API consumers to handle errors predictably.

What About Rate Limiting?

Any public API route needs rate limiting. Without it, a single bad actor can exhaust your database connections or OpenAI credits. Use Upstash Redis with their @upstash/ratelimit package for serverless-compatible rate limiting:

const ratelimit = new Ratelimit({
  redis: Redis.fromEnv(),
  limiter: Ratelimit.slidingWindow(10, "1 m"),
});

Apply rate limiting per IP address for public endpoints and per user ID for authenticated ones.

Should You Use Middleware?

Next.js Middleware runs on the Edge before your Route Handler executes. Use it for authentication checks, geo-routing, and bot blocking — tasks that should run on every request without waiting for a full server response.

Keep middleware lightweight. It runs on Edge Runtime, which does not support Node.js APIs like the file system. For heavier auth logic (database token verification), handle it inside the Route Handler itself.

What Are Common Mistakes to Avoid?

  • Returning sensitive data in error messages (stack traces, SQL errors)
  • Missing await on request.json() causing silent failures
  • Not setting Content-Type: application/json explicitly (though Response.json() handles this)
  • Letting database queries run without timeouts in serverless environments

Bangkok clients often request API integrations with LINE, payment gateways, or logistics providers. These patterns — validation, error handling, rate limiting — apply equally to webhook receivers and internal APIs.

Ready to Build Something Fast?

Get a free quote on LINE. We reply within 24 hours.

Ready to build something fast and scalable?

Get a free project quote on LINE. We reply within 24 hours.

무료 견적 on LINE