Concepts (10-15 mins)
4. Action handler

Action Handler

📝 NOTE: For example project structure reference, click here

For type reference, click here

Action handler are the async functions responsible for returning responsible back to the caller/client.

Register action handler functions by calling run in the final branch. In simple words, once the run is called then you cannot branch out more. That's it!

Back in our final branch of blogs action router,

// app/actions/index.ts
"use server";
 
import { blogsRouter } from "@/lib/action.router.ts";
 
const deleteBlogSchema = z.object({
  id: z.string(),
});
 
export const deleteBlog = blogsRouter
  .branch()
  .input(deleteBlogSchema)
  .use(async ({ context }) => {
    // ✨ context.inputs: { id: string }
    const blog = await callToDatabse(context.inputs.id);
    // extending the context
    return {
      blog: blog as Blog,
      ...context,
    };
  })
  .run(async (request, repsonse) => {
    // to access the final context
    console.log(request.context);
 
    // ✨ inference magic
    // request.context.blog: Blog
    // request.context.inputs: { id: string }
  });

Action Handler Params

ActionRequest Param

On the response object, you have various methods to send information to caller. However, you'are free to return anything from your action handlers and the returned type will be inferred on the caller's side.

// app/actions/index.ts
"use server";
import { blogsRouter } from "@/lib/action.router.ts";
 
const deleteBlogSchema = z.object({
  id: z.string(),
});
 
export const deleteBlog = blogsRouter
  .branch()
  .input(deleteBlogSchema)
  .use(async ({ context }) => {
    // ✨ context.inputs: { id: string }
    const blog = await callToDatabse(context.inputs.id);
    // extending the context
    return {
      blog: blog as Blog,
      ...context,
    };
  })
  .run(async (request, repsonse) => {
    // to access the final context
    console.log(request.context);
 
    // ✨ inference magic
    // request.context.blog: Blog
    // request.context.inputs: { id: string }
  });

ActionResponse Param

// --snip--
.run(async (request, repsonse) => {
  // to access the final context
  console.log(request.context);
  return response.data({ key: "value" });
});