# How to Find API Route Handlers in 9router: Next.js App Router Navigation Guide

> Discover how to find API route handlers in 9router's Next.js App Router implementation. Learn to locate and understand your REST API endpoints effectively.

- Repository: [decolua/9router](https://github.com/decolua/9router)
- Tags: how-to-guide
- Published: 2026-05-08

---

**9router implements its REST API using Next.js 13's App Router, where every endpoint is defined by a [`route.js`](https://github.com/decolua/9router/blob/main/route.js) file under `src/app/api/` that exports async HTTP verb handlers (`GET`, `POST`, `PUT`, `DELETE`) returning `NextResponse` objects.**

To find API route handlers in the decolua/9router repository, you must understand how the **file-system-based routing** maps URL paths to specific JavaScript files. The codebase follows Next.js 13 conventions where the directory structure under `src/app/api/` directly mirrors the API's URL structure. This guide provides the exact file paths, function signatures, and patterns used to locate and inspect every handler.

## Map URL Paths to the File System

The first step to find API route handlers in 9router is converting the endpoint URL to a file path. Remove the `/api/` prefix and append [`/route.js`](https://github.com/decolua/9router/blob/main//route.js) to locate the handler file.

- **Collection endpoints**: `/api/providers` maps to [`src/app/api/providers/route.js`](https://github.com/decolua/9router/blob/main/src/app/api/providers/route.js)
- **Dynamic segments**: URLs with parameters like `/api/providers/[id]` map to folders with bracket notation: `src/app/api/providers/[id]/route.js`

This convention applies throughout the repository. For example, the providers collection handler resides in [`src/app/api/providers/route.js`](https://github.com/decolua/9router/blob/main/src/app/api/providers/route.js), while individual provider operations exist in `src/app/api/providers/[id]/route.js` according to the source code.

## Examine Collection-Level Route Files

Collection-level endpoints handle operations on the entire resource set. In [`src/app/api/providers/route.js`](https://github.com/decolua/9router/blob/main/src/app/api/providers/route.js), the file exports two primary handlers.

**`GET` handler** returns all provider connections:

```javascript
// src/app/api/providers/route.js
export async function GET() {
  const connections = await getProviderConnections();
  // …sanitise and return…
  return NextResponse.json({ connections: safeConnections });
}

```

**`POST` handler** creates new resources by parsing the request body:

```javascript
export async function POST(request) {
  const body = await request.json();
  const { provider, apiKey, name } = body;
  // validation logic …
  const newConnection = await createProviderConnection({ provider, apiKey, name, … });
  // hide secrets before responding
  const result = { ...newConnection };
  delete result.apiKey;
  return NextResponse.json(result);
}

```

Both handlers import database functions from `@/models`, delegating data operations to `getProviderConnections` and `createProviderConnection` respectively.

## Locate Dynamic Route Handlers

Dynamic routes handle specific resource instances using bracketed folder names like `[id]`. To find API route handlers for individual resources, navigate to the dynamic segment folder.

In `src/app/api/providers/[id]/route.js`, handlers receive the `params` argument to access the URL segment:

**`GET` for specific ID**:

```javascript
export async function GET(request, { params }) {
  const { id } = await params;
  const connection = await getProviderConnectionById(id);
  // hide secrets …
  return NextResponse.json({ connection: result });
}

```

**`PUT` handler** updates existing connections:

```javascript
export async function PUT(request, { params }) {
  const { id } = await params;
  const body = await request.json();
  // merge fields, handle proxy config, update DB
  const updated = await updateProviderConnection(id, updateData);
  // hide secrets before responding
  return NextResponse.json({ connection: result });
}

```

**`DELETE` handler** removes resources:

```javascript
export async function DELETE(request, { params }) {
  const { id } = await params;
  const deleted = await deleteProviderConnection(id);
  return NextResponse.json({ message: "Connection deleted successfully" });
}

```

The `params` object destructuring pattern (`{ params }`) is consistent across all dynamic route handlers in the 9router codebase.

## Identify Supporting Files and Imports

Most handlers delegate database work to the models layer. When examining a route file, check the top-level imports for clues about data flow:

- **`@/models`** imports such as `getProviderConnections`, `createProviderConnection`, `updateProviderConnection`, and `deleteProviderConnection` indicate the business logic resides in `src/models/`
- **Local utilities** like `normalizeProxyConfig` or `normalizeProxyPoolId` may be defined within the same route file for request preprocessing
- **Validation constants** imported from `@/shared/constants` (e.g., `APIKEY_PROVIDERS`, `FREE_TIER_PROVIDERS`) enforce business rules before database operations

Additional endpoint categories follow the same pattern:

- [`src/app/api/models/route.js`](https://github.com/decolua/9router/blob/main/src/app/api/models/route.js) handles model-related operations
- [`src/app/api/v1/route.js`](https://github.com/decolua/9router/blob/main/src/app/api/v1/route.js) proxies to versioned sub-routes
- `src/app/api/usage/*` contains streaming, logs, and chart endpoints

## Summary

To find API route handlers in 9router:

- Replace `/api/` with `src/app/api/` in the URL path and append [`/route.js`](https://github.com/decolua/9router/blob/main//route.js)
- Collection endpoints use [`route.js`](https://github.com/decolua/9router/blob/main/route.js) files in the resource folder (e.g., [`src/app/api/providers/route.js`](https://github.com/decolua/9router/blob/main/src/app/api/providers/route.js))
- Dynamic segments use bracketed folders (e.g., `[id]`) containing their own [`route.js`](https://github.com/decolua/9router/blob/main/route.js) files
- Handlers export async functions named after HTTP verbs (`GET`, `POST`, `PUT`, `DELETE`)
- The `request` object provides body data via `request.json()`, while `params` provides dynamic URL segments
- Database operations are imported from `@/models`, keeping route files focused on HTTP handling

## Frequently Asked Questions

### How do I find the handler for a specific API endpoint like `/api/providers/123`?

Navigate to `src/app/api/providers/[id]/route.js`. The dynamic segment `[id]` in the folder name corresponds to the `123` in your URL. Open the file and inspect the exported `GET`, `PUT`, or `DELETE` functions, which receive the ID value through the `params` argument destructured in the function signature.

### What is the difference between [`route.js`](https://github.com/decolua/9router/blob/main/route.js) in a folder versus a subfolder with brackets?

A [`route.js`](https://github.com/decolua/9router/blob/main/route.js) file directly in a resource folder (like [`src/app/api/providers/route.js`](https://github.com/decolua/9router/blob/main/src/app/api/providers/route.js)) handles collection-level operations on the entire set of resources. A [`route.js`](https://github.com/decolua/9router/blob/main/route.js) inside a bracketed subfolder (like `[id]/route.js`) handles individual resource operations where the bracket name becomes a parameter accessible via `params` in the handler function.

### Where does 9router store the actual database logic for API handlers?

The route handlers in `src/app/api/` import database functions from `src/models/` (aliased as `@/models`). For example, handlers in [`providers/route.js`](https://github.com/decolua/9router/blob/main/providers/route.js) import `getProviderConnections`, `createProviderConnection`, and similar functions from the models layer, maintaining separation between HTTP routing and data access logic.

### How do I distinguish between HTTP methods in a 9router route file?

Each HTTP verb is exported as a separate async function from [`route.js`](https://github.com/decolua/9router/blob/main/route.js). The function name matches the verb in uppercase: `GET` for retrieving data, `POST` for creating resources, `PUT` for updates, and `DELETE` for removals. Each function receives the `request` object, and dynamic routes also receive a `params` object containing URL segments.