# How to Embed Related Resources in JSON Server Responses Using `_embed`

> Effortlessly embed related resources in JSON Server responses with the _embed query parameter. Enhance your API by including related data in a single GET request. Learn how to use _embed now.

- Repository: [typicode/json-server](https://github.com/typicode/json-server)
- Tags: how-to-guide
- Published: 2026-03-01

---

**Use the `_embed` query parameter to automatically include related records in JSON Server responses by appending `?_embed=relatedCollection` to any GET request.**

The `typicode/json-server` library generates a zero-configuration REST API that resolves relationships through strict naming conventions. By leveraging the **`_embed`** parameter, developers can enrich API responses with nested related data without writing custom middleware or database joins.

## How `_embed` Works

JSON Server implements embedding through a two-stage pipeline. First, the query parser extracts the parameter values from the request URL. Then, the service layer resolves the relationships and attaches the data.

In [`src/app.ts`](https://github.com/typicode/json-server/blob/main/src/app.ts), the `parseListParams` function (line 64) extracts the `_embed` values and forwards them to the data service. The `Service` class in [`src/service.ts`](https://github.com/typicode/json-server/blob/main/src/service.ts) receives these values through the `embed` option in both `find` (lines 28‑32) and `findById` (lines 96‑104) methods. The core enrichment logic resides in the `embed` helper (lines 23‑47), which determines relationship cardinality and attaches the related objects to the response payload.

## Relationship Conventions and Foreign Key Patterns

JSON Server relies on **convention over configuration** to resolve relationships automatically. The system expects strict naming conventions:

- **Plural collection names**: Resources must use plural forms (e.g., `posts`, `comments`, `users`).
- **Foreign key pattern**: Child records must store the parent identifier using the pattern `<parentSingular>Id`. For example, a comment belonging to a post stores `postId`.
- **Inflection logic**: The embedded `inflection` library handles singularization to determine if a relation is **one-to-many** (plural name like `comments`) or **many-to-one** (singular name like `post`).

When processing `_embed=comments`, the code calls `inflection.singularize('comments')` which returns `'comment'`. Since this differs from the input, JSON Server treats it as a one-to-many relationship. Conversely, `_embed=post` singularizes to `'post'`, matching the input and signaling a many-to-one lookup.

## Embedding Examples

### Embed One-to-Many Relationships

To fetch all posts with their associated comments, request the parent resource with the child collection name:

```http
GET /posts?_embed=comments HTTP/1.1
Host: localhost:3000

```

**Response:**

```json
[
  {
    "id": 1,
    "title": "Post 1",
    "author": "John",
    "comments": [
      { "id": 101, "postId": 1, "body": "Great post!" },
      { "id": 102, "postId": 1, "body": "Thanks for sharing." }
    ]
  }
]

```

According to the source code in [`src/service.ts`](https://github.com/typicode/json-server/blob/main/src/service.ts) (lines 35‑46), the service filters the `comments` collection for records where `postId` matches the parent `id`, then attaches the resulting array under the `comments` key.

### Embed Many-to-One Relationships

To fetch a specific comment and include its parent post:

```http
GET /comments/101?_embed=post HTTP/1.1
Host: localhost:3000

```

**Response:**

```json
{
  "id": 101,
  "postId": 1,
  "body": "Great post!",
  "post": { "id": 1, "title": "Post 1", "author": "John" }
}

```

As implemented in [`src/service.ts`](https://github.com/typicode/json-server/blob/main/src/service.ts) (lines 25‑34), the `embed` function detects the singular relation name, locates the foreign key `postId` on the child record, queries the `posts` collection, and attaches the single matching object.

### Embed Multiple Relations

Request multiple embedded resources by repeating the parameter or using comma-separated values:

```http
GET /posts?_embed=comments&_embed=author HTTP/1.1
Host: localhost:3000

```

JSON Server processes each relation independently, adding both `comments` and `author` fields to every post object.

### Combine with Filtering and Pagination

The embedding phase executes after filtering, sorting, and pagination. This ensures you only embed relations for the final result set:

```http
GET /posts?_embed=comments&_sort=title&_page=2&_per_page=5 HTTP/1.1
Host: localhost:3000

```

The service first applies the sort order and pagination in [`src/service.ts`](https://github.com/typicode/json-server/blob/main/src/service.ts) (lines 28‑32), then iterates the reduced result set to embed comments.

## Internal Implementation Details

The embedding algorithm distinguishes relationship types using the `inflection` library. In [`src/service.ts`](https://github.com/typicode/json-server/blob/main/src/service.ts) (line 24), the check `inflection.singularize(related) === related` determines the code path:

- **Many-to-one** (singular): Uses the foreign key `<related>Id` (e.g., `postId`) to locate a single parent record.
- **One-to-many** (plural): Uses the foreign key `<singularParent>Id` (e.g., `postId`) to filter child records where the foreign key matches the parent `id`.

This logic executes within the `embed` function (lines 23‑47), which is invoked synchronously during the `find` and `findById` operations before the response middleware serializes the result in [`src/app.ts`](https://github.com/typicode/json-server/blob/main/src/app.ts) (lines 55‑63).

## Summary

- Append **`?_embed=relationName`** to any GET request to nest related resources automatically.
- Follow the foreign key convention `<parentSingular>Id` (e.g., `postId`, `userId`) for automatic resolution.
- Use plural names for one-to-many relations (e.g., `_embed=comments`) and singular names for many-to-one (e.g., `_embed=post`).
- Embedding occurs after filtering, sorting, and pagination, ensuring optimal performance for large datasets.
- The implementation resides in [`src/service.ts`](https://github.com/typicode/json-server/blob/main/src/service.ts) (lines 23‑47) with query parsing handled in [`src/app.ts`](https://github.com/typicode/json-server/blob/main/src/app.ts) (line 64).

## Frequently Asked Questions

### What naming convention does JSON Server use for foreign keys?

JSON Server expects foreign keys to follow the pattern `<parentSingular>Id`. For example, a child comment must store its parent post identifier as `postId`. The system uses the `inflection` library to singularize collection names and resolve these relationships automatically in [`src/service.ts`](https://github.com/typicode/json-server/blob/main/src/service.ts).

### Can I embed multiple related resources in a single request?

Yes. Supply multiple `_embed` parameters as either repeated query strings (`?_embed=comments&_embed=author`) or comma-separated values (`?_embed=comments,author`). The parser in [`src/app.ts`](https://github.com/typicode/json-server/blob/main/src/app.ts) (line 64) collects all values into an array, and [`src/service.ts`](https://github.com/typicode/json-server/blob/main/src/service.ts) processes each relation independently.

### Does embedding work with pagination and sorting?

Yes. The `Service.find` method in [`src/service.ts`](https://github.com/typicode/json-server/blob/main/src/service.ts) (lines 28‑32) applies filtering, sorting, and pagination before invoking the `embed` helper. This ensures you only fetch and attach related data for the records actually returned in the current page.

### How does JSON Server determine one-to-many versus many-to-one relationships?

The code uses `inflection.singularize(related) === related` (line 24 in [`src/service.ts`](https://github.com/typicode/json-server/blob/main/src/service.ts)). If singularizing the requested relation name returns the same string (e.g., `post` → `post`), it treats the request as many-to-one and expects a single parent object. If singularization changes the string (e.g., `comments` → `comment`), it treats it as one-to-many and returns an array of child records.