Nextjs Use Server for Advanced API Integration

Author

Reads 366

Close Up Photo of Cables Plugged into the Server
Credit: pexels.com, Close Up Photo of Cables Plugged into the Server

Next.js allows you to use the server to fetch data from an API. This is done using the `getServerSideProps` method, which is a built-in function in Next.js that allows you to pre-render pages on the server at request time.

By using `getServerSideProps`, you can fetch data from an API and make it available to your components on the client-side. This is particularly useful when you need to fetch data from an API that requires authentication or has rate limiting.

For example, in the "Server-Side Rendering with getServerSideProps" section, we saw how to use `getServerSideProps` to fetch data from a fake API. The code looked like this: `export async function getServerSideProps() { ... }`. This code is executed on the server and returns an object with the fetched data.

For more insights, see: Next Js Client Side Rendering

Understanding Next.js

Next.js is a powerful framework for building server-side rendered applications, and understanding its core concepts is crucial for getting the most out of it.

Credit: youtube.com, Next.js Server Actions... 5 awesome things you can do

Server Actions have been a part of Next.js since version 13, but they're now stable and incorporated by default in version 14. This means you can use them for a variety of use cases, including fetching data from external APIs, performing business logic, and updating your database.

One of the key features of Next.js is its ability to handle server-side rendering, which is data-centric. This means that the data requirements for a page or component will dictate whether it's static or dynamic, and data fetching is highly coupled with rendering.

Here are some key differences between Next.js 13 and 14: Server Actions are now stable and incorporated by default in Next.js 14.Next.js 13 brought features like layouts and React Server Components, but also removed the "context" object and getServerSideProps function.

Next.js server-side rendering works by traversing a tree from the root layout to leaf components, collecting context on each node. This context includes the initial request and all the data your server components are going to fetch, which is used for automatic request deduplication.

You can use the NextResponse object to manipulate the response, for example by setting cookies. This is especially useful when using the redirect side-effect in Next.js, which throws an error and needs to be caught and handled carefully.

Curious to learn more? Check out: Next Js Using State Context

Work

Credit: youtube.com, How NextJS REALLY Works

In Next.js, Server Actions are asynchronous JavaScript functions that run on the server in response to user interactions on the client, making it no different than calling an async function.

These actions are triggered by a user action or business logic condition, and Next.js will serialize the request parameters and send them to the server for execution.

The server will then deserialize the request parameters and execute a function that represents the Server Action, once it's finished executing, the server will serialize the response and send it back to Next.js.

Here's a step-by-step breakdown of the process:

  1. In the client, a user action or business logic condition triggers a function call to a Server Action.
  2. Next.js will serialize the request parameters and send them to the server.
  3. The server will then deserialize the request parameters and execute a function that represents the Server Action.
  4. Once the Server Action has finished executing, the server will serialize the response and send it back to Next.js.
  5. Next.js will then deserialize the response and send it back to the front end.
  6. When the promise resolves, the front end will continue its client-side execution.

This process enables developers to create complex server-side logic without worrying about the intricacies of serialization and deserialization.

API Key Security

API Key Security is a crucial aspect of protecting your Next.js application. API keys are a secret string of characters used to identify and authenticate an application, but they don't identify the individual user making the request.

Credit: youtube.com, How to ACTUALLY Secure Your API (5 Steps)

API keys are typically used to protect APIs from unauthorized access and to track usage. However, they have a significant security limitation: anyone with the API key can access the API, regardless of who they are.

API keys implementation varies from project to project, so you should check how your target API implements API keys. You can pass API keys to the target API using Server Actions, but it may vary depending on the API.

To keep your API keys secure, you should store them in environment variables, which are safe to read in Server Actions. However, you should make sure your environment provider is secure, such as Vercel, which automatically encrypts environment variable values at rest.

It's also essential to protect your Server Actions from unauthorized access, just like you would protect API endpoints. This includes handling errors gracefully and returning meaningful error messages to the user.

Here are some best practices to keep in mind:

  • Decouple Server Actions to keep code easier to understand, maintain, reuse, and test.
  • Don't disregard the client-side, as the line between server and client blurs in Next.js.
  • Cache the results of Server Actions to improve performance.
  • Use Server Actions to handle errors and return meaningful error messages.

Configure Amplify

