Data & Auth

Mock API

How the route handlers and mock data layer work, and how to replace them with a real backend.

How Route Handlers Work

Haze Dashboard uses Next.js Route Handlers to serve mock API routes. Files named route.ts in the src/app/api/ directory automatically become API endpoints. Each exported HTTP method (GET, POST, etc.) handles that method:

FileURL
app/api/orders/route.ts/api/orders
app/api/orders/[id]/route.ts/api/orders/123
app/api/dashboard/overview/route.ts/api/dashboard/overview

Pagination Utility

All list endpoints use a shared paginate() helper from src/server/utils/pagination.ts. It accepts query parameters for pagination, search, filtering, and sorting:

ParameterTypeDefaultDescription
pagenumber1Current page number
per_pagenumber10Items per page (max 100)
searchstringSearch term, supports nested paths like customer.name
statusstringFilter by status field
sortstringField name to sort by
orderstringdescSort direction: asc or desc

Response Format

All paginated endpoints return a consistent response structure:

{
  "data": [
    { "id": 1, "orderNumber": "ORD-001", "status": "active",  "total": 245.00 },
    { "id": 2, "orderNumber": "ORD-002", "status": "pending", "total": 189.50 }
  ],
  "meta": {
    "total": 248,
    "page": 1,
    "perPage": 10,
    "lastPage": 25
  }
}

The meta object provides everything needed to render pagination controls.

Anatomy of a Route Handler

Here is a typical list endpoint. It imports JSON data and passes it through the pagination utility:

// src/app/api/orders/route.ts
import { NextRequest } from 'next/server'
import orders from '@/server/data/orders.json'
import { paginate } from '@/server/utils/pagination'

export async function GET(request: NextRequest) {
  return paginate(request, orders, ['orderNumber', 'customer.name', 'customer.email'])
}

The third argument to paginate() specifies which fields to search when the search parameter is provided. Nested fields like customer.name are supported via dot notation.

Mock Datasets

All mock data lives in src/server/data/ as JSON files:

FileUsed By
orders.json/orders, /api/orders
products.json/products, /api/products
customers.json/customers, /api/customers
invoices.json/invoices, /api/invoices
dashboard-*.json5 dashboard variants
chat-messages.json, mail.json, kanban.json…Chat, Mail, Kanban, Calendar, Files

Adding a New Resource

To add a new API resource (e.g., tasks), follow these steps.

1. Create the data file:

// src/server/data/tasks.json
[
  { "id": 1, "title": "Review pull request",   "status": "pending",     "priority": "high" },
  { "id": 2, "title": "Update documentation",  "status": "in_progress", "priority": "medium" },
  { "id": 3, "title": "Fix navigation bug",    "status": "completed",   "priority": "high" }
]

2. Create the route handler:

// src/app/api/tasks/route.ts
import { NextRequest } from 'next/server'
import tasks from '@/server/data/tasks.json'
import { paginate } from '@/server/utils/pagination'

export async function GET(request: NextRequest) {
  return paginate(request, tasks, ['title'])
}

The endpoint is immediately available at /api/tasks with full pagination, search, and filter support.

Replacing with a Real API

When you connect a real backend (Laravel, Django, Express, etc.), you have two options:

  • Option A: Proxy through the route handlers — Update the handlers in src/app/api/ to fetch() from your real backend.
  • Option B: Point fetch calls directly — Change the fetch('/api/orders') calls in page components to point to your external API URL. Delete the route handlers you no longer need.

The key requirement is that your real API returns the same { data: [], meta: {} } response format, or you update the page components to handle the new shape.

Tip

The mock API routes work in production too — Next.js deploys them as serverless functions on Vercel, Netlify, and Cloudflare. Your demo stays fully functional when deployed.

Next Steps

Learn about mock authentication in the Authentication guide, or see how to add new pages that consume these API routes.