Next.js 15 Server Actions: The Complete Guide for 2025
Say goodbye to API routes. Server Actions are changing how we build full-stack React applications. Here is everything you need to know.
Introduction
In the past, handling form submissions in React meant creating an API route, managing loading states, handling errors manually, and ensuring type safety across the network boundary. It was tedious.
Next.js 15 Server Actions simplify this dramatically. They allow you to execute server-side code directly from your components, acting like inline API endpoints. But how do you integrate them with a robust backend like Spring Boot?
💡 Why This Matters: Server Actions reduce boilerplate, improve performance, and allow for a more seamless developer experience in 2025.
Core Concepts
Implementing Server Actions
Let's build a simple form that creates a user. We define the action in a separate file with the 'use server' directive.
'use server';
import { z } from 'zod';
import { revalidatePath } from 'next/cache';
const UserSchema = z.object({
email: z.string().email(),
name: z.string().min(2),
});
export async function createUser(prevState: any, formData: FormData) {
const validatedFields = UserSchema.safeParse({
email: formData.get('email'),
name: formData.get('name'),
});
if (!validatedFields.success) {
return {
errors: validatedFields.error.flatten().fieldErrors,
};
}
// Call Spring Boot Backend
try {
const response = await fetch('http://backend-api:8080/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(validatedFields.data),
});
if (!response.ok) throw new Error('Failed to create user');
revalidatePath('/users');
return { message: 'User created successfully!' };
} catch (e) {
return { message: 'Database Error: Failed to Create User' };
}
}The Spring Boot Backend
In many enterprise architectures, Next.js acts as the "Backend for Frontend" (BFF), while Spring Boot handles the core business logic and database interactions.
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@PostMapping
public ResponseEntity<UserDTO> createUser(@RequestBody @Valid CreateUserRequest request) {
UserDTO user = userService.createUser(request);
return ResponseEntity
.status(HttpStatus.CREATED)
.body(user);
}
}
// DTO with Validation
public class CreateUserRequest {
@NotNull
@Email
private String email;
@NotNull
@Size(min = 2)
private String name;
// Getters and Setters
}💡 Pro Tip: Ensure your Spring Boot API returns clear error codes (400 for validation, 500 for server errors) so your Next.js Server Action can handle them appropriately.
Optimistic UI Updates
Users expect instant feedback. With `useOptimistic`, you can update the UI immediately while the server action runs in the background.
'use client';
import { useOptimistic } from 'react';
import { createUser } from '@/actions/createUser';
export function UserForm({ users }: { users: User[] }) {
const [optimisticUsers, addOptimisticUser] = useOptimistic(
users,
(state, newUser: User) => [...state, newUser]
);
async function action(formData: FormData) {
const newUser = {
name: formData.get('name') as string,
email: formData.get('email') as string,
id: 'temp-id',
};
addOptimisticUser(newUser); // Instant UI update
await createUser(null, formData); // Actual server request
}
return (
<form action={action}>
{/* Form fields */}
<ul>
{optimisticUsers.map(user => (
<li key={user.id}>{user.name} ({user.email})</li>
))}
</ul>
</form>
);
}Security Considerations
Server Actions are public API endpoints. Treat them as such.
🔒 Authentication
Always check if the user is authenticated inside the Server Action.
🔒 Authorization
Verify if the user has permission to perform the action.
🔒 Input Validation
Never trust client data. Validate with Zod or Yup on the server.
🔒 Rate Limiting
Implement rate limiting to prevent abuse.
✅ Implementation Checklist
Ensure your Server Actions are production-ready:
Accelerate Your Development
Need to test your new APIs? Use our tools to validate JSON, test regex, and more.
Related Topics
Conclusion
Next.js 15 Server Actions represent a massive leap forward in React application architecture. They simplify data mutation, improve performance, and reduce the need for separate API layers in the frontend.
By combining them with a robust backend like Spring Boot, you get the best of both worlds: rapid frontend development and enterprise-grade backend reliability.