{"id":13652502,"url":"https://github.com/webpro/dyson","last_synced_at":"2025-04-23T03:30:51.971Z","repository":{"id":6350632,"uuid":"7587268","full_name":"webpro/dyson","owner":"webpro","description":"Node server for dynamic, fake JSON.","archived":true,"fork":false,"pushed_at":"2023-04-13T22:22:59.000Z","size":1807,"stargazers_count":835,"open_issues_count":13,"forks_count":62,"subscribers_count":20,"default_branch":"master","last_synced_at":"2024-05-01T22:48:42.822Z","etag":null,"topics":["dummy","javascript","json","mock","server","stub"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/webpro.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2013-01-13T11:29:05.000Z","updated_at":"2024-01-25T07:24:51.000Z","dependencies_parsed_at":"2023-02-13T16:16:30.806Z","dependency_job_id":"7eb16763-ea2c-49a1-9def-55ae1bf69256","html_url":"https://github.com/webpro/dyson","commit_stats":{"total_commits":340,"total_committers":22,"mean_commits":"15.454545454545455","dds":0.1029411764705882,"last_synced_commit":"a05906fd1381d22dfab1a8c4789e3fad44b18f5b"},"previous_names":[],"tags_count":59,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webpro%2Fdyson","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webpro%2Fdyson/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webpro%2Fdyson/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webpro%2Fdyson/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/webpro","download_url":"https://codeload.github.com/webpro/dyson/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250365329,"owners_count":21418670,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dummy","javascript","json","mock","server","stub"],"created_at":"2024-08-02T02:00:59.918Z","updated_at":"2025-04-23T03:30:50.425Z","avatar_url":"https://github.com/webpro.png","language":"JavaScript","readme":"# dyson\n\nNode server for dynamic, fake JSON.\n\n## Introduction\n\nDyson allows you to define JSON endpoints based on a simple `path` + `template` object:\n\n```javascript\n# my-stubs/users.js\nmodule.exports = {\n  path: '/users/:userId',\n  template: {\n    id: params =\u003e Number(params.userId),\n    name: () =\u003e faker.name.findName(),\n    email: () =\u003e faker.internet.email(),\n    status: (params, query) =\u003e query.status,\n    lorem: true\n  }\n};\n```\n\n```bash\n$ dyson ./my-stubs\n$ curl http://localhost:3000/users/1?status=active\n```\n\n```json\n{\n  \"id\": 1,\n  \"name\": \"Josie Greenfelder\",\n  \"email\": \"Raoul_Aufderhar@yahoo.com\",\n  \"status\": \"active\",\n  \"lorem\": true\n}\n```\n\nWhen developing client-side applications, often either static JSON files, or an actual server, backend, datastore, or API, is used. Sometimes static files are too static, and sometimes an actual server is not available, not accessible, or too tedious to set up.\n\nThis is where dyson comes in. Get a full fake server for your application up and running in minutes.\n\n- [Installation notes](#installation)\n- [Demo](https://dyson-demo.herokuapp.com)\n\n[![Build Status](https://img.shields.io/travis/webpro/dyson.svg?style=flat)](https://travis-ci.org/webpro/dyson)\n[![npm package](https://img.shields.io/npm/v/dyson.svg?style=flat)](https://www.npmjs.com/package/dyson)\n[![dependencies](https://img.shields.io/david/webpro/dyson.svg?style=flat)](https://david-dm.org/webpro/dyson)\n![npm version](https://img.shields.io/node/v/dyson.svg?style=flat)\n\n## Overview\n\n- Dynamic responses, based on\n  - Request path\n  - GET/POST parameters\n  - Query parameters\n  - Cookies\n- HTTP Methods: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS\n- Dynamic HTTP status codes\n- CORS\n- Proxy (e.g. fallback to actual services)\n- Delayed responses\n- Required parameter validation\n- Includes random data generators\n- Includes dummy image generator\n  - Use any external or local image service (included)\n  - Supports base64 encoded image strings\n\n## Endpoint Configuration\n\nConfigure endpoints using simple objects:\n\n```javascript\nmodule.exports = {\n  path: '/user/:id',\n  method: 'GET',\n  template: {\n    id: (params, query, body) =\u003e params.id,\n    name: g.name,\n    address: {\n      zip: g.zipUS,\n      city: g.city\n    }\n  }\n};\n```\n\nThe `path` string is the usual argument provided to [Express](http://expressjs.com/api.html#app.VERB), as in `app.get(path, callback);`.\n\nThe `template` object may contain properties of the following types:\n\n- A `Function` will be invoked with arguments `(params, query, body, cookies, headers)`.\n- Primitives of type `String`, `Boolean`, `Number`, `Array` are returned as-is\n- An `Object` will be recursively iterated.\n- A `Promise` will be replaced with its resolved value.\n\nNote: the `template` itself can also be a _function_ returning the actual data. The template function itself is also invoked with arguments `(params, query, body, cookies, headers)`.\n\n## Defaults\n\nThe default values for the configuration objects:\n\n```javascript\nmodule.exports = {\n  cache: false,\n  delay: false,\n  proxy: false,\n  size: () =\u003e _.random(2, 10),\n  collection: false,\n  callback: response.generate,\n  render: response.render\n};\n```\n\n- `cache: true` means that multiple requests to the same path will result in the same response\n- `delay: n` will delay the response with `n` milliseconds (or between `[n, m]` milliseconds)\n- `proxy: false` means that requests to this file can be skipped and sent to the configured proxy\n- `size: fn` is the number of objects in the collection\n- `collection: true` will return a collection\n- `callback: fn`\n  - the provided default function is doing the hard work (can be overridden)\n  - used as middleware in Express\n  - must set `res.body` and call `next()` to render response\n- `render: fn`\n  - the default function to render the response (basically `res.send(200, res.body);`)\n  - used as middleware in Express\n\n## Fake data generators\n\nYou can use _anything_ to generate data. Here are some suggestions:\n\n- [Faker.js](https://github.com/marak/Faker.js/)\n- [Chance.js](http://chancejs.com/)\n- [dyson-generators](http://github.com/webpro/dyson-generators)\n\nJust install the generator(s) in your project to use them in your templates:\n\n```bash\nnpm install dyson-generators --save-dev\n```\n\n## Containers\n\nContainers can help if you need to send along some meta data, or wrap the response data in a specific way. Just use the `container` object, and return the `data` where you want it. Functions in the `container` object are invoked with arguments `(params, query, data)`:\n\n```javascript\nmodule.exports = {\n  path: '/users',\n  template: user.template,\n  container: {\n    meta: (params, query, data) =\u003e ({\n      userCount: data.length\n    }),\n    data: {\n      all: [],\n      the: {\n        way: {\n          here: (params, query, data) =\u003e data\n        }\n      }\n    }\n  }\n};\n```\n\nAnd an example response:\n\n```json\n{\n  \"meta\": {\n    \"userCount\": 2\n  },\n  \"data\": {\n    \"all\": [],\n    \"the\": {\n      \"way\": {\n        \"here\": [\n          {\n            \"id\": 412,\n            \"name\": \"John\"\n          },\n          {\n            \"id\": 218,\n            \"name\": \"Olivia\"\n          }\n        ]\n      }\n    }\n  }\n}\n```\n\n## Combined requests\n\nBasic support for \"combined\" requests is available, by means of a comma separated path fragment.\n\nFor example, a request to `/user/5,13` will result in an array of the responses from `/user/5` and `/user/13`.\n\nThe `,` delimiter can be [configured](#project-configuration) (or disabled).\n\n## Status codes\n\nBy default, all responses are sent with a status code `200` (and the `Content-Type: application/json` header).\n\nThis can be overridden with your own `status` middleware, e.g.:\n\n```javascript\nmodule.exports = {\n  path: '/feature/:foo?',\n  status: (req, res, next) =\u003e {\n    if (req.params.foo === '999') {\n      res.status(404);\n    }\n    next();\n  }\n};\n```\n\nWould result in a `404` when requesting `/feature/999`.\n\n## Images\n\nIn addition to configured endpoints, dyson registers a [dummy image service](http://github.com/webpro/dyson-image) at `/image`. E.g. requesting `/image/300x200` serves an image with given dimensions.\n\nThis service is a proxy to [Dynamic Dummy Image Generator](http://dummyimage.com/) by [Russell Heimlich](http://twitter.com/kingkool68).\n\n## JSONP\n\nOverride the `render` method of the Express middleware in the endpoint definition. In the example below, depending on the existence of the `callback` parameter, either raw JSON response is returned or it is wrapped with the provided callback:\n\n```javascript\nmodule.exports = {\n  render: (req, res) =\u003e {\n    const callback = req.query.callback;\n    if (callback) {\n      res.append('Content-Type', 'application/javascript');\n      res.send(`${callback}(${JSON.stringify(res.body)});`);\n    } else {\n      res.send(res.body);\n    }\n  }\n};\n```\n\n## File Upload\n\nEx: return file name\u003cbr/\u003e\nformDataName = 'file'\n\n```javascript\nmodule.exports = {\n  render: (req, res) =\u003e {\n    if (callback) {\n      res.send({ fileName: req.files.file.name });\n    } else {\n      res.send(res.body);\n    }\n  }\n};\n```\n\n## HTTPS\n\nIf you want to run dyson over SSL you have to provide a (authority-signed or self-signed) certificate into the `options.https` the same way it's required for NodeJS built-in `https` module. Example:\n\n```javascript\nconst fs = require('fs');\n\nconst app = dyson.createServer({\n  configDir: `${__dirname}/dummy`,\n  port: 3001,\n  https: {\n    key: fs.readFileSync(`${__dirname}'/certs/sample.key`),\n    crt: fs.readFileSync(`${__dirname}/certs/sample.crt`)\n  }\n});\n```\n\n**Note**: if running SSL on port 443, it will require `sudo` privileges.\n\n## GraphQL\n\nIf you want dyson to support GraphQL endpoints, you can build your own logic with the `render` override, or use [`dyson-graphql`](https://github.com/WealthWizardsEngineering/dyson-graphql). Example:\n\n```bash\nnpm install dyson-graphql --save-dev\n```\n\n```javascript\nconst dysonGraphQl = require('dyson-graphql');\n\nconst schema = `\n  type User {\n    id: Int!\n    name: String!\n  }\n\n  type Query {\n    currentUser: User!\n  }\n\n  type Mutation {\n    createUser(name: String!): User!\n    updateUser(id: Int!, name: String!): User!\n  }\n`;\n\nmodule.exports = {\n  path: '/graphql',\n  method: 'POST',\n  render: dysonGraphQl(schema)\n    .query('currentUser', { id: 987, name: 'Jane Smart' })\n    .mutation('createUser', ({ name }) =\u003e ({ id: 456, name }))\n    .mutation('updateUser', ({ id, name }) =\u003e {\n      if (id \u003c 1000) {\n        return { id, name };\n      }\n\n      throw new Error(\"Can't update user\");\n    })\n    .build()\n};\n```\n\n## Custom middleware\n\nIf you need some custom middleware before or after the endpoints are registered, dyson can be initialized programmatically.\nThen you can use the Express server instance (`appBefore` or `appAfter` in the example below) to install middleware before or after the dyson services are registered. An example:\n\n```javascript\nconst dyson = require('dyson');\nconst path = require('path');\n\nconst options = {\n  configDir: path.join(__dirname, 'services'),\n  port: 8765\n};\n\nconst configs = dyson.getConfigurations(options);\nconst appBefore = dyson.createServer(options);\nconst appAfter = dyson.registerServices(appBefore, options, configs);\n\nconsole.log(`Dyson listening at port ${options.port}`);\n```\n\nDyson configuration can also be installed into any Express server:\n\n```javascript\nconst express = require('express');\nconst dyson = require('./lib/dyson');\nconst path = require('path');\n\nconst options = {\n  configDir: path.join(__dirname, 'services')\n};\n\nconst myApp = express();\nconst configs = dyson.getConfigurations(options);\n\ndyson.registerServices(myApp, options, configs);\n\nmyApp.listen(8765);\n```\n\n## Installation\n\nThe recommended way to install dyson is to install it locally and put it in your `package.json`:\n\n```bash\nnpm install dyson --save-dev\n```\n\nThen you can use it from `scripts` in `package.json` using e.g. `npm run mocks`:\n\n```json\n{\n  \"name\": \"my-package\",\n  \"version\": \"1.0.0\",\n  \"scripts\": {\n    \"mocks\": \"dyson mocks/\"\n  }\n}\n```\n\nYou can also install dyson globally to start it from anywhere:\n\n```bash\nnpm install -g dyson\n```\n\n### Project\n\nYou can put your configuration files anywhere. The HTTP method is based on:\n\n- The `method` property in the configuration itself.\n- The folder, or an ancestor folder, containing the configuration is an HTTP method. For example `mocks/post/sub/endpoint.js` will be an endpoint listening to `POST` requests.\n- Defaults to `GET`.\n\n```bash\ndyson [dir]\n```\n\nThis starts the services configured in `[dir]` at [localhost:3000](http://localhost:3000).\n\nYou can also provide an alternative port number by just adding it as a second argument (e.g. `dyson path/ 8181`).\n\n### Demo\n\n- For a demo project, see [webpro/dyson-demo](https://github.com/webpro/dyson-demo).\n- This demo was also installed with [Heroku](https://www.heroku.com) to [dyson-demo.herokuapp.com](https://dyson-demo.herokuapp.com).\n\n## Project Configuration\n\nOptionally, you can put a `dyson.json` file next to the configuration folders (inside `[dir]`). It enables to configure some behavior of dyson:\n\n```json\n{\n  \"multiRequest\": \",\",\n  \"proxy\": true,\n  \"proxyHost\": \"http://dyson.jit.su\",\n  \"proxyPort\": 8080,\n  \"proxyDelay\": [200, 800]\n}\n```\n\n- Setting `multiRequest` to `false` disables the [combined requests](#combined-requests) feature.\n- Setting `bodyParserJsonLimit` or `bodyParserUrlencodedLimit` to `1mb` increases the limit to 1mb from the bodyParser's default of 100kb.\n- By default, the `proxy` is set to `false`\n\n## Watch/auto-restart\n\nIf you want to automatically restart dyson when you change your configuration objects, you can add [nodemon](https://nodemon.io) as a `devDependency`. Say your configuration files are in the `./api` folder, you can put this in your `package.json`:\n\n```\n\"scripts\": {\n  \"mocks\": \"dyson mocks/\",\n  \"watch\": \"nodemon --watch mocks --exec dyson mocks\"\n}\n```\n\n## Development \u0026 run tests\n\n```bash\ngit clone git@github.com:webpro/dyson.git\ncd dyson\nnpm install\nnpm test\n```\n\n## Articles about dyson\n\n- [How do I create a Fake Server with Dyson? | Apiumhub](https://apiumhub.com/tech-blog-barcelona/create-fake-server-dyson/)\n- [Stubbing Network Calls (Api) Using Dyson for Emberjs Apps](http://nepalonrails.herokuapp.com/blog/2014/03/stubbing-network-calls-api-using-dyson-for-emberjs-apps/)\n- [Our Ember.js Toolchain](https://nebulab.com/blog/our-ember-js-toolchain)\n- [Dyson, construye un servidor de pruebas que devuelva fake JSON para simular una API](https://www.genbeta.com/desarrollo/dyson-construye-un-servidor-de-pruebas-que-devuelva-fake-json-para-simular-una-api)\n- [Mockear la capa back con Dyson](https://www.adictosaltrabajo.com/2014/08/27/dyson-fake-json/)\n- [Serve JSONP in Dyson](https://grysz.com/2015/12/01/serve-jsonp-in-dyson/)\n- Videos\n  _ [Dyson - HTTP Service mocking](https://www.youtube.com/watch?v=aoSk5Bak-KM)\n  _ [How to implement HTTP Mock Services into Webpack - Dyson](https://www.youtube.com/watch?v=tfCQOcz9oi4)\n\n## License\n\n[MIT](http://webpro.mit-license.org)\n","funding_links":[],"categories":["Data generation"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebpro%2Fdyson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwebpro%2Fdyson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebpro%2Fdyson/lists"}