Data fetching in the App Router is one of the most pleasant developer experiences in modern web frameworks. Server Components can declare themselves async and use await directly on fetch calls or database queries, with no need for useEffect or third-party data libraries. Because the fetch happens on the server, secrets like API keys never leave the machine. Next.js also deduplicates identical fetch requests made during a single render pass: if two components fetch the same URL with the same options, only one network call is made and the result is shared.
Caching behavior can be tuned per request. The default cache: 'force-cache' keeps responses cached indefinitely and applies to GET requests by default. Setting cache: 'no-store' disables caching for fully dynamic data, while the option next: { revalidate: 60 } enables time-based revalidation every sixty seconds. For more precise invalidation, you can tag a fetch with next: { tags: ['posts'] } and later call revalidateTag('posts') from a Server Action or Route Handler to purge every entry that shares that label.
Server Actions provide a way to handle mutations without writing API endpoints. They are async functions annotated with the "use server" directive, either inline at the top of a function or at the top of an entire module, and they can be invoked directly from forms. Passing a Server Action as the action prop of a <form> element lets the form submit even when JavaScript is disabled, making applications progressively enhanced by default.
When you do need a traditional HTTP endpoint, Route Handlers fill that role: a route.ts file exports named functions such as GET, POST, PUT, and DELETE, each receiving a standard Request object. A route segment cannot contain both route.ts and page.tsx simultaneously, so API endpoints are typically grouped under app/api/. Middleware, declared in middleware.ts at the project root, runs before a request is completed and can rewrite URLs, redirect, modify headers, or set cookies. It runs on the Edge runtime and is scoped to specific paths via the matcher configuration option, making it ideal for authentication checks and lightweight rewrites.