See all posts

How to use Nextjs Api Route

How to use Nextjs Api Route

When you first hear API routes in Next.js, it sounds like something only back-end engineers would touch. But here’s the secret: Next.js makes working with APIs ridiculously straightforward. You don’t need a separate server, you don’t need to spin up Express, and you don’t need to juggle multiple projects. Everything is baked right in.

In this guide, we’ll explore what API routes are, how they work, practical use cases, and step-by-step examples. Whether you’re a beginner dipping your toes into full-stack development or a builder who wants to ship features fast, this post will give you everything you need to master Next.js API routes.

So grab your coffee (or tea, if you’re fancy) and let’s dig in.

What Are Next.js API Routes?

Think of API routes as your project’s built-in mini back-end. They allow you to create RESTful endpoints directly inside your Next.js app, without setting up a separate server.

A typical API route lives inside the pages/api folder. Each file becomes an endpoint. For example:

bash
/pages/api/hello.js

This file is automatically available at:

bash
http://localhost:3000/api/hello

Simple as that. No server configuration. No frameworks. Just Next.js handling the heavy lifting.

Nextjs-route

Why Use API Routes?

You might be wondering: Why not just use a dedicated back-end like Express, NestJS, or Django?

Here’s why API routes are powerful:

  1. Zero setup → You don’t need to maintain a separate server.

  2. Co-location → Your API and frontend live in the same codebase.

  3. Serverless-friendly → On platforms like Vercel, each route becomes a serverless function, scaling automatically.

  4. Perfect for small to medium apps → Great for forms, authentication, and quick integrations.

Of course, if you’re building the next Twitter, you might outgrow this and need a full backend. But for 90% of modern web apps, API routes are more than enough.

How API Routes Work

Every API route exports a function that receives two objects:

js
export default function handler(req, res) {
res.status(200).json({ message: "Hello from Next.js API route!" });
}
  • req (Request) → contains data about the incoming request (method, headers, body, query, etc.)

  • res (Response) → used to send data back to the client (status codes, JSON, etc.)

That’s it. This single function powers your endpoint.

Api-routes-work

Practical Use Cases

Here’s where API routes shine:

  1. Form handling – Capture contact form submissions and store them (or email them).

  2. Authentication – Handle login, logout, and session checks.

  3. Fetching data from external APIs – Hide your API keys and fetch securely.

  4. Database operations – Perform CRUD actions without exposing credentials on the client.

  5. Webhooks – Receive events from services like Stripe, GitHub, or Slack.

Example 1: Handling GET and POST Requests

Let’s create an endpoint that both reads and saves data.

pages/api/notes.js:

js
let notes = []; // in-memory storage for demo purposes
export default function handler(req, res) {
if (req.method === "GET") {
res.status(200).json(notes);
} else if (req.method === "POST") {
const note = req.body.note;
if (!note) {
return res.status(400).json({ error: "Note is required" });
}
notes.push(note);
res.status(201).json({ success: true, note });
} else {
res.status(405).json({ error: "Method not allowed" });
}
}
  • GET /api/notes → returns all notes.

  • POST /api/notes → adds a note to the list.

Now you have a working mini API, right inside your Next.js app.

Example 2: Connecting to a Database

In real life, you won’t just store notes in memory. Let’s integrate MongoDB:

Install dependency:

bash
npm install mongodb

lib/mongodb.js:

js
import { MongoClient } from "mongodb";
const uri = process.env.MONGODB_URI;
const options = {};
let client;
let clientPromise;
if (!process.env.MONGODB_URI) {
throw new Error("Please add your Mongo URI to .env.local");
}
if (process.env.NODE_ENV === "development") {
// Reuse client in dev mode to avoid creating new connections on hot reload
if (!global._mongoClientPromise) {
client = new MongoClient(uri, options);
global._mongoClientPromise = client.connect();
}
clientPromise = global._mongoClientPromise;
} else {
client = new MongoClient(uri, options);
clientPromise = client.connect();
}
export default clientPromise;

pages/api/notes.js:

js
import clientPromise from "../../lib/mongodb";
export default async function handler(req, res) {
const client = await clientPromise;
const db = client.db("nextjs-demo");
const notesCollection = db.collection("notes");
if (req.method === "GET") {
const notes = await notesCollection.find({}).toArray();
res.status(200).json(notes);
} else if (req.method === "POST") {
const { note } = req.body;
if (!note) return res.status(400).json({ error: "Note is required" });
const result = await notesCollection.insertOne({ note });
res.status(201).json(result);
} else {
res.status(405).json({ error: "Method not allowed" });
}
}

Now your notes are stored in MongoDB, and you have a real, production-ready API.

Example 3: Hiding API Keys

Imagine you need to fetch weather data from an external API. Instead of exposing your API key in the frontend, do it in an API route:

pages/api/weather.js:

js
export default async function handler(req, res) {
const city = req.query.city || "London";
const apiKey = process.env.WEATHER_API_KEY;
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`
);
const data = await response.json();
res.status(200).json(data);
}

Now your frontend can call /api/weather?city=Paris without ever revealing the API key.

Best Practices for API Routes

  1. Validation is key → Always validate incoming data to avoid errors or abuse.

  2. Use environment variables → Never hardcode secrets or keys.

  3. Error handling → Always send clear error messages and use proper status codes.

  4. Organize your routes → For larger apps, group routes logically (/api/auth/login, /api/auth/logout).

  5. Think serverless → Remember that on Vercel, each API route is its own serverless function. Keep functions lightweight and fast.

best-api-practices

When Not to Use API Routes

API routes are great, but they’re not a silver bullet. Don’t use them if:

  • You need heavy background jobs (use a dedicated server or queue).

  • You’re building a massive API serving multiple clients (better to spin up a real backend).

  • Your app requires long-lived connections like WebSockets (serverless isn’t ideal here).

Conclusion

Next.js API routes hit a sweet spot: they let frontend developers dip into backend functionality without friction. You can handle forms, connect to a database, integrate APIs, or secure your keys — all in the same project.

For small to medium projects (and even many production apps), this built-in approach saves time, reduces complexity, and pairs perfectly with the serverless model of modern hosting.

So the next time someone tells you Next.js is “just for frontends,” you can smile and say: “Well, actually, it does backends too — built right in.”


Windframe is an AI visual editor for rapidly building stunning web UIs & websites

Start building stunning web UIs & websites!

Build from scratch or select prebuilt tailwind templates