Implementation comparison

Compare two approaches side by side

REST endpoint

Several manual response branches

api/users.ts
export async function GET(request: Request) {
  const url = new URL(request.url);
  const teamId = url.searchParams.get("teamId");

  if (!teamId) {
    return Response.json({ error: "Missing teamId" }, { status: 400 });
  }

  const users = await db.user.findMany({ where: { teamId } });

  return Response.json({ users });
}

Typed action

Validated input with one return shape

users.action.ts
const input = z.object({
  teamId: z.string().min(1),
});

export const listUsers = action(input, async ({ teamId }) => {
  const users = await db.user.findMany({ where: { teamId } });

  return { users };
});