Credit: youtube.com, Zero-Config Deploy of a Next.js 13 SSR App with AWS Amplify Hosting | Amazon Web Services

To configure Amplify, you need to install the Amplify Next.js adapter. This adapter is crucial for accessing Amplify assets from the server.

First, install the Amplify Next.js adapter by following the instructions in your project. The adapter will help you gain access to Amplify assets from the server.

Next, create a utils/amplify-utils.ts file from the root of your project. This file will contain the code that declares the functions runWithAmplifyServerContext, cookiesClient, and AuthGetCurrentUserServer, which you'll use to access Amplify assets from the server.

These functions will be used to gain access to Amplify assets from the server, making it easier to configure Amplify for your Next.js project.

If this caught your attention, see: Next Js App Folder

Add Redirect Middleware

To add redirect middleware in Next.js, you can use the `runWithAmplifyServerContext` function to wrap `fetchAuthSession`. This middleware will redirect to `/login` when a user is not logged in.

You can use this middleware to ensure users are logged in before accessing certain pages. For example, if a user tries to access a page that requires authentication, the middleware will redirect them to the login page.

Intriguing read: Middleware Config Nextjs

Credit: youtube.com, Middleware with Next.js 14 — Course part 12

The `runWithAmplifyServerContext` function is used to run the `fetchAuthSession` function within the Amplify server context. This allows the middleware to access authentication information and redirect users accordingly.

To catch the redirect thrown by the `redirect` function in Next.js, you can use the `NextResponse` object to manipulate the response. This includes setting cookies, if needed.

By using the `runWithAmplifyServerContext` function and catching redirects with `NextResponse`, you can create robust middleware that handles authentication and redirects in Next.js.

Rendering and Requests

Server rendering is all about taking user requests as input and producing HTML, CSS, and JavaScript as output. This happens specifically per-request rendering, which is now referred to as dynamic rendering.

Dynamic rendering happens server-side, at request time, and it needs a specific user request as input. Static rendering, on the other hand, happens server-side too, but at build-time, and doesn't take a request as input.

The difference between static and dynamic rendering is all about the presence or absence of a request. To illustrate this, consider the following:

  • Dynamic rendering is about requests, while static rendering is about build-time rendering.
  • Both happen on the server, but static rendering happens before requests start hitting the server.

Rendering Is About

Credit: youtube.com, 10 Rendering Patterns for Web Apps

Rendering is about taking user requests as input and producing HTML, CSS, and JavaScript as output. This is the core idea behind Server-Side Rendering (SSR).

SSR happens server-side, at request time, which means it needs a specific user request to function. Static rendering, on the other hand, happens at build-time before requests start hitting the server.

Here's a simple way to remember the difference between static and dynamic rendering:

  • Dynamic rendering (SSR) happens server-side, at request time.
  • Static rendering happens server-side, but at build-time.

The key takeaway is that static rendering doesn't take a request as input, while dynamic rendering (SSR) needs a specific user request.

Requests Live in Context

Requests are the lifeblood of server-side rendering, and they carry valuable information that can be used to render content specific to the current user.

The HTTP request contains interesting information like who the user is, via the cookies, or what language they use, via the headers, which makes up a "server context" for the request.

This server context is created directly by the server and used to render content that is specific to the current user.

Expand your knowledge: Title of Specific Page Nextjs

Credit: youtube.com, How to Make 2500 HTTP Requests in 2 Seconds with Async & Await

In Next.js 13, the server context is accessed cleanly from any React Server Component, nested or not, using new methods like cookies and headers.

You can use this context to render content that is specific to the current user, whether you're a PHP developer maintaining a 20-year-old website or a Next.js developer trying out the latest features.

Here are the key takeaways about the server context:

  • The server context contains useful information like the current request, some derived data (like the current user), cached data, and so on.
  • Each request is associated with a server context.
  • In Next.js 13, you can access the server context from any React Server Component, at any level.

Best Practices

Decoupling Server Actions is a great way to keep your code organized and maintainable. This means writing Server Actions in a separate file, rather than including them directly in your components.

Separating concerns, as recommended in the book "Clean Code", is essential for keeping your code easy to understand and reuse. So, try to keep a separation between components and actions.

Caching the results of Server Actions can improve performance by avoiding unnecessary data fetching. If a Server Action returns data that is not frequently changing, cache the results.

