|
1 | 1 | --- |
2 | 2 | title: Faker |
3 | | -description: Faker plugin for Hey API. Compatible with all our features. |
| 3 | +description: Generate realistic mock data factories from OpenAPI with the Faker plugin for openapi-ts. Fully compatible with all core features. |
4 | 4 | --- |
5 | 5 |
|
6 | 6 | <script setup lang="ts"> |
7 | | -import FeatureStatus from '@components/FeatureStatus.vue'; |
| 7 | +import Heading from '@components/Heading.vue'; |
8 | 8 | </script> |
9 | 9 |
|
10 | | -# Faker <span data-badge>vote</span> |
11 | | - |
12 | | -<FeatureStatus issueNumber=1485 name="Faker" /> |
| 10 | +<Heading> |
| 11 | + <h1>Faker</h1> |
| 12 | +</Heading> |
13 | 13 |
|
14 | 14 | ### About |
15 | 15 |
|
16 | 16 | [Faker](https://fakerjs.dev) is a popular library that generates fake (but reasonable) data that can be used for things such as unit testing, performance testing, building demos, and working without a completed backend. |
17 | 17 |
|
| 18 | +The Faker plugin for Hey API generates factory functions from your OpenAPI spec that return realistic mock data using `@faker-js/faker`. |
| 19 | + |
| 20 | +## Features |
| 21 | + |
| 22 | +- seamless integration with `@hey-api/openapi-ts` ecosystem |
| 23 | +- factory functions for reusable schema definitions and operation responses |
| 24 | +- smart property name inference for realistic data (e.g. `email` → `faker.internet.email()`) |
| 25 | +- constraint and format awareness (min/max, string formats, array bounds) |
| 26 | +- optional property and default value handling |
| 27 | +- dependency injection for custom faker instances (locale, seed) |
| 28 | +- minimal learning curve thanks to extending the underlying technology |
| 29 | + |
| 30 | +## Installation |
| 31 | + |
| 32 | +In your [configuration](/openapi-ts/get-started), add `@faker-js/faker` to your plugins and you'll be ready to generate faker factories. :tada: |
| 33 | + |
| 34 | +```js |
| 35 | +export default { |
| 36 | + input: 'hey-api/backend', // sign up at app.heyapi.dev |
| 37 | + output: 'src/client', |
| 38 | + plugins: [ |
| 39 | + // ...other plugins |
| 40 | + '@faker-js/faker', // [!code ++] |
| 41 | + ], |
| 42 | +}; |
| 43 | +``` |
| 44 | + |
| 45 | +## Output |
| 46 | + |
| 47 | +The Faker plugin will generate the following artifacts, depending on the input specification. |
| 48 | + |
| 49 | +## Definitions |
| 50 | + |
| 51 | +A factory function is generated for every reusable definition from your input. |
| 52 | + |
| 53 | +::: code-group |
| 54 | + |
| 55 | +```ts [example] |
| 56 | +import { faker, type Faker } from '@faker-js/faker'; |
| 57 | + |
| 58 | +import type { Bar, Foo } from '../types.gen'; |
| 59 | + |
| 60 | +export const fakeFoo = (options?: Options): Foo => ({ |
| 61 | + name: ensureFaker(options).string.sample(), |
| 62 | + age: ensureFaker(options).number.int({ min: 1, max: 120 }), |
| 63 | +}); |
| 64 | + |
| 65 | +export const fakeBar = (options?: Options): Bar => |
| 66 | + ensureFaker(options).helpers.arrayElement(['baz', 'qux']); |
| 67 | +``` |
| 68 | + |
| 69 | +```js [config] |
| 70 | +export default { |
| 71 | + input: 'hey-api/backend', // sign up at app.heyapi.dev |
| 72 | + output: 'src/client', |
| 73 | + plugins: [ |
| 74 | + // ...other plugins |
| 75 | + { |
| 76 | + name: '@faker-js/faker', |
| 77 | + definitions: true, // [!code ++] |
| 78 | + }, |
| 79 | + ], |
| 80 | +}; |
| 81 | +``` |
| 82 | + |
| 83 | +::: |
| 84 | + |
| 85 | +You can customize the naming and casing pattern for `definitions` factories using the `.name` and `.case` options. |
| 86 | + |
| 87 | +## Responses |
| 88 | + |
| 89 | +A factory function is generated for operation responses. When an operation has a single success response, the factory is unsuffixed. When multiple responses exist, each factory is suffixed with the status code. |
| 90 | + |
| 91 | +::: code-group |
| 92 | + |
| 93 | +```ts [example] |
| 94 | +// single success response — unsuffixed |
| 95 | +export const fakeCreatePetResponse = (options?: Options): CreatePetResponse => fakePet(options); |
| 96 | + |
| 97 | +// multiple responses — suffixed with status code |
| 98 | +export const fakeGetPetResponse200 = (options?: Options): GetPetResponses[200] => fakePet(options); |
| 99 | + |
| 100 | +export const fakeGetPetResponse404 = (options?: Options): GetPetErrors[404] => fakeError(options); |
| 101 | +``` |
| 102 | + |
| 103 | +```js [config] |
| 104 | +export default { |
| 105 | + input: 'hey-api/backend', // sign up at app.heyapi.dev |
| 106 | + output: 'src/client', |
| 107 | + plugins: [ |
| 108 | + // ...other plugins |
| 109 | + { |
| 110 | + name: '@faker-js/faker', |
| 111 | + responses: true, // [!code ++] |
| 112 | + }, |
| 113 | + ], |
| 114 | +}; |
| 115 | +``` |
| 116 | + |
| 117 | +::: |
| 118 | + |
| 119 | +You can customize the naming and casing pattern for `responses` factories using the `.name` and `.case` options. |
| 120 | + |
| 121 | +## Smart Inference |
| 122 | + |
| 123 | +The plugin infers semantically appropriate faker methods from property names, producing more realistic mock data without requiring explicit schema formats or annotations. |
| 124 | + |
| 125 | +```ts |
| 126 | +// property name "email" → faker.internet.email() |
| 127 | +// property name "firstName" → faker.person.firstName() |
| 128 | +// property name "city" → faker.location.city() |
| 129 | +// property name "id" → faker.string.uuid() |
| 130 | +// property name "age" → faker.number.int({ min: 1, max: 120 }) |
| 131 | +``` |
| 132 | + |
| 133 | +Ancestor context is also used for disambiguation. For example, `name` under a `User` schema produces `faker.person.fullName()`, while `name` under a `Company` schema produces `faker.company.name()`. |
| 134 | + |
| 135 | +Explicit schema annotations (format, pattern, constraints) always take priority over name-based inference. |
| 136 | + |
| 137 | +## Formats and Constraints |
| 138 | + |
| 139 | +The plugin respects OpenAPI schema formats and constraints to generate appropriately bounded data. |
| 140 | + |
| 141 | +**String formats:** |
| 142 | + |
| 143 | +- `email` → `faker.internet.email()` |
| 144 | +- `date-time` → `faker.date.recent().toISOString()` |
| 145 | +- `date` → `faker.date.recent().toISOString().slice(0, 10)` |
| 146 | +- `uuid` → `faker.string.uuid()` |
| 147 | +- `uri` / `url` → `faker.internet.url()` |
| 148 | +- `ipv4` → `faker.internet.ipv4()` |
| 149 | +- `ipv6` → `faker.internet.ipv6()` |
| 150 | +- `pattern` → `faker.helpers.fromRegExp(pattern)` |
| 151 | + |
| 152 | +**Numeric constraints:** |
| 153 | + |
| 154 | +- `minimum` / `maximum` → `faker.number.int({ min, max })` |
| 155 | +- `exclusiveMinimum` / `exclusiveMaximum` → adjusted bounds |
| 156 | + |
| 157 | +**String constraints:** |
| 158 | + |
| 159 | +- `minLength` / `maxLength` → `faker.string.alpha({ length: { min, max } })` |
| 160 | + |
| 161 | +**Array constraints:** |
| 162 | + |
| 163 | +- `minItems` / `maxItems` → controls count in `faker.helpers.multiple()` |
| 164 | + |
| 165 | +## Optional Properties |
| 166 | + |
| 167 | +Required properties are always included. Optional properties are controlled by the `includeOptional` option at runtime. |
| 168 | + |
| 169 | +```ts |
| 170 | +const user = fakeFoo(); // includes optional properties by default |
| 171 | +const user = fakeFoo({ includeOptional: false }); // excludes optional properties |
| 172 | +const user = fakeFoo({ includeOptional: 0.5 }); // 50% probability per optional property |
| 173 | +``` |
| 174 | + |
| 175 | +## Default Values |
| 176 | + |
| 177 | +When a schema defines default values, you can control whether to use them instead of generating fake data via the `useDefault` option. |
| 178 | + |
| 179 | +```ts |
| 180 | +const data = fakeFoo(); // always generates fake data |
| 181 | +const data = fakeFoo({ useDefault: true }); // uses schema defaults when available |
| 182 | +const data = fakeFoo({ useDefault: 0.5 }); // 50% probability of using defaults |
| 183 | +``` |
| 184 | + |
| 185 | +## Locale |
| 186 | + |
| 187 | +You can configure the locale for generated faker factories. When set, the generated code imports the faker instance from the locale-specific build of `@faker-js/faker`. |
| 188 | + |
| 189 | +::: code-group |
| 190 | + |
| 191 | +```ts [output] |
| 192 | +import { faker } from '@faker-js/faker/locale/de'; |
| 193 | +import type { Faker } from '@faker-js/faker'; |
| 194 | +``` |
| 195 | + |
| 196 | +```js [config] |
| 197 | +export default { |
| 198 | + input: 'hey-api/backend', // sign up at app.heyapi.dev |
| 199 | + output: 'src/client', |
| 200 | + plugins: [ |
| 201 | + // ...other plugins |
| 202 | + { |
| 203 | + name: '@faker-js/faker', |
| 204 | + locale: 'de', // [!code ++] |
| 205 | + }, |
| 206 | + ], |
| 207 | +}; |
| 208 | +``` |
| 209 | + |
| 210 | +::: |
| 211 | + |
| 212 | +See the [Faker localization guide](https://fakerjs.dev/guide/localization) for available locales. |
| 213 | + |
| 214 | +## Custom Faker Instance |
| 215 | + |
| 216 | +For runtime locale switching or seeded deterministic output, you can pass your own faker instance via the `faker` option. |
| 217 | + |
| 218 | +```ts |
| 219 | +import { faker } from '@faker-js/faker/locale/de'; |
| 220 | + |
| 221 | +faker.seed(42); |
| 222 | +const data = fakeFoo({ faker }); |
| 223 | +``` |
| 224 | + |
| 225 | +## API |
| 226 | + |
| 227 | +You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@faker-js/faker/types.ts) interface. |
| 228 | + |
18 | 229 | <!--@include: ../../partials/sponsors.md--> |
0 commit comments