Course

Introduction to Server Actions

intro-server-action

Not too long ago, right after the release of Server Components, Next.js released Server Actions. From Next.js v14, server actions have been officially declared as a stable feature

Insight

💡 What’s a server action?

Simply put, Server actions are functions that run on the server, but we can call them like any other normal JavaScript function.

Do not, I repeat, CONFUSE THIS WITH SERVERLESS FUNCTIONS.

Yes, they both enable server-side code execution, but they differ in purpose and integration. Serverless functions are framework-agnostic, general-purpose, and ideal for standalone backend logic, while server actions are tightly integrated with Next.js and React, focusing on UI-coupled operations and enhancing developer experience within the same application context.

To create these server actions, all you have to do is use the flag.

So, a common example of Server action you may have seen on the internet might look like this:

"use client";

async function requestUsername(formData) {
  "use server";
  const username = formData.get("username");
  // ...
}

export default function App() {
  return (
    <form action={requestUsername}>
      <input type='text' name='username' />
      <button type='submit'>Request</button>
    </form>
  );
}

You may wonder; there is a client component called App in which we have a form that’s calling requestUsername function, which seems to be using that flag.

So a client component is making a call to a function that is stored inside a server? What the heck is happening here?

It means that it isn’t just a function call. A request was actually made to the Next.js API to call that function. It’s just we can’t see them as Next.js hides it for us. It’s abstracted from us.

But under the hood, whatever we write inside the function labeled as "use server" is turned into an API with a POST method.

In short, we’re doing this

"use client";

async function requestUsername(formData) {
  const response = await fetch("some_url", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      // Add other headers as needed
    },
    body: JSON.stringify({
      username: formData.get("username"),
      // Add other key-value pairs for your request payload
    }),
  });
}

export default function App() {
  return (
    <form action={requestUsername}>
      <input type='text' name='username' />
      <button type='submit'>Request</button>
    </form>
  );
}

… a normal API request from client to server. More so like that.

Here’s how a server action works if you call it via a client component

Serverless-Actions-Mermaid-Diagram-Nov-19-2024

Let's break down this process and explain the serialization of action arguments:

  1. Invocation:

    The Client Component invokes the Server Action as if it were a regular function.

  2. Argument Serialization

    The Next.js Framework serializes the action arguments. Serialization is the process of converting complex data structures into a format that can be easily transmitted over the network and reconstructed on the server side.

    How it works:

    1. The framework identifies the Server Action being called and assigns it a unique identifier.
    2. It then converts the JavaScript objects or primitives passed as arguments into a JSON-like format.
    3. Special cases like Date objects, BigInts, or complex types are handled with custom serialization logic.
  3. Network Request

    The Framework sends a POST request to the server, which includes the action identifier and the serialized arguments.

  4. Server Processing

    The Server receives the request and deserializes the arguments, reconstructing them into JavaScript objects.

  5. Action Validation

    The Server validates that the action being called is legitimate and allowed, providing an additional security layer.

  6. Action Execution

    The Server Action is executed with the deserialized arguments. It performs any necessary operations, including database interactions.

  7. Cache Update

    The Server Action updates the server-side cache, which is part of Next.js's smart caching system.

  8. UI Update Generation

    The Server generates updated UI components based on the action results and serializes these updates.

  9. Response

    The serialized UI updates are sent back to the client.

  10. Client Update

    The Framework deserializes the UI updates and applies them to the client-side React tree without a full page reload.

Hope that makes sense.

Loading...

0 Comments

glass-bbok

No Comments Yet

Be the first to share your thoughts and start the conversation.

tick-guideNext Lesson

Server Action Demo