Credit: youtube.com, Next.js: Authentication (Best Practices for Server Components, Actions, Middleware)

Use Server Actions to handle errors gracefully and return meaningful error messages to the users. This will help prevent frustration and improve the overall user experience.

Protect your Server Actions with the same level of security as you would an API endpoint. This means securing and protecting them from unauthorized access.

Here are some key best practices for using Server Actions:

  • Decouple of Server Actions
  • Cache the results of Server Actions
  • Use Server Actions to handle errors gracefully
  • Protect your Server Actions

API Routes

API Routes support is now available in the new app directory. To define an API route, create a file named route.tsx in the app directory.

API routes now use the standard Request object instead of express-like req and res objects. This change allows for more flexibility and ease of use.

To support multiple methods, such as GET and POST, export the corresponding functions from the route.tsx file. For example, you can export the GET and POST functions to handle requests for those methods.

Cookies can also be set in API routes using the function cookies().set, but keep in mind that you cannot set a cookie from a Server Component.

API Routes

Credit: youtube.com, NextJS 13 API Routes: Better Than Expected!

API Routes are now supported in the new app directory. They use the standard Request object instead of express-like req and res objects.

To define an API route, create a file named route.tsx in the app directory. This convention is the standard way to define API routes.

You can export the handler for the methods you want to support, such as the GET and POST functions. For example, you can export the GET and POST functions.

Alternatively, you can use the function cookies().set to set cookies in API routes and Server Actions. This is a convenient way to manage cookies.

Server Actions are a new concept introduced in Next.js 13. They are a way to define server-side actions that can be called from the client.

Handling Webhooks

Handling webhooks in API routes is a common use case, and Next.js App Router makes it simpler than in the Pages routing system. You can get the raw body request by using the request.text() method.

Credit: youtube.com, How WebHook works | System Design

This method is a game-changer for handling webhooks, making it easier to retrieve the raw body from the request. It's a straightforward approach that eliminates unnecessary complexity.

