26. Pattern: Master Detail

The Master Detail pattern allows clients to efficiently navigate heavy time-series or hierarchical datasets by first querying lightweight summary data for a given date (the “Master” view) and subsequently retrieving high-resolution, intra-day data on demand (the “Detail” view).

Rather than overwhelming the client with massive payloads of granular data that the user may never look at, this pattern enforces a two-step retrieval process. It provides immediate high-level visibility while keeping network traffic, database query times, and memory consumption strictly proportional to user interaction.

26.1. Overview

Dashboards, financial applications, and IoT monitoring systems frequently display historical data over time. When a user looks at a specific date (e.g., September 25, 2026), they typically need an aggregate summary first (total sales, average temperature, end-of-day balance). Only when they select that date do they need the granular intra-day metrics (minute-by-minute temperature fluctuations or individual transactions).

Without a Master Detail separation, APIs often dump thousands of granular records into a single response, leading to sluggish rendering, excessive bandwidth usage, and timeouts.

The Master Detail pattern solves this by dividing the responsibility:

  • The Master endpoint (/sales/daily-summary?date=2026-09-25) returns pre-aggregated, low-resolution data spanning the requested period.
  • The Detail endpoint (/sales/2026-09-25/transactions or /sales?date=2026-09-25&resolution=minute) returns the high-resolution intra-day data explicitly requested by the client.

This design naturally complements the concepts established in Pattern 25: Filter Collection by Identifier. While that pattern resolves the N+1 HTTP Request Problem by fetching specific batches of known IDs, this pattern prevents payload bloat by deferring the fetch of unknown, voluminous child records until they are explicitly needed.

26.2. When to Use Master Detail

Use the Master Detail pattern when:

  • Exposing high-frequency time-series data.
    • e.g., Fetching daily server CPU load averages, then drilling down into 5-minute intervals for a specific day.
  • Handling financial ledgers or transactional logs.
    • e.g., Displaying a monthly calendar view of total daily spend, then fetching individual transactions when a user clicks a specific date.
  • Supporting user interfaces with progressive disclosure.
    • UI paradigms that show summary charts or lists first and require a user action (click/tap) to expand the detailed view.
  • Payloads for full detail exceed acceptable performance thresholds.
    • If returning the detailed intra-day data pushes the JSON response size into the megabytes, the data must be split into Master and Detail endpoints.

26.3. When NOT to Use Master Detail

Avoid the Master Detail pattern when:

  • The dataset is universally small.
    • If the detail records for a given date are limited (e.g., maximum 5-10 lightweight records), standard collection fetching is sufficient. Forcing a second network request for trivial amounts of data degrades the user experience.
  • Clients require full offline access or bulk processing.
    • If the API consumer is an analytical engine or a mobile client designed for offline mode that requires the entire dataset up-front, a bulk export or firehose endpoint is more appropriate.

26.4. What the Pattern Looks Like

Below are HTTP request and response flows demonstrating the progressive retrieval of summary data followed by intra-day details.

1. The Master Request (Summary)

The client requests a high-level summary of a specific date (or date range).

Request

GET /metrics/daily-summary?date=2026-09-25 HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOi...

Response

The server returns lightweight aggregated totals for the requested date.

HTTP/1.1 200 OK
Cache-Control: public, max-age=3600
Content-Type: application/json

{
  "date": "2026-09-25",
  "totalTransactions": 142,
  "totalRevenue": 4550.75,
  "status": "closed",
  "links": {
    "detail": "/metrics/2026-09-25/intra-day"
  }
}

2. The Detail Request (Intra-day)

After reviewing the summary, the user clicks on the date to view the breakdown. The client follows the detail link to fetch the granular data.

Request

GET /metrics/2026-09-25/intra-day?limit=50 HTTP/1.1
Host: api.example.com

Response

The server returns a paginated list of granular intra-day events.

HTTP/1.1 200 OK
Content-Type: application/json

