DEV Community

Santhanam Elumalai
Santhanam Elumalai

Posted on

Building a Robust API Layer - `api-def` Package Integration with React (NextJs) app

Welcome back! In this part, we'll demonstrate how to integrate the api-def package with a Next.js application for client-side and server-side API fetching using Tanstack Query.

Recap:

  • We explored the concept and implementation of the api-def package.

Integration with Tanstack Query:

  1. Configure Tanstack Client:
    • Create a Providers component to manage the QueryClient instance.
    • Use isServer from @tanstack/react-query to create separate clients for server and client.
 import { QueryClient, QueryClientProvider, isServer } from "@tanstack/react-query"; function makeQueryClient() { return new QueryClient({ defaultOptions: { queries: { staleTime: 60 * 1000, // Cache timeout in milliseconds }, }, }); } let browserQueryClient: QueryClient | undefined = undefined; function getQueryClient() { if (isServer) { return makeQueryClient(); } else { if (!browserQueryClient) { browserQueryClient = makeQueryClient(); } return browserQueryClient; } } export function Providers({ children }: { children: React.Node }) { const queryClient = getQueryClient(); return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;  } 
Enter fullscreen mode Exit fullscreen mode
  1. Provider Placement:
    • Wrap your application with the Providers component at the root level (e.g., in layout.tsx) to make the QueryClient context globally accessible.
 import { Providers } from "./providers"; export default function RootLayout({ children }: { children: React.Node }) { return ( <html lang="en"> <body> <Providers>{children}</Providers>  </body>  </html>  ); } 
Enter fullscreen mode Exit fullscreen mode
  1. Client-Side Fetching:
    • Create a component (e.g., Users component) that utilizes the useQuery hook from Tanstack Query.
    • Use the GetUserKeys function from api-def to define the query key for caching and invalidation.
    • Use the ApiClient from api-def within the queryFn to fetch data from the API.
 import { GetUserKeys, ApiClient } from "@repo/api-definitions"; import { useQuery } from "@tanstack/react-query"; export function Users() { const { data } = useQuery({ queryKey: GetUserKeys.getUsers({}), queryFn: async ({ queryKey }) => { const queries = queryKey[0]?.requestBody; return ApiClient.getUsers(queries || {}); }, }); return <>{JSON.stringify(data)}</>;  } 
Enter fullscreen mode Exit fullscreen mode
  1. Server-Side Prefetching:
    • Within a server component (e.g., in page.tsx), prefetch the data using queryClient.prefetchQuery before rendering the component.
    • Use the same GetUserKeys and ApiClient from api-def within the queryFn for consistency.
    • Wrap the component with a HydrationBoundary from Tanstack Query to hydrate the prefetched data on the client.
 import { dehydrate, HydrationBoundary, QueryClient } from "@tanstack/react-query"; import { GetUserKeys, ApiClient } from "@repo/api-definitions"; import { Users } from "@app/user/users"; export default async function PostsPage() { const queryClient = new QueryClient(); await queryClient.prefetchQuery({ queryKey: GetUserKeys.getUsers({}), queryFn: ({ queryKey: [requestBody] }) => { return ApiClient.getUsers(requestBody?.requestBody || {}); }, }); return ( <HydrationBoundary state={dehydrate(queryClient)}> <Users /> </HydrationBoundary>  ); } 
Enter fullscreen mode Exit fullscreen mode

Benefits:

  • Type safety: Zod ensures type safety throughout the API interactions.
  • Centralized definitions: api-def offers a single source for API definitions and endpoints.
  • Efficient caching: Tanstack Query manages caching and invalidation for optimized performance.

Next Steps:

In the upcoming post, we'll delve into the integration of another powerful tool: React Hook Form. This library will help us streamline form handling, validation, and submission processes within our React applications.

Stay tuned!

Github PR Location

Footnote: This implementation is inspired by the Tanstack Query documentation on Advanced Server-Side Rendering: Advanced Server Rendering

Top comments (0)