<!-- Generated from https://trafficparrot.com/documentation/5.65.x/mockserver_users.html by scripts/generate-md-mirrors.sh. Do not edit: edit the .html and regenerate. -->

# Traffic Parrot for MockServer users

<a id="same-idea"></a>
## An expectation and a mapping are the same idea

[MockServer](https://www.mock-server.com/) and Traffic Parrot describe a mock the same way: a request matcher paired with a response, with a priority when several match, a state machine when the answer depends on what came before, a delay or a fault when the test needs one, and a journal afterwards to verify what the system under test sent. If you have written MockServer expectations, a Traffic Parrot [mapping](https://trafficparrot.com/documentation/5.65.x/request_matching.html#what-is-a-mapping) reads like one with the field names changed, and the [concept-mapping table](#concept-mapping) is that rename.

What differs is where the mock lives and who edits it. A MockServer expectation is an object the running server holds: a test or a client library puts it there over the API, an initializer file seeds the set at start, and the dashboard shows and edits it. A Traffic Parrot mapping is a file in the selected scenario's `mappings` directory, created in the [mapping editor](https://trafficparrot.com/documentation/5.65.x/http.html#add-edit-http-mappings), by [recording](https://trafficparrot.com/documentation/5.65.x/http.html#recording-http) real traffic, or through the [management API](https://trafficparrot.com/documentation/5.65.x/user_guide.html#management-apis), and kept in version control like any other file. The protocols the two reach also differ, in direction rather than in count; the next section is about when those differences start to matter.

The JSON does not carry over. A MockServer expectation is not a Traffic Parrot mapping and Traffic Parrot does not import one, so moving a mock is a translation, expectation by expectation. The [worked example](#worked-example) shows one done both ways. If your expectations were generated from an OpenAPI specification, the shortest route is to [import that specification into Traffic Parrot](https://trafficparrot.com/documentation/5.65.x/http.html#import-http-usage) and carry only your edits across.

<a id="why-traffic-parrot"></a>
## Why MockServer users move to Traffic Parrot

MockServer's scope is wide and deliberate: an expectation set up from code or from its dashboard, on one port that speaks HTTP, HTTP/2, gRPC, WebSockets and raw TCP, with proxying, chaos testing and contract tooling built in. A great many teams never need more. The teams that move are the ones that hit one of these:

- **The mock is owned by people who do not write code.** Both tools have a user interface; the unit it edits differs. MockServer's dashboard creates, edits and verifies expectations held by the running server. Traffic Parrot's web user interface covers the whole life of a mock as files: [record](https://trafficparrot.com/documentation/5.65.x/http.html#recording-http) real traffic into mapping files, [clean them up](https://trafficparrot.com/documentation/5.65.x/http.html#http-cleanup) into a flexible mock, edit the matcher, the response, the [delays](https://trafficparrot.com/documentation/5.65.x/http.html#fault-delay-delays) and [faults](https://trafficparrot.com/documentation/5.65.x/http.html#fault-delay-faults) in forms, group them into [scenarios](https://trafficparrot.com/documentation/5.65.x/user_guide.html#scenarios), and commit the directory. A tester or an analyst maintains that without a client library, and a developer who prefers JSON still has it.
- **The system under test speaks JMS, IBM® MQ, Thrift or files.** MockServer's protocols run towards the web and towards event brokers: HTTP/1.1, HTTPS, HTTP/2, gRPC and gRPC-Web, WebSockets, raw TCP, HTTP/3 as an experiment, JSON-RPC for MCP, and Kafka, MQTT and AMQP brokers driven from an AsyncAPI specification. Traffic Parrot's run towards enterprise integration: [JMS](https://trafficparrot.com/documentation/5.65.x/jms.html) (ActiveMQ, RabbitMQ, Azure AMQP 1.0 and IBM® WebSphere MQ over JMS), [native IBM® MQ](https://trafficparrot.com/documentation/5.65.x/ibmmq.html), [Thrift](https://trafficparrot.com/documentation/5.65.x/thrift.html) and [file-based messages](https://trafficparrot.com/documentation/5.65.x/filemessage.html), alongside [HTTP](https://trafficparrot.com/documentation/5.65.x/http.html), [SOAP](https://trafficparrot.com/documentation/5.65.x/http.html#soap), [gRPC](https://trafficparrot.com/documentation/5.65.x/grpc.html) and [WebSocket](https://trafficparrot.com/documentation/5.65.x/websocket.html), in one process with one configuration model. Neither list contains the other; see [Where each tool fits](#scope).
- **Recording that becomes a mock you keep, on the messaging side too.** MockServer records through its proxy and replays what it recorded, and subscribes to broker channels to record messages for verification. Traffic Parrot records [HTTP](https://trafficparrot.com/documentation/5.65.x/http.html#recording-http), [gRPC](https://trafficparrot.com/documentation/5.65.x/grpc.html#recording-grpc), [JMS queues and topics](https://trafficparrot.com/documentation/5.65.x/jms.html#recording-jms) and [native IBM® MQ](https://trafficparrot.com/documentation/5.65.x/ibmmq.html#recording-mq) straight into mapping files, then [cleanup](https://trafficparrot.com/documentation/5.65.x/http.html#http-cleanup) turns a literal recording into a mock with URL patterns, templated bodies and duplicates consolidated. See the [record and replay tutorial](https://trafficparrot.com/tutorials/record-replay-http-requests-and-responses-to-create-api-mocks.html).
- **Several teams on one server, each with its own set of mocks.** MockServer's guidance for a shared deployment is one instance with a session identifier in every expectation's matcher, so one run's expectations do not answer another's requests. Traffic Parrot gives each team or environment its own [scenario](https://trafficparrot.com/documentation/5.65.x/user_guide.html#scenarios), a directory of mappings switched in the user interface or over the API, or its own [virtual service](https://trafficparrot.com/documentation/5.65.x/virtual_services.html) on its own port, on one instance that developers, testers, demos, performance runs and CI agents use at the same time. Licensing is by [concurrent (floating) instances](https://blog.trafficparrot.com/2020/04/what-is-concurrent-floating-license.html).
- **Contract checks that cover messaging as well as HTTP.** Both tools generate mocks from OpenAPI. Traffic Parrot also [reports which operations your mocks cover](https://trafficparrot.com/documentation/5.65.x/http.html#http-coverage), checks mappings against the specification [at startup](https://trafficparrot.com/documentation/5.65.x/http.html#openapi-schema-check) and [from the command line in CI](https://trafficparrot.com/documentation/5.65.x/http.html#validate-cli), and the command-line check reads proto files for gRPC and [AsyncAPI specifications for JMS and IBM® MQ](https://trafficparrot.com/documentation/5.65.x/jms.html#validate-messaging) as well as OpenAPI for HTTP.

Traffic Parrot is a supported commercial product: there is a team behind it that answers questions, fixes defects and adds protocols. MockServer is Apache-2.0 licensed and free, which is the right trade for many teams; the rest of this page is for the ones whose needs have moved past what it covers.

<a id="scope"></a>
## Where each tool fits

|  | MockServer | Traffic Parrot |
| --- | --- | --- |
| Protocols | HTTP/1.1, HTTPS, HTTP/2, gRPC and gRPC-Web, WebSockets and raw TCP on one port; HTTP/3 as an experiment; JSON-RPC for MCP and A2A; Kafka, MQTT and AMQP brokers driven with example messages from an AsyncAPI specification, and recorded; SOAP expectations generated from a WSDL | [HTTP and HTTPS](https://trafficparrot.com/documentation/5.65.x/http.html) (HTTP/2 included), [WebSocket](https://trafficparrot.com/documentation/5.65.x/websocket.html), [SOAP](https://trafficparrot.com/documentation/5.65.x/http.html#soap), [gRPC](https://trafficparrot.com/documentation/5.65.x/grpc.html), [JMS](https://trafficparrot.com/documentation/5.65.x/jms.html), [native IBM® MQ](https://trafficparrot.com/documentation/5.65.x/ibmmq.html), [Thrift](https://trafficparrot.com/documentation/5.65.x/thrift.html) and [file-based messages](https://trafficparrot.com/documentation/5.65.x/filemessage.html), with [AsyncAPI import](https://trafficparrot.com/documentation/5.65.x/jms.html#import-asyncapi-jms) for the messaging protocols; no Kafka, MQTT or raw TCP |
| Runs as | Docker, Helm on Kubernetes, a JAR, a WAR or a Homebrew install; JUnit and Spring support and a Testcontainers module; clustered state for a multi-instance deployment | One standalone server shared by the team and its environments: [downloaded distribution](https://trafficparrot.com/documentation/5.65.x/start.html), [Docker image](https://trafficparrot.com/documentation/5.65.x/user_guide.html#running-docker), [Kubernetes](https://trafficparrot.com/documentation/5.65.x/user_guide.html#running-kubernetes) or [OpenShift](https://trafficparrot.com/documentation/5.65.x/user_guide.html#running-openshift) with a sample Helm chart, started from a build by the [Maven](https://trafficparrot.com/documentation/5.65.x/user_guide.html#maven-plugin) or [Gradle](https://trafficparrot.com/documentation/5.65.x/user_guide.html#gradle-plugin) plugin, or from a JUnit test with the [Testcontainers module](https://trafficparrot.com/documentation/5.65.x/testcontainers.html) |
| Where a mock is defined | An expectation in the running server: from a client library in Java, JavaScript, Python, Ruby, Go, .NET, Rust or PHP, the REST API, the dashboard, or an initializer JSON file loaded at start and, on request, written back to | The [web user interface](https://trafficparrot.com/documentation/5.65.x/http.html#add-edit-http-mappings), the [management API](https://trafficparrot.com/documentation/5.65.x/user_guide.html#management-apis), or a JSON file per mapping dropped into the scenario's `mappings` directory |
| Recording | Proxy modes (port forwarding, HTTP proxy, HTTPS tunnelling, SOCKS) that record and replay traffic; broker channels recorded for verification | [Recording](https://trafficparrot.com/documentation/5.65.x/http.html#recording-http) into mapping files for HTTP, gRPC, JMS and IBM® MQ, then [cleanup](https://trafficparrot.com/documentation/5.65.x/http.html#http-cleanup) into a flexible mock |
| Dynamic responses | Velocity, Mustache or JavaScript templates; callbacks to a Java class or back to the client; forwarding with overrides | [Handlebars templating](https://trafficparrot.com/documentation/5.65.x/dynamic.html) with helpers for the request, random data, CSV and database lookups, an object store and state, plus [external-process middleware](https://trafficparrot.com/documentation/5.65.x/dynamic.html#external-process-transformer) and [your own Java helpers and transformers](https://trafficparrot.com/documentation/5.65.x/dynamic.html#write-your-own) |
| Contract tooling | Expectations generated from OpenAPI or WSDL; a request matcher that names an OpenAPI operation; contract tests run against a live service; Pact import, export and verify; recorded traffic validated against a specification | [OpenAPI import](https://trafficparrot.com/documentation/5.65.x/http.html#import-http-usage), [export](https://trafficparrot.com/documentation/5.65.x/http.html#export-http-openapi), [coverage](https://trafficparrot.com/documentation/5.65.x/http.html#http-coverage), [a startup check](https://trafficparrot.com/documentation/5.65.x/http.html#openapi-schema-check) and [validation in CI](https://trafficparrot.com/documentation/5.65.x/http.html#validate-cli) for HTTP, gRPC and messaging; [Pact import](https://trafficparrot.com/documentation/5.65.x/http.html#import-http-pact) for HTTP and [message Pact import](https://trafficparrot.com/documentation/5.65.x/jms.html#import-message-pact-jms) for JMS and IBM® MQ |
| Access control | Mutual TLS, JWT or OpenID Connect on the control plane, with read, mutate and admin roles under OpenID Connect | [Login and roles](https://trafficparrot.com/documentation/5.65.x/user_guide.html#role-based-access) on the web user interface and its APIs: a role that views and a role that edits |
| Licence and support | Open source (Apache-2.0) | Commercial, with support; licensed by concurrent instances |

<a id="concept-mapping"></a>
## Mapping MockServer concepts onto Traffic Parrot

The MockServer column uses the field names of an expectation as the REST API and the initializer file take it, which is what you keep in version control whichever client wrote it. Every Traffic Parrot cell links to the page that documents it.

| MockServer | Traffic Parrot |
| --- | --- |
| An **expectation**: `httpRequest`, one action such as `httpResponse`, and `id`, `priority`, `times` and `timeToLive` around them | A [mapping](https://trafficparrot.com/documentation/5.65.x/request_matching.html#what-is-a-mapping): a `request` matcher, a `response`, a `priority`, one JSON file each in the selected [scenario](https://trafficparrot.com/documentation/5.65.x/user_guide.html#scenarios)'s `mappings` directory. The `times` and `timeToLive` fields have no counterpart: a mapping answers until it is [disabled](https://trafficparrot.com/documentation/5.65.x/http.html#add-edit-enable-disable) or deleted, and a one-shot answer is a [scenario state](https://trafficparrot.com/documentation/5.65.x/dynamic.html#built-in-transformers) that the first match moves on from. |
| `httpRequest`: `method`, `path` as a literal or a regular expression, `pathParameters` for the `{id}` segments, `queryStringParameters`, `headers`, `cookies`, and a `body` matched as a string, a regular expression, JSON, a JSON schema, JSONPath, XML or XPath | The [request matchers](https://trafficparrot.com/documentation/5.65.x/http.html#http-matchers) on the same parts of the request: the method, a URL matcher (an exact path, a [regular expression](https://trafficparrot.com/documentation/5.65.x/http.html#request-url-matchers), or a [path template](https://trafficparrot.com/documentation/5.65.x/request_matching.html#matchers-reference) whose `{id}` segments become named variables), query parameters, headers, cookies, and body patterns with `equalTo`, `matches`, `contains`, `equalToJson`, `matchesJsonPath`, `matchesJsonSchema`, `equalToXml` and `matchesXPath`, combined with [`and`, `or` and `not`](https://trafficparrot.com/documentation/5.65.x/request_matching.html#logical-operators). |
| `priority` on the expectation, where a higher number is matched first and creation order breaks a tie | [Priority](https://trafficparrot.com/documentation/5.65.x/http.html#add-edit-priority) on the mapping, where the number runs the other way: `1` is the highest and the default is `5`. A catch-all gets a higher number than the specific mappings. |
| `scenarioName`, `scenarioState` and `newScenarioState` on an expectation; every scenario starts in `Started` | [Stub-level scenario state](https://trafficparrot.com/documentation/5.65.x/dynamic.html#built-in-transformers) with the same shape: `scenarioName`, `requiredScenarioState` and `newScenarioState` on the mapping, starting in `Started`, and `POST /api/http/__admin/scenarios/reset` to put every one back. Traffic Parrot also uses the word scenario for a [directory of mappings](https://trafficparrot.com/documentation/5.65.x/user_guide.html#scenarios); the two are unrelated. |
| `httpResponse`: `statusCode`, `headers`, `cookies`, `body`, `delay` and `connectionOptions` | The mapping's `response`: `status`, `headers` and `body`, or `bodyFileName` for a body kept as a [file under `__files`](https://trafficparrot.com/documentation/5.65.x/http.html#file-backed-responses), binary files included, with [delays](https://trafficparrot.com/documentation/5.65.x/http.html#fault-delay-delays) that are fixed, uniform, log-normal or a chunked dribble. |
| `httpError` with `dropConnection` or raw `responseBytes`, and the chaos features around it | [Faults](https://trafficparrot.com/documentation/5.65.x/http.html#fault-delay-faults) on the mapping: a connection reset, an empty response, malformed or random data, among nine, set per mapping in the editor. |
| `httpResponseTemplate` or `httpForwardTemplate` with a `templateType` of `VELOCITY`, `MUSTACHE` or `JAVASCRIPT` | [Handlebars](https://trafficparrot.com/documentation/5.65.x/dynamic.html) in the response body: [request data](https://trafficparrot.com/documentation/5.65.x/dynamic.html#request-data-http) (`request.path`, `request.query`, `request.headers`, `request.body`), with [JSONPath](https://trafficparrot.com/documentation/5.65.x/dynamic.html#extract-jsonpath), [XPath](https://trafficparrot.com/documentation/5.65.x/dynamic.html#extract-xpath) and [regular-expression](https://trafficparrot.com/documentation/5.65.x/dynamic.html#extract-regex) helpers to pick a value out, [random values](https://trafficparrot.com/documentation/5.65.x/dynamic.html#random-values), [conditionals](https://trafficparrot.com/documentation/5.65.x/dynamic.html#conditionals) and [loops](https://trafficparrot.com/documentation/5.65.x/dynamic.html#loops-iterators). For a match that no matcher expresses, a [request matcher script](https://trafficparrot.com/documentation/5.65.x/http.html#add-edit-request-matcher-script) on the mapping. |
| `httpResponseClassCallback` or `httpForwardClassCallback` to a Java class on the classpath, and `httpResponseObjectCallback` or `httpForwardObjectCallback` back to the client that created the expectation | A [custom response transformer](https://trafficparrot.com/documentation/5.65.x/dynamic.html#custom-http-response-transformers) in Java, dropped into `lib/external`, or the [external-process middleware](https://trafficparrot.com/documentation/5.65.x/dynamic.html#external-process-transformer), which hands the request and response to a program in any language. A call to another system after the response is a [webhook](https://trafficparrot.com/documentation/5.65.x/http.html#add-edit-webhook) on the mapping. |
| `httpForward` and `httpOverrideForwardedRequest`, and the proxy modes | A [proxy response](https://trafficparrot.com/documentation/5.65.x/http.html#add-edit-proxy) on one mapping, or the [passthrough proxy](https://trafficparrot.com/documentation/5.65.x/http.html#passthrough-proxy) for a whole virtual service. When the forwarded traffic should become mappings, use [recording](https://trafficparrot.com/documentation/5.65.x/http.html#recording-http) instead; an [HTTPS recording proxy](https://trafficparrot.com/documentation/5.65.x/user_guide.html#recording-https-proxy) covers the system under test's outbound calls. |
| An `openAPIExpectation` with `specUrlOrPayload` and `operationsAndResponses`, and an `httpRequest` that names an `operationId` | [OpenAPI import](https://trafficparrot.com/documentation/5.65.x/http.html#import-http-usage), which generates a mapping per operation and lets you [choose the response by status code](https://trafficparrot.com/documentation/5.65.x/http.html#import-http-matching-response-code). The generated mappings match on method and URL rather than by operation id; the [startup check](https://trafficparrot.com/documentation/5.65.x/http.html#openapi-schema-check) and the [validate command](https://trafficparrot.com/documentation/5.65.x/http.html#validate-cli) keep them in step with the specification, and [coverage](https://trafficparrot.com/documentation/5.65.x/http.html#http-coverage) reports the operations your mocks and your traffic reach. |
| Verification: `PUT /mockserver/verify` with a matcher and `times` (`atLeast`, `atMost`), `verifySequence`, and `retrieve` for recorded requests | The [request journal](https://trafficparrot.com/documentation/5.65.x/http.html#verifying-requests) over the management API: `POST /api/http/requests/count` and `/find` take a request pattern, `GET /api/http/requests` lists the journal in order for a sequence check, `/unmatched` and [`/unmatched/near-misses`](https://trafficparrot.com/documentation/5.65.x/http.html#verifying-requests-near-misses) say what arrived that nothing answered. The [endpoint reference](https://trafficparrot.com/documentation/5.65.x/http.html#verifying-requests-reference) lists them all. |
| `PUT /mockserver/clear` and `PUT /mockserver/reset` | [Four resets](https://trafficparrot.com/documentation/5.65.x/user_guide.html#junit-spring-tests-reset), because the state lives in four places: `DELETE /api/http/requests` clears the journal, `POST /api/http/__admin/scenarios/reset` the scenario states, `DELETE /api/state` the key-value state, and `POST /api/http/__admin/mappings/reset` the mappings added over the API without `"persistent": true`, which are held in memory; the mapping files stay and are reloaded. A mapping added with the flag is a file, so a test that added one deletes it by id rather than resetting them all. |
| An initializer file (`initializationJsonPath`, watched with `watchInitializationJson`) and `persistExpectations` back to a file | The `mappings` directory itself: every file in it is loaded at start, edits in the user interface and over the API are written back to it, and a file dropped in is picked up. Several sets become several [scenarios](https://trafficparrot.com/documentation/5.65.x/user_guide.html#scenarios), or [further virtual services](https://trafficparrot.com/documentation/5.65.x/virtual_services.html#manage-add) when each needs its own port. |
| The dashboard at `/mockserver/dashboard`: live requests, logs and active expectations, editing, clearing and verifying | The web user interface: the [mapping list and editor](https://trafficparrot.com/documentation/5.65.x/http.html#add-edit-http-mappings), the [request log](https://trafficparrot.com/documentation/5.65.x/http.html#request-log) whose unmatched entries name the [closest mapping and the field that did not match](https://trafficparrot.com/documentation/5.65.x/http.html#request-log-near-misses), and [live coverage](https://trafficparrot.com/documentation/5.65.x/http.html#recording-live-coverage) while recording. |
| The client libraries, the JUnit extension and the Testcontainers module | The [management API](https://trafficparrot.com/documentation/5.65.x/user_guide.html#management-apis), documented as an [OpenAPI specification](https://trafficparrot.com/documentation/5.65.x/openapi/index.html) for whichever client you generate; [Traffic Parrot in JUnit and Spring Boot tests](https://trafficparrot.com/documentation/5.65.x/user_guide.html#junit-spring-tests); the [Testcontainers module](https://trafficparrot.com/documentation/5.65.x/testcontainers.html); the [Maven](https://trafficparrot.com/documentation/5.65.x/user_guide.html#maven-plugin) and [Gradle](https://trafficparrot.com/documentation/5.65.x/user_guide.html#gradle-plugin) plugins. |
| Control-plane authentication: mutual TLS, JWT or OpenID Connect, with `read`, `mutate` and `admin` roles | [Login and roles](https://trafficparrot.com/documentation/5.65.x/user_guide.html#role-based-access) on the web user interface and its APIs: one role views, one edits. HTTPS on the virtual service ports with your own [certificates](https://trafficparrot.com/documentation/5.65.x/user_guide.html#https-certificates). |
| A shared, centralised deployment with a session identifier in every matcher, and clustered state | One shared instance with a [scenario](https://trafficparrot.com/documentation/5.65.x/user_guide.html#scenarios) or a [virtual service](https://trafficparrot.com/documentation/5.65.x/virtual_services.html) per team or environment, its mapping directories in version control; no matcher needs to carry a run id, because the sets are separate. |
| The CRUD entity store | The [object store](https://trafficparrot.com/documentation/5.65.x/dynamic.html#object-store) for records a request creates and later requests read back, and the [data source](https://trafficparrot.com/documentation/5.65.x/dynamic.html#data-source) and [CSV](https://trafficparrot.com/documentation/5.65.x/dynamic.html#csv) helpers for lookups keyed by a request value. |
| gRPC and gRPC-Web expectations | [gRPC mappings](https://trafficparrot.com/documentation/5.65.x/grpc.html) from your proto files or [server reflection](https://trafficparrot.com/documentation/5.65.x/grpc.html#configure-reflection), unary and [streaming](https://trafficparrot.com/documentation/5.65.x/grpc.html#streaming-modes), with [recording](https://trafficparrot.com/documentation/5.65.x/grpc.html#recording-grpc). |
| WebSocket expectations | [WebSocket mappings](https://trafficparrot.com/documentation/5.65.x/websocket.html#websocket-mappings): a mapping fires on a message matched by its body, or on connect for a server push. |
| Kafka, MQTT and AMQP brokers driven and recorded from an AsyncAPI specification | No Kafka or MQTT. The messaging virtual services are [JMS](https://trafficparrot.com/documentation/5.65.x/jms.html) (ActiveMQ, RabbitMQ, Azure AMQP 1.0, IBM® MQ over JMS) and [native IBM® MQ](https://trafficparrot.com/documentation/5.65.x/ibmmq.html), request-reply and publish-subscribe, with [AsyncAPI import](https://trafficparrot.com/documentation/5.65.x/jms.html#import-asyncapi-jms) and [recording](https://trafficparrot.com/documentation/5.65.x/jms.html#recording-jms) of a real broker's traffic. |
| SOAP expectations generated from a WSDL | [SOAP over HTTP](https://trafficparrot.com/documentation/5.65.x/http.html#soap) mappings, matched with the XML and XPath matchers and recorded like any HTTP traffic; no WSDL import. |
| Mocked chat-completion APIs, and the built-in MCP server that lets an AI coding assistant drive MockServer | A chat-completion endpoint is an HTTP mapping like any other, with no provider-specific templates. Traffic Parrot serves its own [MCP endpoint](https://trafficparrot.com/documentation/5.65.x/mcp.html), so an assistant reads and changes the mappings, requests and scenarios of a running instance; see [Generate mocks with an AI agent](https://trafficparrot.com/documentation/5.65.x/generate-mocks-with-ai-agent.html). |
| Mocked OAuth2, OpenID Connect, SAML and SCIM providers | Plain HTTP mappings: the [JWT bearer token tutorial](https://trafficparrot.com/tutorials/mock-jwt-bearer-token-authentication.html) builds a token endpoint that signs real tokens, a guarded API and a JWKS endpoint. |

<a id="worked-example"></a>
## One expectation, both ways

A customer lookup as two MockServer expectations, in the JSON that `PUT /mockserver/expectation` and the initializer file take. The first answers `GET /customers/123`; the second is the catch-all, a regular-expression path that answers everything else under `/customers/` with a 404. The specific one carries the higher priority so that it wins when both match:

```json
{
  "httpRequest": { "method": "GET", "path": "/customers/123" },
  "httpResponse": {
    "statusCode": 200,
    "headers": { "Content-Type": ["application/json"] },
    "body": { "id": 123, "name": "Example customer" }
  },
  "priority": 10
}
```

```json
{
  "httpRequest": { "method": "GET", "path": "/customers/.*" },
  "httpResponse": {
    "statusCode": 404,
    "headers": { "Content-Type": ["application/json"] },
    "body": { "error": "not found" }
  }
}
```

In Traffic Parrot each becomes a mapping. The specific mapping matches the exact path; the catch-all matches a path template at a lower priority, which in Traffic Parrot's numbering is the higher number, so it answers only when the specific one does not:

```json
{
  "name": "customers: GET /customers/123",
  "request": { "method": "GET", "urlPath": "/customers/123" },
  "response": {
    "status": 200,
    "headers": { "Content-Type": "application/json" },
    "body": "{\"id\": 123, \"name\": \"Example customer\"}"
  }
}
```

```json
{
  "name": "customers: GET /customers/{id} not found",
  "priority": 10,
  "request": { "method": "GET", "urlPathTemplate": "/customers/{id}" },
  "response": {
    "status": 404,
    "headers": { "Content-Type": "application/json" },
    "body": "{\"error\": \"not found\"}"
  }
}
```

Three things changed in the translation. The body is a string holding JSON rather than a JSON object, and the header value is a string rather than a list. The priority number runs the other way. And the regular-expression path became a [path template](https://trafficparrot.com/documentation/5.65.x/request_matching.html#matchers-reference), which is the documented way to say "any id" and gives the template `{{request.path.id}}` to read it back; `urlPathPattern` with the same regular expression would also work.

Save each as a file in the selected scenario's `mappings` directory, paste it into the [Add/Edit mapping](https://trafficparrot.com/documentation/5.65.x/http.html#add-edit-http-mappings) form, or push it through the management port with `POST /api/http/__admin/mappings` (a mapping pushed that way is held in memory unless its JSON carries `"persistent": true`). Then call the virtual service port and compare with what MockServer answered:

```bash
curl -i http://localhost:8081/customers/123
curl -i http://localhost:8081/customers/999
```

Where the MockServer response was an `httpResponseTemplate`, for example the id echoed into the body, the Traffic Parrot body reads the same value from the request: one mapping on the path template with `{{request.path.id}}` in the body replaces both of the above when the id is only echoed rather than looked up. The [request data](https://trafficparrot.com/documentation/5.65.x/dynamic.html#request-data-http) section lists the other fields.

<a id="where-to-next"></a>
## Where to go next

- **Request matching**: the matchers your `httpRequest` fields become, on [Request Matching](https://trafficparrot.com/documentation/5.65.x/request_matching.html) and the [HTTP matchers reference](https://trafficparrot.com/documentation/5.65.x/http.html#http-matchers).
- **Dynamic responses**: the helpers that replace templates and callbacks, on the [Dynamic Responses](https://trafficparrot.com/documentation/5.65.x/dynamic.html) page, and the [stateful API mocking tutorial](https://trafficparrot.com/tutorials/stateful-api-mocking-with-scenarios.html) for scenario state.
- **Verifying requests**: the journal endpoints that replace `verify`, on [Verifying requests](https://trafficparrot.com/documentation/5.65.x/http.html#verifying-requests), and the [near misses tutorial](https://trafficparrot.com/tutorials/debug-unmatched-requests-with-near-misses.html).
- **Recording and cleanup**: the [record and replay tutorial](https://trafficparrot.com/tutorials/record-replay-http-requests-and-responses-to-create-api-mocks.html) and [How to clean up recorded HTTP mappings](https://trafficparrot.com/tutorials/clean-up-recorded-http-mappings.html).
- **Starting it from a test or a build**: [Traffic Parrot in JUnit and Spring Boot tests](https://trafficparrot.com/documentation/5.65.x/user_guide.html#junit-spring-tests), the [Testcontainers module](https://trafficparrot.com/documentation/5.65.x/testcontainers.html) and the [Maven plugin](https://trafficparrot.com/documentation/5.65.x/user_guide.html#maven-plugin).
- **Messaging**: the [JMS](https://trafficparrot.com/documentation/5.65.x/jms.html) and [native IBM® MQ](https://trafficparrot.com/documentation/5.65.x/ibmmq.html) pages, and the [ActiveMQ queues tutorial](https://trafficparrot.com/tutorials/mock-activemq-jms-queues.html).

Still weighing up the wider field rather than moving a specific MockServer setup? This page stays a migration reference. For a comparison across tools, protocols, deployment and licensing, read [Best Service Virtualization Tools](https://trafficparrot.com/articles/best-service-virtualization-tools.html); for the same exercise from the WireMock, Mountebank or Mockoon side, read [Traffic Parrot for WireMock users](https://trafficparrot.com/documentation/5.65.x/wiremock_users.html), [Traffic Parrot for Mountebank users](https://trafficparrot.com/documentation/5.65.x/mountebank_users.html) and [Traffic Parrot for Mockoon users](https://trafficparrot.com/documentation/5.65.x/mockoon_users.html).
