LLM-powered command-line tool that generates structured data based on Zod schemas and serves it as a REST API
MIT License
gfa
(generate-fake-api) is a LLM-powered command-line tool that generates structured data based on Zod schemas and serves it as a REST API. You can think of it as an AI-driven json-server. Just define a seed file with the resources you want to generate, and gfa
will take care of the rest.
You define a seed file with the resources you want to generate:
import type { Seed } from "gfa";
import { z } from "zod";
export default {
posts: {
prompt: "Generate 3 blog posts. The title should be between 5 and 10 words and the body should be between 50 and 100 words.",
schema: z.object({
id: z.number(),
title: z.string(),
body: z.string(),
}),
},
} satisfies Seed;
You get a fake REST API with the resources you defined:
$ npx gfa seed.ts
✔ Resources generated (total tokens: 453)
Serving API on http://localhost:3000 (Press Ctrl-C to quit)
Available routes:
GET /api/posts
GET /api/posts/:id
POST /api/posts
PUT /api/posts/:id
PATCH /api/posts/:id
DELETE /api/posts/:id
gfa
currently supports the following AI providers for generating data:
You need an API key from one of these providers to use gfa
. Once you have your API key, set it as an environment variable, either OPENAI_API_KEY
or ANTHROPIC_API_KEY
, using the export
command. For example:
export OPENAI_API_KEY=your-api-key
After setting the API key, install the dependencies in your project:
npm install gfa zod --save-dev
Next, create a seed file. The seed file should export an object that satisfies the Seed
type from gfa
. The seed object should have keys that represent the resources you want to generate. Each resource should have a schema
key that describes the shape of the resource using a ZodObject
instance. Resources can also have an optional prompt
key that describes the prompt to generate the resource. Resources are considered to be plural by default, i.e., they are arrays of objects. If you want to generate a single object instead of an array, you can set the single
key to true
.
Here is an example seed file:
import type { Seed } from "gfa";
import { z } from "zod";
export default {
posts: {
prompt: "Generate 3 posts",
schema: z.object({
id: z.number(),
title: z.string(),
views: z.number(),
}),
},
comments: {
prompt: "Generate 5 comments. postIds should be between 1 and 3",
schema: z.object({
id: z.number(),
text: z.string(),
postId: z.number(),
}),
},
profile: {
single: true,
prompt: "Generate a profile",
schema: z.object({
name: z.string(),
}),
},
} satisfies Seed;
Now you can run the gfa
command to generate resources and serve the API:
$ npx gfa seed.ts
✔ Resources generated (total tokens: 383)
Serving API on http://localhost:3000 (Press Ctrl-C to quit)
Available routes:
GET /api/posts
GET /api/posts/:id
POST /api/posts
PUT /api/posts/:id
PATCH /api/posts/:id
DELETE /api/posts/:id
GET /api/comments
GET /api/comments/:id
POST /api/comments
PUT /api/comments/:id
PATCH /api/comments/:id
DELETE /api/comments/:id
GET /api/profile
PUT /api/profile
PATCH /api/profile
The API is now running at http://localhost:3000
. You can interact with it using curl
or a tool like Postman. Here is an example request using curl
:
$ curl -s http://localhost:3000/api/posts | jq .
[
{
"id": 1,
"title": "Exploring the Wonders of Nature",
"views": 150
},
{
"id": 2,
"title": "The Future of Technology: Trends to Watch",
"views": 200
},
{
"id": 3,
"title": "Healthy Eating: Tips for a Balanced Diet",
"views": 120
}
]
$ curl -s 'http://localhost:3000/api/posts?page=2&per_page=2' | jq .
[
{
"id": 3,
"title": "Healthy Eating: Tips for a Balanced Diet",
"views": 120
}
]
-m
, --modelId
Specifies the model ID to use for generating data. The default is gpt-4o-2024-08-06
. For a list of available model IDs, see the Available Model Ids section.
npx gfa seed.ts --modelId 'gpt-4o-mini'
--regenerate
Generates new data for the resources specified in the seed file even if the data already exists.
npx gfa seed.ts --regenerate
-p
, --port
Specifies the port on which to serve the API. The default is 3000
.
npx gfa seed.ts --port 8888
-s
, --serve
Specifies the resources path to serve. If the option is set, gfa
will not generate new data but will serve the data from the specified path. The path should be point to a JSON file that contains the following structure:
{
"resource_a": [
{
"id": 1,
"name": "Resource A 1"
},
{
"id": 2,
"name": "Resource A 2"
}
],
"resource_b": {
"description": "Resource B"
},
...
}
Note that data in arrays should have an id
field. Without an id
field, some routes (e.g., GET /resource_a/[id]
) will not function properly.
--basePath
Specifies the base path for the API. The base path, which defaults to /api
, is prepended to all routes.
npx gfa seed.ts --basePath '/v1'
Now the API will be served on http://localhost:3000/v1
.
page
GET /api/posts?page=2
per_page
GET /api/posts?per_page=5
gfa
generates the data into the node_modules/gfa/dist
directory. You can tweak the data or add more data to the generated files if you want.
Currently, gfa
does not save the changes made to the resources through the API.
gfa
?The cost of using gfa
varies based on the AI provider and the amount of data you generate. gfa
displays the total number of tokens generated each time you run the command. For the details of the pricing, please refer to the pricing pages of the AI providers: