Full-stack Architecture

Backend-for-Frontend with Next.js and .NET

A practical division of responsibilities for using Next.js as a web-specific API layer while ASP.NET Core owns durable business capabilities and data access.

A browser often needs data shaped differently from the contracts exposed by domain APIs. It may need several calls combined for one screen, an HTTP-only session cookie, web-specific caching, localized presentation, or a stable façade while backend services evolve.

A Backend-for-Frontend places that composition close to the user experience. Next.js Route Handlers, Server Components, and server-side functions can serve this role, while ASP.NET Core retains business workflows, authorization rules, integrations, and data ownership. The value comes from a clear boundary—not from duplicating backend logic in TypeScript.

Diagram for Backend-for-Frontend with Next.js and .NETWEB-SPECIFIC BACKEND-FOR-FRONTENDBrowserSecure session cookieNext.js BFFCompose • shape • cacheSession • validation • rate limitASP.NET CoreAuthorize • transact • integrateReusable domain contractsData+ APIsEND-TO-END OPERATING CONTRACTIdentity context • explicit timeouts • correlation • tenant-aware caching • versioned contracts • independent rollback
Next.js composes the web experience while ASP.NET Core protects reusable business workflows and data ownership.

1. Introduce a BFF for a concrete web problem

Use a BFF when the web client repeatedly coordinates several backend calls, exposes tokens that could stay server-side, needs response shaping specific to one experience, or changes at a different pace from shared APIs. A BFF can also reduce browser exposure to internal service topology.

Do not add the layer automatically. If the browser already consumes one well-shaped API securely, another network hop may add latency and operations without enough value. Write down the client-specific responsibility that justifies the boundary.

2. Divide responsibilities deliberately

Next.js should own web composition: session-aware rendering, request and response adaptation, aggregation, cache behavior for the user experience, and endpoints used only by that frontend. ASP.NET Core should own business invariants, durable commands, authorization over domain resources, transactions, integrations, and reusable APIs.

Next.js documentation describes its backend capability as an API layer rather than a full backend replacement. Keep rules that must remain consistent across web, mobile, partner, and background clients behind .NET contracts.

  • BFF: screen-oriented aggregation and presentation shaping
  • BFF: secure session handling and server-side token exchange
  • .NET: domain authorization and workflow state transitions
  • .NET: database ownership, transactions, jobs, and integrations
  • Both: explicit contracts, timeouts, telemetry, and deployment compatibility

3. Design authentication and token flow

Prefer an HTTP-only, Secure, SameSite session cookie between browser and BFF so backend access tokens are not exposed to client JavaScript. The BFF validates the session, obtains or forwards an appropriate downstream token, and calls .NET over TLS.

The .NET API must still authenticate and authorize every request. Do not treat traffic from the BFF as automatically trusted or rely on Next.js proxy logic as the only authorization layer. Preserve user, tenant, scopes, and correlation context without forwarding arbitrary incoming headers.

4. Make aggregation resilient and observable

Set an end-to-end latency budget and explicit timeouts for each downstream call. Parallelize independent reads, avoid unbounded fan-out, cancel work when the browser disconnects, and decide whether partial data is useful or misleading. Mutations should use idempotency where retries are possible.

Trace browser request, Next.js route or render, .NET endpoint, database, and external dependencies under one correlation context. Record cache status, downstream duration, status, retry, and payload size without leaking tokens or sensitive response bodies.

  • Validate content type, payload size, and parameters at the BFF boundary
  • Rate-limit by session and operation
  • Avoid passing internal error details to the browser
  • Cache only with user and tenant boundaries represented in the key
  • Version BFF and API contracts for independent deployment

5. Deploy the BFF as a runtime component

A Next.js application that uses Route Handlers, server-side sessions, or runtime aggregation needs a compatible server or function deployment; it cannot be treated as a purely static export. Place the BFF and .NET API in the same region when practical and secure their network path according to the threat model.

Scale and monitor the two tiers independently. Use health checks that distinguish BFF availability from downstream readiness, propagate graceful failure, and rehearse rollback across contract changes. The architecture succeeds when the frontend can evolve quickly without becoming a second domain backend.

Key takeaways

What to carry into your next decision

  • Add a BFF only for a clear web-specific composition, security, or evolution need.
  • Keep durable workflows, data ownership, and domain authorization in ASP.NET Core.
  • Use secure server-side sessions while re-authorizing every request in .NET.
  • Operate the BFF as a real runtime tier with contracts, telemetry, scaling, and rollback.

Sources and further reading

Version-specific and platform guidance was checked against these primary sources.

  1. Next.js: Backend for Frontend guide
  2. Next.js: Authentication guide
  3. Microsoft: Overview of ASP.NET Core authentication