Centralized API Logic in Next.js with an External Backend

anisriva

Animesh Srivastava

Posted on November 9, 2024

Centralized API Logic in Next.js with an External Backend

When using an external backend with a Next.js application, maintaining centralized logic for API calls is crucial. This approach improves code maintainability, reusability, and consistency across both client and server components.

In this guide, we’ll create a centralized API service and show how to use it across different components in three simple steps. This blog will also help you gain a deeper understanding of data-fetching and caching principles tailored to various component types in Next.js.


Why Centralize API Logic?

  1. Maintainability: Centralized functions handle all API calls, making updates or bug fixes easy in a single location.
  2. Reusability: Write once, use anywhere—whether in server-side, static, or client-side components.
  3. Consistency: Centralized error handling ensures predictable responses across your app.

Step 1: Create the API Service Layer

Define API functions in a dedicated service file, services/userService.js, to fetch data from your backend:

// services/userService.js
export async function fetchUserData(userId) {
  const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/users/${userId}`);
  if (!response.ok) {
    throw new Error(`Failed to fetch user data: ${response.statusText}`);
  }
  return response.json();
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Use the Service in Server-Side Components

For server-rendered pages, call the service function directly within getServerSideProps or getStaticProps. This allows server-side data fetching with zero client-side JavaScript overhead.

// pages/user/[id].js
import { fetchUserData } from '@/services/userService';

export async function getServerSideProps({ params }) {
  const { id } = params;
  try {
    const user = await fetchUserData(id);
    return { props: { user } };
  } catch (error) {
    console.error(error);
    return { notFound: true };
  }
}

export default function UserPage({ user }) {
  return (
    <div>
      <h1>{user.name}</h1>
      <p>{user.email}</p>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Use the Service in Client-Side Components

For dynamic or interactive client components, wrap the service function in a custom hook that handles loading and error states.

// hooks/useUser.js
import { useState, useEffect } from 'react';
import { fetchUserData } from '@/services/userService';

export function useUser(userId) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    if (!userId) return;

    const getUserData = async () => {
      setLoading(true);
      try {
        const data = await fetchUserData(userId);
        setUser(data);
      } catch (err) {
        setError(err);
      } finally {
        setLoading(false);
      }
    };

    getUserData();
  }, [userId]);

  return { user, loading, error };
}
Enter fullscreen mode Exit fullscreen mode

Then, use this custom hook in your client-side component:

// components/UserProfile.js
'use client';

import { useUser } from '@/hooks/useUser';

export default function UserProfile({ userId }) {
  const { user, loading, error } = useUser(userId);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error loading user data</p>;

  return (
    <div>
      <h1>{user.name}</h1>
      <p>{user.email}</p>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Summary

Centralizing API calls in Next.js with an external backend simplifies data-fetching logic across server and client components. By organizing API logic in a service layer, we streamline updates, improve reusability, and ensure consistent error handling across your application. This setup keeps your code clean and maintainable, whether you’re fetching data on the server or client side.

💖 💪 🙅 🚩
anisriva
Animesh Srivastava

Posted on November 9, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related