To call a server action from a client component, you have multiple options. You can define the action as the action property of a form component, call the action from a button component using the formAction property, or use the useTransition hook (if it mutates data). Alternatively, you can simply call the action like a normal function (if it doesn't mutate data).

Here are the different ways to call a server action from a client component:

  • Defining the action as the action property of a form component
  • Calling the action from a button component using the formAction property
  • Calling the action using the useTransition hook (if it mutates data)
  • Simply calling the action like a normal function (if it does not mutate data)

Defining

Defining Server Components is straightforward. Server components are the default components when rendered in the app directory.

We can't use React hooks, Context, or browser-only APIs in Server Components, but we can use Server Components only APIs like headers and cookies.

In fact, Server Components are the default component type in the new app directory, so you don't need to specify a notation to define one.

Assuming a component isn't a child of a Client Component, it will be rendered on the server and sent to the client as compiled JSX.

Sending Data to an API

Credit: youtube.com, RESTful APIs in 100 Seconds // Build an API from Scratch with Node.js Express

Sending data to an API is a fundamental aspect of API routes. You can use Server Actions to send data to a third-party API, such as when a user submits a form.

To create a Server Action, you'll add a new function that expects a single parameter of the type FormData. For example, you can create a Server Action called addComment that expects one single parameter of the type FormData.

Server Actions differ from other functions triggered by JavaScript function calls. They can be triggered from a form submission, which is useful for sending data to an API.

You can create a new Server Action by following the example of addComment. This function will be fully functional and ready to be invoked when the user submits a form.

However, if you try it out, you'll notice that the user is not aware that something is happening, as there is no "loading" or "saving" activity shown. This is because the Server Action looks unresponsive.

See what others are reading: Nextjs Server Actions File Upload

Authentication

Credit: youtube.com, Next.js App Router Authentication (Sessions, Cookies, JWTs)

Authentication is a crucial aspect of Next.js server rendering. To make authenticated requests to Convex, you'll need to pass a JWT token to either `preloadQuery` or `fetchQuery` in the third options argument.

The implementation of `getAuthToken` depends on your authentication provider. You can use either Clerk or Auth0.

To get started, you'll need to decide which authentication provider to use. Clerk and Auth0 both offer robust solutions for server-side authentication.

Here are some popular authentication providers you can use:

  • Clerk
  • Auth0

Client and Server

In Next.js 13, React Server Components can access the server context, which contains useful information like the current request, user, and cached data. This is a major change from older versions of Next.js.

You can access the server context from any React Server Component, not just at the root of the component tree. This means you can render user-specific content in client components by passing serializable values through props or client context.

The server context is hidden in Next.js 13, but it's still accessible from any React Server Component. You can use cookies and headers methods to access the server context cleanly, making it easier to render content specific to the current user.

Checkpoint: What We Have Learned

From above crop faceless male developer in black hoodie writing software code on netbook while working in light studio
Credit: pexels.com, From above crop faceless male developer in black hoodie writing software code on netbook while working in light studio

In Next.js 13, things get harder: the server context is now hidden, yet it's ubiquitous within React Server Components. This means we need to understand what happens.

You can't just read the context, you often need to extend it. This is crucial for many use cases.

To invoke a Server Action in Next.js, you have three main methods: using the action prop, the useFormState hook, or the startTransition hook. These methods allow you to trigger Server Actions in various ways.

The action prop can be used to invoke a Server Action from any HTML element, such as a button, input type="submit", or form. This is useful for situations where you want to trigger an action on a specific user interaction.

The useFormState hook is specifically designed for forms, allowing you to invoke a Server Action when the user submits a form. This is a convenient way to handle form submissions and server-side actions.

The startTransition hook can be used to invoke a Server Action from any component in your Next.js application. This gives you a flexible way to trigger Server Actions in different parts of your app.

If this caught your attention, see: Form Submit Nextjs

Client

Credit: youtube.com, The Client Server Model | Clients and Servers

Client components are the components as we know them today. They're the building blocks of your user interface, and can be rendered at any time, not just when a new request is triggered.

You can use props or client context in client components, just like you would in any other React component. This is a great way to pass information from one component to another.

One thing to keep in mind is that client components can't access the server context, at least not directly. But, you can use React Server Components to render client components, as long as they're in a different file.

In Next.js 13, you can access the server context from any React Server Component, not just at the root of the tree. This makes it much easier to use server context in your application.

You can also pass values down to client-side components using server context. Just be careful not to confuse it with normal React client-side context.

Take a look at this: Use Client Nextjs

Fetch and Cache Request Results

Credit: youtube.com, Fetching with Next.js 14 — Course part 15

Next.js extends fetch automatically and caches results per URL, working similarly to the browser HTTP cache. This deduplication and caching logic can be considered as part of the server context.

The current user is stored somewhere, in a cache, for the duration of the current server rendering. Cached data are tied to the current request only, so each user will see their own data and not the profile of their neighbor.

You can use the force-cache option for public data, so that the result is reused for all requests and not just the current one. This way, you can get the same data for all users.

However, not all APIs use HTTP, and React Server Components allow you to run any kind of server code, so you can call your database directly. To benefit from the same server-side deduplication feature, you can use React 18's cache function.

This caching mechanism lets you enhance the server context implicitly, which is suitable when the exact same request is fired twice or more. It's a kind of server context enhancement, but it falls short when facing more advanced use cases.

Redirects and Middleware

Credit: youtube.com, Effortless Protected Routes In Next.js Using Middleware

You can use middleware to add server-side redirects to your Next.js application. This middleware runs fetchAuthSession wrapped in runWithAmplifyServerContext and will redirect to /login when a user is not logged in.

In Next.js, the redirect function throws an error if you try to use it directly. Its return type is never, so you need to catch the error and follow the redirect.

To manipulate the response, you can use the NextResponse object. It's exported by the Next.js package and allows you to set cookies, for example.

Here's an interesting read: Next Js Error Boundary

Frequently Asked Questions

Does Next.js need a server?

Next.js includes its own server, but you can still use an existing backend if you have one. A custom server is only needed for specific use cases, such as programmatically starting a server for custom patterns.

Does Next.js use server-side rendering?

Yes, Next.js uses server-side rendering by default, automatically implementing server rendering with no additional configuration required. You can also opt into using client-side rendering when needed.

Margarita Champlin

Writer

Margarita Champlin is a seasoned writer with a passion for crafting informative and engaging content. With a keen eye for detail and a knack for simplifying complex topics, she has established herself as a go-to expert in the field of technology. Her writing has been featured in various publications, covering a range of topics, including Azure Monitoring.

Love What You Read? Stay Updated!

Join our community for insights, tips, and more.