Introduction
Next.js supports creating API routes, allowing you to build backend functionality within your application. Here’s a quick guide to setting up and using custom APIs.
1. Setting Up Basic API Routes
API routes are defined in the pages/api directory. Each file in this directory maps to a unique endpoint.
Example. Basic API Route
Create File
mkdir -p pages/api
touch pages/api/hello.js
Define Handler
// pages/api/hello.js
export default function handler(req, res) {
res.status(200).json({ message: 'Hello, World!' });
}
Testing: Access the endpoint at http://localhost:3000/api/hello.
2. Handling Different HTTP Methods
You can handle various HTTP methods like GET, POST, PUT, and DELETE.
Example. Handling Methods
// pages/api/posts.js
export default function handler(req, res) {
if (req.method === 'GET') {
res.status(200).json({ message: 'GET request received' });
} else if (req.method === 'POST') {
res.status(201).json({ message: 'POST request received', data: req.body });
} else {
res.setHeader('Allow', ['GET', 'POST']);
res.status(405).end(`Method ${req.method} Not Allowed`);
}
}
3. Working with Query Parameters
Access query parameters from req. query.
Example. Query Parameters
// pages/api/posts/[id].js
export default function handler(req, res) {
const { id } = req.query;
res.status(200).json({ message: `Post ID: ${id}` });
}
4. Connecting to a Database
Connect to a database and perform CRUD operations.
Example SQLite Integration
Install SQLite
npm install sqlite3
Set Up Database Connection
// pages/api/posts.js
import sqlite3 from 'sqlite3';
import { open } from 'sqlite';
async function openDb() {
return open({
filename: './mydatabase.db',
driver: sqlite3.Database,
});
}
export default async function handler(req, res) {
const db = await openDb();
if (req.method === 'GET') {
const posts = await db.all('SELECT * FROM posts');
res.status(200).json(posts);
} else if (req.method === 'POST') {
const { title, content } = req.body;
await db.run('INSERT INTO posts (title, content) VALUES (?, ?)', [title, content]);
res.status(201).json({ message: 'Post created' });
} else {
res.setHeader('Allow', ['GET', 'POST']);
res.status(405).end(`Method ${req.method} Not Allowed`);
}
}
5. Adding Middleware
Implement custom middleware for request processing.
Example. Logging Middleware
// pages/api/posts.js
function logRequest(req, res, next) {
console.log(`Request received: ${req.method} ${req.url}`);
next();
}
export default async function handler(req, res) {
logRequest(req, res, () => {
// Actual API handling code
});
// Handle requests here
}
6. Authentication
Protect your API routes with authentication.
Example. Simple Auth Check
// pages/api/posts.js
export default async function handler(req, res) {
const token = req.headers.authorization;
if (token !== 'Bearer my-secret-token') {
return res.status(403).json({ message: 'Forbidden' });
}
// Handle requests if authenticated
}
7. Testing API Routes
Test your API routes using frameworks like Jest.
Example. Jest Test
Install Jest
npm install --save-dev jest
Write Test
// __tests__/api/posts.test.js
import { createMocks } from 'node-mocks-http';
import handler from '../../pages/api/posts';
test('returns a 200 status code for GET requests', async () => {
const { req, res } = createMocks({
method: 'GET',
});
await handler(req, res);
expect(res._
Run Tests
npm test
Summary
Next.js makes it easy to create custom APIs within your application. By defining API routes, handling different HTTP methods, working with query parameters, and integrating with databases, you can build robust backend functionalities. Adding middleware, implementing authentication, and testing further enhance your APIs, making Next.js a powerful tool for full-stack development.