Rapid GraphQL server setup for testing with Faker
Step by step guide on how to install, setup, generate fake data for JSON files, and run a GraphQL server (GraphiQL included) for testing or mocking in under 10 minutes.
June 16, 2020
What is covered
Code repository
Primers
-
json-graphql-server "Get a full fake GraphQL API with zero coding in less than 30 seconds"
-
faker.js "Generate massive amounts of fake data in the browser and Node.js"
Installing json-graphql-server and faker
Nothing special here npm i --save-dev json-graphql-server faker
. We also need some other Node.js packages to set the whole thing up: express
, ip
, lodash.get
, lodash.find
, lodash.filter
, lodash.findindex
, lodash.startcase
, random-string
.
Generate data with Faker
Let’s take a look at /scripts/faker-data.js file. We first define some constants (lines 5-25) to calibrate Faker generated data, dataSet
object we want populated with data, the helper function generateGroup
and we make use of it to generate featuredPool
. Between lines 62-105 we generate the data making use of the Faker functions lorem
, random
, company
, name
, finance
. Finally, we write the JSON stringified dataSet
to the dataSet.json
file. We also create the activation.json
file to authenticate the Apple TV devices based on their UUID
.
const faker = require('faker');
const fs = require('fs');
const startCase = require('lodash.startcase');
const MAX = 100;
const FEATURED = 6;
const CATEGORIES = [
'Action',
'Adventure',
'Comedy',
'Crime',
'Drama',
'Epics',
'Horror',
'History',
'Documentary',
'Musical',
'Sci-Fi',
'War',
'Western',
'Thriller',
'Biographical',
'Animated',
'Fantasy',
];
const dataSet = {
categories: [],
movies: [],
};
const generateGroup = (no, func, join = true) => {
const group = [];
while (group.length < no) {
const item = func();
if (group.indexOf(item) === -1) {
group.push(item);
}
}
if (join) {
return group.join(', ');
}
return group;
};
const featuredPool = generateGroup(
FEATURED,
() => faker.random.number({ min: 1, max: MAX }),
false,
);
CATEGORIES.forEach((categ, idx) => {
dataSet.categories.push({
id: idx + 1,
title: categ,
});
});
for (let i = 1; i <= MAX; i += 1) {
dataSet.movies.push({
id: i,
title: startCase(faker.lorem.words()),
released: faker.date.past(),
genre: generateGroup(faker.random.number({ min: 1, max: 3 }), () =>
faker.random.arrayElement(CATEGORIES),
),
rated: faker.random.arrayElement([
'G',
'PG',
'PG-13',
'R',
'NC-17',
'NR',
'UR',
]),
country: generateGroup(faker.random.number({ min: 1, max: 3 }), () =>
faker.random.arrayElement([
'USA',
'UK',
'Hong Kong',
'Canada',
'Australia',
]),
),
production: faker.company.companyName(),
runtime: faker.random.number({ min: 60, max: 180 }),
director: faker.name.findName(),
writer: faker.name.findName(),
actors: generateGroup(faker.random.number({ min: 4, max: 8 }), () =>
faker.name.findName(),
),
plot: faker.lorem.paragraph(),
poster:
'https://i.kinja-img.com/gawker-media/image/upload/b4xfydll6qktsk9dwxve.jpg',
cover: 'https://cdn.hipwallpaper.com/i/69/13/V07gqa.jpg',
rating: faker.finance.amount(4, 9, 1),
boxOffice: `$${faker.finance.amount(600000, 1000000000, 0)}`,
featured: featuredPool.indexOf(i) !== -1,
trailer:
'http://movietrailers.apple.com/movies/wb/wonderwoman/wonder-woman-trailer-5_h720p.mov',
});
}
fs.writeFile(
`${__dirname}/../backend/dataSet.json`,
JSON.stringify(dataSet, null, 2),
() => console.log('dataSet.json file generated'),
);
fs.writeFile(
`${__dirname}/../backend/activation.json`,
JSON.stringify({ devices: [] }, null, 2),
() => console.log('activation.json file generated'),
);
Getting the Express backed server ready
/backend/server.js is an Express backed server using the jsonGraphqlExpress
middleware. Those helpers imported at line 8 are used to read and write to the .json
files. We also simulate a network delay of half a second at line 16. The first 3 routes /me
, /activation-code
, /logout
are required by the authentication system of the Apple TV devices. The Express middleware between lines 68-78 is a firewall looking for uuid
variable in the request headers or in the query params. Finally, we load the jsonGraphqlExpress
middleware and start the GraphQL server.
const express = require('express');
const cors = require('cors');
const jsonGraphqlExpress = require('json-graphql-server').default;
const ip = require('ip');
const get = require('lodash.get');
const randomstring = require('random-string');
const { isActivated, insertActivation, logout, getMe } = require('./helpers');
const db = require('./db');
const PORT = 3100;
const IP = ip.address();
const app = express();
const DELAY = 500;
app.use((req, res, next) => setTimeout(next, DELAY));
app.use(cors());
app.get('/me', (req, res) => {
const uuid = get(req, 'headers.uuid', null);
if (!uuid) {
res.sendStatus(400);
} else {
getMe(uuid, me => {
if (!me) {
res.sendStatus(401);
} else {
res.json(me);
}
});
}
});
app.get('/activation-code', (req, res) => {
const uuid = get(req, 'headers.uuid', null);
if (!uuid) {
res.sendStatus(400);
} else {
const activationCode = randomstring({ length: 6 }).toUpperCase();
const newDevice = {
activationCode,
uuid,
activated: false,
};
insertActivation(newDevice, () => {
res.json(activationCode);
});
}
});
app.get('/logout', (req, res) => {
const uuid = get(req, 'headers.uuid', null);
if (!uuid) {
res.sendStatus(400);
} else {
logout(uuid, result => {
if (!result) {
res.sendStatus(400);
} else {
res.sendStatus(204);
}
});
}
});
app.use((req, res, next) => {
const uuidHeaders = get(req, 'headers.uuid', null);
const uuidParams = get(req, 'query.uuid', null);
const uuid = uuidHeaders || uuidParams;
if (uuid && isActivated(uuid)) {
next();
} else {
res.sendStatus(401);
}
});
app.use('/graphql', jsonGraphqlExpress(db));
app.listen(PORT, () => {
console.log(`GraphQL server is running on http://${IP}:${PORT}`);
});
First you need an activated UUID to authenticate. Please add to the /backend/activation.json
file one activated UUID
like this:
{
"devices": [
{
"id": 1,
"activationCode": "BJDRIT",
"uuid": "35814a01-f678-4ff0-8ccd-62263409138f",
"activated": true
}
]
}
Now you can play with the server using the GraphiQL interface using an URL like this http://192.168.0.2:3100/graphql?uuid=35814a01-f678-4ff0-8ccd-62263409138f
where 192.168.0.2
might be your connection allocated IP address. Check your network settings to find what your real IP address is.