{
  "date": "2026-09-25",
  "items": [
    {
      "id": "txn_8821",
      "timestamp": "2026-09-25T08:15:30Z",
      "amount": 120.00,
      "category": "hardware"
    },
    {
      "id": "txn_8822",
      "timestamp": "2026-09-25T09:42:12Z",
      "amount": 45.50,
      "category": "software"
    }
  ],
  "pagination": {
    "next_cursor": "e30="
  }
}

26.5. Anti-Patterns to Avoid

  • Including the detail array by default (Payload Bloat)
    • Returning massive nested arrays of detailed logs inside the summary object simply because the client might need them. This exhausts server memory and drastically slows down client parsing.
  • Forcing N+1 calls to construct the Master view
    • Making the client request all intra-day details just to sum them up on the client side. The server must provide a dedicated Master endpoint with pre-calculated aggregations.
  • Inconsistent query parameters between Master and Detail
    • If the Master view supports timezone offsets or currency conversions (e.g., ?tz=America/Denver), the Detail endpoint must accept and respect those exact same parameters to ensure data consistency.

26.6. OpenAPI Example

A complete OpenAPI 3.0.3 specification illustrating the separation of Master (Summary) and Detail (Intra-day) endpoints.

openapi: 3.0.3
info:
  title: Metrics API - Master Detail Example
  version: 1.0.0
servers:
  - url: https://api.example.com

paths:
  /metrics/daily-summary:
    get:
      summary: Retrieve daily summary (Master)
      description: Returns pre-aggregated daily metrics for a given date.
      tags: [Metrics]
      parameters:
        - in: query
          name: date
          required: true
          schema:
            type: string
            format: date
            example: "2026-09-25"
      responses:
        '200':
          description: Master summary data
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DailySummary'

  /metrics/{date}/intra-day:
    get:
      summary: Retrieve intra-day details (Detail)
      description: Returns granular, high-resolution transaction logs for a specific date.
      tags: [Metrics]
      parameters:
        - in: path
          name: date
          required: true
          schema:
            type: string
            format: date
            example: "2026-09-25"
      responses:
        '200':
          description: Granular detail records
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntraDayDetail'

components:
  schemas:
    DailySummary:
      type: object
      properties:
        date:
          type: string
          format: date
          example: "2026-09-25"
        totalTransactions:
          type: integer
          example: 142
        totalRevenue:
          type: number
          format: float
          example: 4550.75
        links:
          type: object
          properties:
            detail:
              type: string
              example: "/metrics/2026-09-25/intra-day"
              
    IntraDayDetail:
      type: object
      properties:
        date:
          type: string
          format: date
        items:
          type: array
          items:
            $ref: '#/components/schemas/Transaction'

    Transaction:
      type: object
      properties:
        id:
          type: string
          example: "txn_8821"
        timestamp:
          type: string
          format: date-time
          example: "2026-09-25T08:15:30Z"
        amount:
          type: number
          format: float
          example: 120.00

26.7. Visualizing Master Detail (Mermaid Diagram)

sequenceDiagram
    autonumber
    actor User as Client Application
    participant API as API Server
    participant DB as Database (Aggregations)
    participant TSDB as Time-Series DB (Granular)

    Note over User,TSDB: Phase 1: Retrieve Master Summary
    User->>API: GET /metrics/daily-summary?date=2026-09-25
    API->>DB: SELECT SUM(amount), COUNT(id) FROM metrics WHERE date='2026-09-25'
    DB-->>API: { totalTransactions: 142, totalRevenue: 4550.75 }
    API-->>User: 200 OK (Lightweight Summary)

    Note over User: User reviews summary, clicks to view daily breakdown
    
    Note over User,TSDB: Phase 2: Retrieve Intra-Day Detail On-Demand
    User->>API: GET /metrics/2026-09-25/intra-day
    API->>TSDB: SELECT * FROM transactions WHERE date='2026-09-25' ORDER BY time
    TSDB-->>API: List of 142 granular records
    API-->>User: 200 OK (Heavy Detail Payload)