Back to Next JS Course

Next JS Course

Next JS provides a way to create API endpoints within your application. These API routes are stored in the pages/api directory and can be used to handle various backend functionalities, such as form submissions, data fetching, and more.

Creating API Routes

API routes are created by adding files to the pages/api directory. Each file in this directory maps to a corresponding endpoint.

For example,

// pages/api/hello.js export default function handler(req, res) { res.status(200).json({ message: 'Hello, world!' }); }

Access the API route at http://localhost:3000/api/hello.

Handling Different HTTP Methods

You can handle different HTTP methods (GET, POST, PUT, DELETE) within a single API route.

For example,

// pages/api/posts.js export default function handler(req, res) { const { method } = req; switch (method) { case 'GET': res.status(200).json({ message: 'Fetching posts' }); break; case 'POST': res.status(201).json({ message: 'Creating a post' }); break; default: res.setHeader('Allow', ['GET', 'POST']); res.status(405).end(`Method ${method} Not Allowed`); } }

Dynamic API Routes

You can create dynamic API routes by using brackets in the file name.

For example,

// pages/api/posts/[id].js export default function handler(req, res) { const { id } = req.query; if (req.method === 'GET') { res.status(200).json({ message: `Fetching post with id ${id}` }); } else { res.setHeader('Allow', ['GET']); res.status(405).end(`Method ${req.method} Not Allowed`); } }

Accessing Request Body and Query Parameters

You can access the request body and query parameters in your API routes.

For example,

// pages/api/data.js export default function handler(req, res) { const { query } = req; const { body } = req; res.status(200).json({ query, body, }); }

Sending a POST request with a query parameter and body:

// POST http://localhost:3000/api/data?name=Praveen // Body: { "age": 38 }

Connecting to a Database

You can connect your API routes to a database to fetch or store data.

For example,

// pages/api/users.js import { MongoClient } from 'mongodb'; export default async function handler(req, res) { const { method } = req; const uri = process.env.MONGODB_URI; const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true }); await client.connect(); const db = client.db('mydatabase'); const collection = db.collection('users'); switch (method) { case 'GET': const users = await collection.find({}).toArray(); res.status(200).json(users); break; case 'POST': const user = req.body; await collection.insertOne(user); res.status(201).json(user); break; default: res.setHeader('Allow', ['GET', 'POST']); res.status(405).end(`Method ${method} Not Allowed`); } client.close(); }

Authentication and Middleware

You can add authentication and other middleware functions to your API routes.

// middleware/auth.js export function authenticated(req, res, next) { if (req.headers.authorization === 'Bearer my-secret-token') { next(); } else { res.status(401).json({ message: 'Unauthorized' }); } } // pages/api/secure-data.js import { authenticated } from '../../middleware/auth'; export default function handler(req, res) { authenticated(req, res, () => { res.status(200).json({ message: 'Secure data' }); }); }

Error Handling

Proper error handling ensures your API routes respond with meaningful error messages.

For example,

// pages/api/weather.js export default async function handler(req, res) { const { city } = req.query; if (!city) { res.status(400).json({ message: 'City is required' }); return; } try { const data = await fetchWeatherData(city); res.status(200).json(data); } catch (error) { console.error(error); res.status(500).json({ message: error.message }); } } async function fetchWeatherData(city) { const apiKey = process.env.OPENWEATHER_API_KEY; const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`); if (!response.ok) { throw new Error('Failed to fetch weather data'); } const data = await response.json(); return data; }