Next JS Data Fetching from API Routes


In Next.js, API routes provide a way to build API endpoints within your application. They are part of the same codebase as your frontend application, allowing you to create backend functionality alongside your frontend code. This feature is useful for handling server-side logic, accessing databases, or performing other operations without needing a separate backend server.

1. Creating API Routes

API routes are created by adding JavaScript (or TypeScript) files to the pages/api directory. Each file in this directory corresponds to an endpoint. For example, a file located at pages/api/users.js would create an API route at /api/users.

Example of an API Route

// pages/api/users.js export default function handler(req, res) { // Handle different HTTP methods if (req.method === 'GET') { // Example: Fetch users from a data source (could be a database, etc.) const users = [ { id: 1, name: 'John Doe' }, { id: 2, name: 'Jane Smith' }, ]; res.status(200).json(users); // Respond with a JSON array of users } else if (req.method === 'POST') { // Example: Add a new user (simplified for demonstration) const newUser = req.body; // Get the user data from the request body // Here, you would typically save the user to a database res.status(201).json(newUser); // Respond with the created user } else { // Handle any other HTTP method res.setHeader('Allow', ['GET', 'POST']); res.status(405).end(`Method ${req.method} Not Allowed`); } }

Explanation of the Code

  1. Handler Function: The default export is a function that handles incoming requests. It takes req (request) and res (response) as parameters.

  2. Handling HTTP Methods:

    • The function checks the HTTP method of the request (req.method).
    • If it's a GET request, it responds with a JSON array of users.
    • If it's a POST request, it retrieves the user data from the request body and responds with the created user. (In a real application, you would typically save the user to a database before responding.)
  3. Unsupported Methods: If the method is not supported, the handler sends a 405 Method Not Allowed response, setting the Allow header to indicate which methods are permitted.

2. Fetching Data from API Routes

You can fetch data from your API routes just like you would from any external API. This is often done using the fetch API or libraries like Axios.

Example: Fetching from API Route

Here’s how you can fetch data from the API route you created:

import { useEffect, useState } from 'react'; const UsersList = () => { const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchUsers = async () => { try { const response = await fetch('/api/users'); // Fetch data from the API route if (!response.ok) { throw new Error('Failed to fetch users'); } const data = await response.json(); setUsers(data); // Update state with fetched users } catch (err) { setError(err.message); // Handle errors } finally { setLoading(false); // Update loading state } }; fetchUsers(); }, []); // Run only once when the component mounts if (loading) return <p>Loading...</p>; if (error) return <p>Error: {error}</p>; return ( <ul> {users.map((user) => ( <li key={user.id}>{user.name}</li> ))} </ul> ); }; export default UsersList;

Explanation of the Code

  1. State Management:

    • users: Stores the list of fetched users.
    • loading: Indicates whether the data is being loaded.
    • error: Stores any error messages.
  2. useEffect Hook:

    • The useEffect hook is used to fetch the user data when the component mounts.
    • The fetch API is called to get data from the /api/users route.
    • The response is checked for errors, and the user data is stored in the state.
  3. Conditional Rendering:

    • While loading, a loading message is displayed.
    • If an error occurs, the error message is shown.
    • Once the data is fetched successfully, it is rendered as a list of users.

Benefits of Using API Routes

  1. Integrated Backend: API routes allow you to create backend functionality within the same Next.js application, reducing the need for a separate server.

  2. Serverless Deployment: When deployed, API routes can be served as serverless functions, enabling scalability and simplicity in hosting.

  3. Simplified Data Fetching: You can easily fetch data from your own API routes, making it straightforward to handle data flow in your application.

  4. Middleware and Authentication: You can implement authentication and middleware logic within API routes, making them secure and adaptable.

Summary

API routes in Next.js provide a powerful way to create backend endpoints that can handle data fetching and server-side logic. By using API routes, you can manage data within the same codebase as your frontend, enabling seamless interaction between client and server. Whether you're building a simple application or a complex system, API routes make it easier to handle data operations, ensuring a smooth development experience.