# How the Next.js Client Interacts with the Backend in OpenMAIC

> Discover how the Next.js client connects with the backend in OpenMAIC. Learn about API routes and server-only handlers that execute business logic and return JSON.

- Repository: [MAIC/OpenMAIC](https://github.com/THU-MAIC/OpenMAIC)
- Tags: how-to-guide
- Published: 2026-08-30

---

**OpenMAIC bridges the React frontend and server logic through Next.js 13 App Router API routes, where client-side `fetch` calls invoke server-only handlers under `app/api/**` that execute business logic and return JSON responses.**

OpenMAIC implements a classic client-server architecture using Next.js 13's App Router to separate UI rendering from data processing. The frontend operates as a **React client** using `'use client'` directives, while backend functionality resides in **API route handlers** that run exclusively on the server. This pattern allows the application to offload heavy operations like session management and agent runtime orchestration to serverless Node.js functions while maintaining a lightweight browser interface.

## Architecture Overview

The codebase follows a strict separation between client and server concerns. UI components marked with `'use client'` execute in the browser and communicate via standard HTTP requests to internal endpoints.

**Server-only execution** occurs in files under `app/api/**`, which export route handlers configured for the Node.js runtime:

```typescript
export const runtime = 'nodejs';

```

These handlers have unrestricted access to environment variables like `DATABASE_URL` and server-only utilities such as `@/lib/config/feature-flags` or the durable session store. Because they reside outside the `'use client'` boundary, they can securely perform database operations and interact with external services without exposing credentials to the browser.

## API Route Communication Flow

Every backend interaction follows a consistent request lifecycle:

1. **Client dispatch** – React components invoke `fetch()` with relative paths to `/api/*` endpoints
2. **Route handling** – Next.js matches the URL to the corresponding [`route.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/route.ts) file (e.g., `/api/agent/sessions` → [`app/api/agent/sessions/route.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/app/api/agent/sessions/route.ts))
3. **Server execution** – The handler validates requests, queries databases, and queues background workers
4. **JSON response** – Results serialize to JSON and return to the client
5. **State hydration** – React hooks (`useEffect`, `useState`) parse responses and update the UI

This architecture ensures that sensitive operations and heavy computational tasks remain server-side while the client manages only presentation logic.

## Runtime and Session Management

The primary interaction points demonstrate how OpenMAIC handles agent availability checks and conversation lifecycle management through specific API contracts.

### Probing Agent Runtime Availability

When the home page loads at [`app/page.tsx`](https://github.com/THU-MAIC/OpenMAIC/blob/main/app/page.tsx), it verifies whether the Pro workbench should render by querying the runtime status:

```typescript
useEffect(() => {
  fetch('/api/agent/runtime')
    .then(r => r.ok ? r.json() : null)
    .then(body => {
      workbenchRuntimeCache = body?.enabled === true;
      setWorkbenchRuntimeEnabled(workbenchRuntimeCache);
    })
    .catch(() => {/* ignore */});
}, []);

```

The handler at **[`app/api/agent/runtime/route.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/app/api/agent/runtime/route.ts)** evaluates feature flags and infrastructure health, returning a structured object:

```json
{ "enabled": true, "runtimeEnabled": true }

```

This boolean response determines whether the UI exposes advanced agent capabilities or falls back to basic functionality.

### Listing Active Sessions

The workspace shell in [`components/workbench/workspace/WorkspaceShell.tsx`](https://github.com/THU-MAIC/OpenMAIC/blob/main/components/workbench/workspace/WorkspaceShell.tsx) populates the navigation rail by fetching durable session records. The implementation includes timeout handling and credential propagation:

```typescript
async function fetchSessions(): Promise<ProHomeSessionItem[]> {
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), 15000);
  try {
    const response = await fetch('/api/agent/sessions', {
      credentials: 'include',
      signal: controller.signal,
    });
    if (!response.ok) throw new Error(`${response.status}`);
    const body = await response.json();
    if (!Array.isArray(body)) throw new Error('invalid list response');
    return body as ProHomeSessionItem[];
  } finally {
    clearTimeout(timeout);
  }
}

```

The corresponding handler in **[`app/api/agent/sessions/route.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/app/api/agent/sessions/route.ts)** validates the request context, extracts the owner ID from the session, and queries the persistent store for metadata arrays. This endpoint supports both retrieval and mutation operations depending on the HTTP method.

### Creating New Agent Sessions

When users initiate conversations, the client POSTs structured payloads to the same sessions endpoint:

```typescript
await fetch('/api/agent/sessions', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    prompt: userPrompt,
    skill: selectedSkillId,
    materialIds: uploadedIds,
  }),
});

```

The POST handler in **[`app/api/agent/sessions/route.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/app/api/agent/sessions/route.ts)** (lines 37‑84) performs transactional operations: creating the session record, binding uploaded materials through foreign key relationships, and queuing the initial user message for background processing by the agent worker pool. This ensures that session state persists even if the client disconnects during the request.

## Server-Side Implementation Details

API routes in OpenMAIC leverage the full Node.js ecosystem because they explicitly opt out of edge runtime constraints. The **`export const runtime = 'nodejs'`** declaration enables native modules and database drivers required for the application’s durable storage layer.

Handlers import shared server utilities using path aliases:

```typescript
import { checkFeatureFlag } from '@/lib/config/feature-flags';
import { sessionStore } from '@/lib/db/session-store';

```

This modular structure keeps business logic decoupled from HTTP transport concerns. Responses maintain a consistent JSON schema that client-side TypeScript interfaces consume, ensuring type safety across the network boundary.

## Summary

- **OpenMAIC** uses Next.js 13 App Router API routes under `app/api/**` to expose backend functionality to the React client.
- **Client components** call `fetch('/api/agent/*')` to check runtime availability, list sessions, and create new conversations.
- **Server handlers** execute in the Node.js runtime with access to databases and feature flags, returning JSON that hydrates React state.
- **Session management** combines GET requests for retrieval and POST requests for creation, both handled by [`app/api/agent/sessions/route.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/app/api/agent/sessions/route.ts).
- **Security-critical operations** remain server-only, preventing exposure of database connections or internal configuration to the browser.

## Frequently Asked Questions

### How does the OpenMAIC frontend detect if the agent runtime is available?

On initialization, the home page in [`app/page.tsx`](https://github.com/THU-MAIC/OpenMAIC/blob/main/app/page.tsx) sends a `fetch` request to `/api/agent/runtime`. The handler returns a boolean `enabled` flag derived from infrastructure health checks and feature flag evaluations. If the runtime is unavailable, the UI suppresses Pro workbench features and displays fallback content.

### What distinguishes GET from POST requests to `/api/agent/sessions`?

The GET method retrieves an array of existing session metadata for the authenticated user, validating credentials via the `credentials: 'include'` option. The POST method creates a new session record, accepts a JSON body containing the initial prompt and skill selection, and triggers background job queuing for agent processing.

### Why does OpenMAIC use API routes instead of Next.js Server Actions?

According to the OpenMAIC source code, the application relies on API routes to maintain explicit HTTP semantics and support complex request lifecycle management, such as AbortController timeouts and streaming responses. Additionally, API routes provide clearer separation of concerns for external client integration and enable consistent error handling patterns across the agent runtime interface.

### How does the client maintain authentication state across backend requests?

The client includes `credentials: 'include'` in all `fetch` calls to `/api/agent/sessions`, ensuring cookies or bearer tokens transmit automatically with each request. Server handlers validate these credentials against the session store before executing database operations, enforcing row-level security based on the extracted owner ID.