Skip to documentation

Guide · REST

Available

Model the contract and the behavior

A useful REST mock does more than return a sample object. Define the request contract, reuse response models, represent failure branches, and connect related calls with persistent state.

In this guide

  • Create contract-shaped endpoints
  • Return typed dynamic JSON
  • Keep not-found and validation branches explicit
  • Test state, faults, hooks, and traffic end to end

Prerequisites

  • A DotMock workspace you can access
  • The API ID in $API_ID and its published runtime URL in $MOCK_URL when the example calls the mock
On this page

Start with method, path, and intent

Each operation has an HTTP method, a path with optional parameters, a short summary, and a default response. Use resource-oriented paths such as /users and /users/{userId}; the tester turns braces into editable path-parameter fields.

text
POST /users
GET  /users/{userId}
PATCH /users/{userId}

Reuse models instead of copying shapes

Define application/json request bodies and response schemas from reusable models. A create request can omit server-generated fields while the 201 response references the complete User model. Reuse that same response model on GET and PATCH.

  • Request schema — what the client may or must send
  • Response model — the stable object returned on success
  • Error model — a shared envelope only when the real API uses one
  • Examples — realistic tester input, not a substitute for validation

Keep dynamic responses typed

Use request helpers for focused values and exact state helpers for complete JSON. Exact helper expressions preserve native types; surrounding text deliberately stringifies the result.

Focused request values
{
  "id": "{{param \"userId\"}}",
  "plan": "{{header \"x-plan\"}}",
  "email": "{{body \"profile.email\"}}"
}

Complete stored object
{{state.get "users-by-id" "$param.userId" "" null}}

Put failure cases beside success

Conditional responses use the regular expression language. A missing stored user, an invalid plan, or a rate-limit counter is a condition—not a special response mode. Give each branch its own status, headers, body, and optional schema.

Missing user
!state.exists("users-by-id", params["userId"])

Validation branch
body.total <= 0 || !("x-customer-id" in header)

Add state, faults, and hooks intentionally

State actions run before or after rendering, while exact inline mutations can both write and return a value. Faults model delay, disconnect, malformed output, or an upstream failure. Response hooks can trigger a configured webhook event after the response.

Prove both the response and the side effects

Use the tester with realistic path parameters, query pairs, headers, and a generated JSON body. Run safely first, inspect the winner and state diff, then send a live request and confirm the persisted value or delivery record.

DotMock REST endpoint workspace with POST, GET, and PATCH users operations
One workspace keeps endpoints, models, state, testing, and authoring tools in the same context.