One open format
for all your API mocks
OpenMock is an open format and data model for describing how a mock API should respond. Routes, request matching, response bodies, delays, and templated values live in a single, portable, human- and AI-friendly file. No split metadata, no external dispatcher. Just the mock.
openmock: 0.2.0
info:
title: Users API mock
servers:
- name: users-api
type: http
operations:
- method: GET
path: /users/{id}
scenarios:
# Specific case first: an admin request.
- name: admin-user
when:
headers:
X-Role: admin
response:
status: 200
body:
id: "{{params.id}}"
name: "{{faker.person.fullName}}"
role: admin
# Default fallback (no `when`): always matches, goes last.
- name: default-user
response:
status: 200
delay: 200 # latency in ms
body:
id: "{{params.id}}"
name: "{{faker.person.fullName}}"
role: user
Four steps, and that's it
An implementation resolves every request the same way. No dispatchers, no scripting. The rules live right next to the response.
Route
The request names its server, then method + path select the operation, capturing path params like id.
Select
Scenarios are tried top-to-bottom. The first whose when matches wins; a when-less default catches the rest.
Render
{{params.*}} and {{faker.*}} placeholders are substituted into the native response body.
Respond
Answer with the status, headers, and body after any declared delay. First match wins, every time.
Example-driven mocks, made smaller and standalone
The good idea, example-driven mocks in one open format, with the ceremony removed. One file, inline matching, and a clear JSON Schema humans and AI agents can both read and write.
One file
A whole mock environment lives in a single openmock.yml. Two HTTP services, a gRPC backend, and a WebSocket feed coexist because every request addresses a server by name.
Native bodies
Response payloads are real structured data, never escaped JSON-in-a-string. What you write is what the client receives.
One model, many protocols
HTTP, gRPC, GraphQL, and WebSocket servers share the same scenario / when / response shape. Learn it once.
Explicit, in-file matching
Requests are matched by rules written right next to the response. First match wins, with a plain default fallback. No external dispatcher concept.
Stateful without scripting
A per-operation call counter mocks polling flows (upload → pending → done) with plain data. No code, no side effects.
Transport-agnostic & self-contained
OpenMock describes mocks, not running processes. How a server maps to a port stays an implementation concern. It depends on no other spec or format.
Mock the whole stack
v0.2 covers HTTP/REST, gRPC, GraphQL, and WebSocket. Each one reuses the same scenario model rather than forking it.
REST routes with path params, header & query matching, status codes, and inline latency.
Unary and server-streaming calls, decoded via the server's descriptorSet.
Queries and mutations over HTTP, with optional schema-powered introspection.
Client-initiated request/reply exchanges with per-connection call counters.
Write a mock. Serve it. Done.
Describe your servers, operations, and scenarios in one openmock.yml, then serve it with the Go reference implementation.
- Stateful polling: the
callsfacet keeps a counter per operation and concrete path, soupload → pending → doneis plain data. - Templating & faker:
{{params.hash}},{{request.body.x}}, and{{faker.*}}fill responses dynamically. - Marked synthetic fallbacks: unrouted 404 or unmatched 501, each carrying an
openmockmarker so it's never mistaken for an authored mock.
openmock: 0.2.0
servers:
- name: main
type: http
operations:
- method: GET
path: /v1/file/{hash}
scenarios:
- name: analyzing
when:
calls: { min: 2, max: 3 }
response:
status: 200
body:
hash: "{{params.hash}}"
status: pending
# 4th call onward → the default scenario
- name: done
response:
status: 200
body:
hash: "{{params.hash}}"
status: done
verdict: clean
Deliberately smaller
Existing API tooling makes simple, portable mocking harder than it should be. OpenMock takes the good idea and removes the ceremony.
| Capability | OpenMock | OpenAPI examples | WireMock | Microcks |
|---|---|---|---|---|
| Single portable file | Yes | Scattered | Stub format | Split files |
| Request-conditional responses | Inline when |
Not designed for it | Yes | External dispatcher |
| Native (unescaped) bodies | Native | Yes | JSON stubs | Yes |
| Runtime-independent | Spec-first | Yes | Ties to JVM | Ties to server |
| Multi-protocol, one model | HTTP · gRPC · GraphQL · WS | HTTP only | Mostly HTTP | Several |
A canonical, corpus-validated engine
OpenMock is first a specification. The tooling proves it's implementable. openmock-go is the canonical engine: a pure parse → match → render core that passes every conformance case across all four protocols.
# Serve a mock document over HTTP, gRPC, GraphQL & WebSocket $ openmock serve mocks.yml serving "main" on http://127.0.0.1:3000 admin API on http://127.0.0.1:4400 $ curl -s localhost:3000/health {"status":"ok"} $ curl -s localhost:4400/servers # resolved topology
Engine-first, CLI-second
The engine package is pure (no I/O, no server assumption), importable standalone by an embedding host. The server package adds the protocol adapters and the admin/discovery API. openmock serve runs it from the command line.
- Go engine (canonical): validated against every conformance case.
- All four protocol servers: HTTP, gRPC, GraphQL, WebSocket.
- TypeScript port: planned, provably equivalent via the shared corpus.
Describe a mock once. Run it anywhere.
Read the spec, browse the examples, and write your first openmock.yml in minutes.