C++ SCHX ยท rev 4
Networking ยท current

Express + Next.js route ownership

The routing contract that prevents self-proxy loops and keeps the School-GIT public origin unified.

currentstatus
Backend developers ยท Operatorsaudience
School-GIT docssource
SCHX nativeruntime
SCHX / FEATURE LAYER

System flow

1

Request hits :3000

2

Express checks owned route

3

Otherwise proxy to :3001

4

Next resolves route locally

SCHX / FEATURE LAYER

Source map

  • server.js
  • next.config.js
  • app/api/cdn/*
SCHX / FEATURE LAYER

Architecture diagram

mermaidflowchart TD
A[Incoming request :3000] --> B{Express-owned?}
B -->|yes| C[Handle in server.js]
B -->|no| D[Proxy to Next :3001]
D --> E{Next route exists?}
E -->|yes| F[Handle in Next]
E -->|no| G[Next 404]
F -. never rewrite Next-owned API back to :3000 .-> F
SCHX / FEATURE LAYER

Authoritative ownership

The routing model works when each path has a single owner. Express should directly handle its legacy/host/runtime endpoints, while the Web Bro and OS APIs remain inside Next.js.

  • /api/cdn/execute โ†’ Express.
  • /api/cdn/files โ†’ Express.
  • /api/cdn/logs โ†’ Express.
  • /api/cdn/container-status โ†’ Express.
  • /api/cdn/profile โ†’ Express.
  • /api/cdn/apps/* โ†’ Next.js.
  • /api/cdn/os/* โ†’ Next.js.
SCHX / FEATURE LAYER

The proxy-loop failure mode

If Express proxies /api/cdn/apps/* to Next, but next.config.js rewrites generic /api/cdn/* traffic back to Express, the same request can bounce between :3000 and :3001 until it times out or resets.

The fix is not to proxy Next-owned routes back to port 3000. Keep rewrites narrowly scoped to explicit Express-owned endpoints.

text// Good mental model
Express :3000
  โ”œโ”€ /api/cdn/execute  -> handle here
  โ”œโ”€ /api/cdn/files    -> handle here
  โ””โ”€ /api/cdn/apps/*   -> proxy once to Next :3001

Next :3001
  โ””โ”€ /api/cdn/apps/*   -> handle here, no rewrite back to :3000
SCHX / FEATURE LAYER

Debugging ownership

Test the Next port directly first, then test the public Express port. If the Next request succeeds and the public request hangs, the problem is usually proxy ownership or forwarding rather than the route implementation itself.

SCHX / FEATURE LAYER

Related documentation