apimock-rs 4.6.9 → 4.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +186 -39
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -9,13 +9,54 @@
9
9
  [![Releases Workflow](https://github.com/apimokka/apimock-rs/actions/workflows/release-executable.yaml/badge.svg)](https://github.com/apimokka/apimock-rs/actions/workflows/release-executable.yaml)
10
10
  [![App Docs Workflow](https://github.com/apimokka/apimock-rs/actions/workflows/docs.yaml/badge.svg)](https://github.com/apimokka/apimock-rs/actions/workflows/docs.yaml)
11
11
 
12
- Build a working REST API in seconds — without a backend.
12
+ ![logo](docs/src/assets/logo.png)
13
13
 
14
+ Build a working REST API in seconds — without a backend.
14
15
  Frontend blocked by an unfinished backend ?
15
- Need stable API responses for UI tests or offline development ?
16
-
16
+ Need stable API responses for UI tests or offline development ?
17
17
  Drop JSON files into a folder and your API immediately exists.
18
18
 
19
+ ## Mock APIs easily 🎈 — just JSON and go
20
+
21
+ If you’re building or testing APIs, this tool makes mocking painless. It’s super fast, efficient, and flexible when you need it to be.
22
+ All you have to do to start up is just use folders and JSON without any config set.
23
+
24
+ - ❄️ Zero-config start.
25
+ - 🌬️ Fast to boot, light on memory.
26
+ - 🪄 File-based and rule-based matching. Scripting supported.
27
+
28
+ ### Why `apimock-rs` ?
29
+
30
+ - The backend is not ready yet.
31
+ - You need stable API responses for UI testing.
32
+ - You want offline development.
33
+ - CI tests require a predictable API.
34
+ - Your mock data is becoming large.
35
+
36
+ ### Handles real project scale
37
+
38
+ As your project grows, your mock API grows, too. Large mock datasets often cause problems:
39
+
40
+ - Slow startup
41
+ - High memory usage
42
+ - Crashes during UI testing
43
+ - Unstable CI runs
44
+
45
+ apimock-rs does not preload responses. Each response file is read only when a request arrives using non-blocking I/O. This keeps:
46
+
47
+ - Startup nearly instant
48
+ - Memory usage minimal
49
+ - Stable behavior under repeated requests
50
+
51
+ as validated with k6 load testing.
52
+ You can run UI development and automated tests continuously without worrying about server instability.
53
+
54
+ ### 📖 Documentation
55
+
56
+ For more details, **🧭 check out [the docs](https://apimokka.github.io/apimock-rs/)**.
57
+
58
+ ---
59
+
19
60
  ## Quick start
20
61
 
21
62
  Easy to start with [npm package](https://www.npmjs.com/package/apimock-rs).
@@ -42,14 +83,6 @@ You may also check it out with browser to visit http://localhost:3001/api/v1/hel
42
83
 
43
84
  You now have a running REST endpoint.
44
85
 
45
- ### Customization
46
-
47
- Also, there's room to tweak things later with optional config file(s):
48
-
49
- ```sh
50
- npx apimock --init
51
- ```
52
-
53
86
  ### Vite project integration
54
87
 
55
88
  An example of **scripts** section in **package.json** is as below.
@@ -84,53 +117,167 @@ npm run dev
84
117
  | `npx apimock -d tests/apimock-dyn-route` | Run with custom root dir on server response. |
85
118
  | `npx apimock -c apimock.toml` | Run with config file giving rich features. Running `npx apimock --init` beforehand is required. |
86
119
 
87
- ## Mock APIs easily 🎈 — just JSON and go
120
+ ---
88
121
 
89
- If you’re building or testing APIs, this tool makes mocking painless. It’s super fast, efficient, and flexible when you need it to be.
90
- All you have to do to start up is just use folders and JSON without any config set.
122
+ ## Configuration reference
91
123
 
92
- - ❄️ Zero-config start.
93
- - 🌬️ Fast to boot, light on memory.
94
- - 🪄 File-based and rule-based matching. Scripting supported.
124
+ Everything below describes the TOML config files. Run `npx apimock --init` (or
125
+ `apimock --init`) once to scaffold `apimock.toml` and `apimock-rule-set.toml`
126
+ into the current directory, then tweak to taste.
95
127
 
96
- ### When to use `apimock-rs` ?
128
+ ### `apimock.toml` — top-level file
97
129
 
98
- - The backend is not ready yet.
99
- - You need stable API responses for UI testing.
100
- - You want offline development.
101
- - CI tests require a predictable API.
102
- - Your mock data is becoming large.
130
+ ```toml
131
+ [listener]
132
+ ip_address = "127.0.0.1" # interface to bind
133
+ port = 3001 # plaintext HTTP port
103
134
 
104
- ### Handles real project scale
135
+ [listener.tls] # optional enables HTTPS
136
+ cert = "./cert.pem"
137
+ key = "./key.pem"
138
+ # port = 3002 # optional — if omitted, HTTPS replaces HTTP on the port above
105
139
 
106
- As your project grows, your mock API grows, too. Large mock datasets often cause problems:
140
+ [log]
141
+ verbose = { header = true, body = true }
107
142
 
108
- - Slow startup
109
- - High memory usage
110
- - Crashes during UI testing
111
- - Unstable CI runs
143
+ [service]
144
+ strategy = "first_match" # only value supported today
145
+ rule_sets = ["apimock-rule-set.toml"] # paths, resolved relative to this file
146
+ middlewares = [] # Rhai scripts, resolved relative to this file
147
+ fallback_respond_dir = "." # folder served when no rule matches
148
+ ```
112
149
 
113
- apimock-rs does not preload responses. Each response file is read only when a request arrives using non-blocking I/O. This keeps:
150
+ | Section / field | Required | Default | Notes |
151
+ | --- | --- | --- | --- |
152
+ | `listener.ip_address` | no | `127.0.0.1` | Bind address. `0.0.0.0` to accept from other machines. |
153
+ | `listener.port` | no | `3001` | Plaintext HTTP port. |
154
+ | `listener.tls.cert` / `.key` | yes if `[listener.tls]` set | — | PEM files. Any key format `rustls-pki-types` accepts (PKCS#8, PKCS#1, SEC1). |
155
+ | `listener.tls.port` | no | same as `listener.port` | When omitted, the single port serves HTTPS only — no plaintext listener is started. |
156
+ | `log.verbose.header` | no | `false` | Log each request's headers. |
157
+ | `log.verbose.body` | no | `false` | Log each request's URL query and JSON body (pretty-printed). |
158
+ | `service.strategy` | no | `first_match` | Currently the only strategy — the first rule that matches wins. |
159
+ | `service.rule_sets` | no | `[]` | See **Rule-set schema** below. Paths relative to this file. |
160
+ | `service.middlewares` | no | `[]` | Rhai script paths, relative to this file. |
161
+ | `service.fallback_respond_dir` | no | `.` | Folder served when nothing in `rule_sets` or `middlewares` handled the request. |
162
+
163
+ ### Rule-set schema — `apimock-rule-set.toml`
164
+
165
+ ```toml
166
+ [prefix] # optional
167
+ url_path = "/api/v1/" # prepended to every rule's url_path
168
+ respond_dir = "apimock-rule-sets/@respond-dir" # prepended to every rule's file_path
169
+
170
+ [default] # optional
171
+ delay_response_milliseconds = 0 # applied to every rule in this set unless overridden
172
+
173
+ [[rules]]
174
+ when.request.url_path = "complicated"
175
+ when.request.method = "POST"
176
+ when.request.headers.authorization = { value = "Bearer eyJhb", op = "starts_with" }
177
+ when.request.headers.user = { value = "user1" } # op defaults to "equal"
178
+ when.request.body.json."user.id" = { value = "42" }
179
+ respond = { text = "Strictly authorized !" }
180
+
181
+ [[rules]]
182
+ when.request.url_path = { value = "/public/", op = "starts_with" }
183
+ respond = { file_path = "public/index.json", csv_records_key = "records" }
184
+
185
+ [[rules]]
186
+ when.request.url_path = ""
187
+ respond = { status = 403 }
188
+ ```
114
189
 
115
- - Startup nearly instant
116
- - Memory usage minimal
117
- - Stable behavior under repeated requests
190
+ #### `when.request` match conditions (AND-ed together)
118
191
 
119
- as validated with k6 load testing.
120
- You can run UI development and automated tests continuously without worrying about server instability.
192
+ | Field | Accepts | Purpose |
193
+ | --- | --- | --- |
194
+ | `url_path` | string *or* `{ value, op }` | URL path match. String form is shorthand for `op = "equal"`. |
195
+ | `method` | `"GET"` / `"POST"` / `"PUT"` / `"DELETE"` | HTTP method. Omit to match any method. |
196
+ | `headers` | `{ header-name = { value, op } }` map | Every listed header must match. Header names are matched case-insensitively per HTTP. |
197
+ | `body.json` | `{ json-path = { value, op } }` map | JSON body match — see **JSONPath form** below. |
121
198
 
122
- ### 📖 Documentation
199
+ #### `respond` — response shape
123
200
 
124
- For more details, **🧭 check out [the docs](https://apimokka.github.io/apimock-rs/)**.
201
+ Exactly one of `file_path` / `text` / `status` must be present. (`text` may be combined with `status` to set the response code.)
202
+
203
+ | Field | Type | Purpose |
204
+ | --- | --- | --- |
205
+ | `file_path` | string | File under `prefix.respond_dir` (or the working dir if no prefix). Extension decides content type; `.json` / `.json5` / `.csv` served as JSON, other text types served verbatim with an inferred `Content-Type`, binary types (images, audio, video, `.pdf`, `.zip`) served with the corresponding binary `Content-Type`. |
206
+ | `text` | string | Return this string verbatim. Content type `text/plain; charset=utf-8`. |
207
+ | `status` | integer (100–999) | HTTP status code. With `text`, sets the status; alone, returns an empty body with that status. Cannot be combined with `file_path`. |
208
+ | `headers` | `{ name = value }` map | Extra response headers. |
209
+ | `delay_response_milliseconds` | integer | Sleep this long before responding — useful for simulating slow backends in UI tests. |
210
+ | `csv_records_key` | string | Only meaningful when `file_path` points at a `.csv`. The JSON response wraps the rows as `{ "<key>": [...] }` using this value; defaults to `"records"`. |
211
+
212
+ #### `op` — comparison operators
213
+
214
+ Every `{ value, op }` structure accepts these `op` values. If `op` is omitted it defaults to `equal`.
215
+
216
+ | `op` | Meaning | Example |
217
+ | --- | --- | --- |
218
+ | `equal` (default) | Exact string match | `{ value = "user1" }` matches `user1` only |
219
+ | `not_equal` | Anything *but* an exact match | `{ value = "guest", op = "not_equal" }` matches everything except `guest` |
220
+ | `starts_with` | String starts with value | `{ value = "Bearer ", op = "starts_with" }` matches any Bearer token |
221
+ | `contains` | Value appears anywhere inside the target | `{ value = "admin", op = "contains" }` matches `superadmin`, `admin-1`, etc. |
222
+ | `wild_card` | Glob match — see below | `{ value = "/api/v*/users/?", op = "wild_card" }` |
223
+
224
+ ##### Wildcard / glob syntax (`wild_card`)
225
+
226
+ The glob matcher supports exactly two metacharacters, matching the common case without the complexity of a full regex engine:
227
+
228
+ | Token | Matches |
229
+ | --- | --- |
230
+ | `?` | Exactly one character |
231
+ | `*` | Zero or more characters |
232
+
233
+ Examples:
234
+
235
+ | Pattern | Matches | Doesn't match |
236
+ | --- | --- | --- |
237
+ | `hello` | `hello` | `hell`, `hello!` |
238
+ | `file*.txt` | `file.txt`, `file123.txt`, `files/doc.txt` | `file.csv` |
239
+ | `file?.txt` | `file1.txt`, `fileX.txt` | `file.txt`, `file12.txt` |
240
+ | `a*b?c` | `axyzbxc`, `ab1c` | `abc` |
241
+ | `*test*` | `my_test_file`, `test` | `tes` |
242
+ | `こんにち?世界` | `こんにちは世界` | Unicode is respected per code point. |
243
+
244
+ This is NOT a regex. Sequences such as `.`, `[…]`, `(…)`, `+`, `^`, `$` are matched literally.
245
+
246
+ ##### JSONPath form (`body.json` and `csv_records_key`)
247
+
248
+ The JSONPath support is deliberately minimal — only the "object key" and "array index" forms, joined by `.`. This covers every real-world body-match need without exposing a full jsonpath engine that users would then have to learn.
249
+
250
+ | Input | Meaning |
251
+ | --- | --- |
252
+ | `user` | Top-level key `user` |
253
+ | `user.id` | `user` → `id` (nested object) |
254
+ | `items.0` | First element of array `items` |
255
+ | `orders.2.total` | Array index 2 of `orders`, then key `total` |
256
+ | `a.b.c` | Three-level nested object lookup |
257
+
258
+ If any segment is missing or has the wrong shape (e.g. a numeric segment against an object), the rule simply does not match — no error, because "missing" is a useful matchable condition.
259
+
260
+ #### `prefix`
261
+
262
+ | Field | Effect |
263
+ | --- | --- |
264
+ | `url_path` | Prepended to every rule's `when.request.url_path` before matching. Leading/trailing slashes are normalised. The `contains` operator deliberately ignores the prefix — it matches against the raw `url_path` value — because "contains" usually means "substring anywhere in the full request path", and re-applying a prefix there would be surprising. |
265
+ | `respond_dir` | Prepended to every rule's `respond.file_path`. Resolved relative to the rule-set file's directory, not the working dir — so configs travel cleanly between machines. |
266
+
267
+ #### `default`
268
+
269
+ | Field | Effect |
270
+ | --- | --- |
271
+ | `delay_response_milliseconds` | Default delay for rules in this set that don't specify their own. |
125
272
 
126
273
  ---
127
274
 
128
275
  ## Open-source, with care
129
276
 
130
- [This project](https://github.com/apimokka/apimock-rs) is lovingly built and maintained by volunteers.
277
+ This project is lovingly built and maintained by volunteers.
131
278
  We hope it helps streamline your API development.
132
279
  Please understand that the project has its own direction — while we welcome feedback, it might not fit every edge case 🌱
133
280
 
134
281
  ## Acknowledgements
135
282
 
136
- Depends on [tokio](https://github.com/tokio-rs/tokio) / [hyper](https://hyper.rs/) / [toml](https://github.com/toml-rs/toml) / [serde](https://serde.rs/) / [serde_json](https://github.com/serde-rs/json) / [json5](https://github.com/callum-oakley/json5-rs) / [console](https://github.com/console-rs/console) / [rhai](https://github.com/rhaiscript/rhai). In addition, [mdbook](https://github.com/rust-lang/mdBook) (as to workflows).
283
+ Depends on [tokio](https://github.com/tokio-rs/tokio) / [hyper](https://hyper.rs/) / [toml](https://github.com/toml-rs/toml) / [serde](https://serde.rs/) / [serde_json](https://github.com/serde-rs/json) / [json5](https://github.com/callum-oakley/json5-rs) / [console](https://github.com/console-rs/console) / [rhai](https://github.com/rhaiscript/rhai) / [thiserror](https://crates.io/crates/thiserror) / [anyhow](https://crates.io/crates/anyhow). In addition, [mdbook](https://github.com/rust-lang/mdBook) (as to workflows).
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "apimock-rs",
3
- "version": "4.6.9",
4
- "description": "A developer-friendly, featherlight and functional HTTP(S) mock server built in Rust.",
3
+ "version": "4.7.1",
4
+ "description": "HTTP(S) mock server. Drop JSON files into a folder and your API immediately exists.",
5
5
  "author": "nabbisen<nabbisen@scqr.net>",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {