json api server

master
Tudor Stanciu 2020-04-11 20:01:31 +03:00
parent 263ecdf14e
commit bf2eef21f2
4 changed files with 189 additions and 1 deletions

View File

@ -2,7 +2,10 @@
"name": "ps-redux",
"description": "React and Redux Pluralsight course by Cory House",
"scripts": {
"start": "webpack-dev-server --config webpack.config.dev.js --port 3000"
"start": "run-p start:dev start:api",
"start:dev": "webpack-dev-server --config webpack.config.dev.js --port 3000",
"prestart:api": "node tools/createMockDb.js",
"start:api": "node tools/apiServer.js"
},
"dependencies": {
"bootstrap": "4.3.1",

81
tools/apiServer.js Normal file
View File

@ -0,0 +1,81 @@
/*
This uses json-server, but with the module approach: https://github.com/typicode/json-server#module
Downside: You can't pass the json-server command line options.
Instead, can override some defaults by passing a config object to jsonServer.defaults();
You have to check the source code to set some items.
Examples:
Validation/Customization: https://github.com/typicode/json-server/issues/266
Delay: https://github.com/typicode/json-server/issues/534
ID: https://github.com/typicode/json-server/issues/613#issuecomment-325393041
Relevant source code: https://github.com/typicode/json-server/blob/master/src/cli/run.js
*/
/* eslint-disable no-console */
const jsonServer = require("json-server");
const server = jsonServer.create();
const path = require("path");
const router = jsonServer.router(path.join(__dirname, "db.json"));
// Can pass a limited number of options to this to override (some) defaults. See https://github.com/typicode/json-server#api
const middlewares = jsonServer.defaults({
// Display json-server's built in homepage when json-server starts.
static: "node_modules/json-server/dist"
});
// Set default middlewares (logger, static, cors and no-cache)
server.use(middlewares);
// To handle POST, PUT and PATCH you need to use a body-parser. Using JSON Server's bodyParser
server.use(jsonServer.bodyParser);
// Simulate delay on all requests
server.use(function (req, res, next) {
setTimeout(next, 0);
});
// Declaring custom routes below. Add custom routes before JSON Server router
// Add createdAt to all POSTS
server.use((req, res, next) => {
if (req.method === "POST") {
req.body.createdAt = Date.now();
}
// Continue to JSON Server router
next();
});
server.post("/courses/", function (req, res, next) {
const error = validateCourse(req.body);
if (error) {
res.status(400).send(error);
} else {
req.body.slug = createSlug(req.body.title); // Generate a slug for new courses.
next();
}
});
// Use default router
server.use(router);
// Start server
const port = 3001;
server.listen(port, () => {
console.log(`JSON Server is running on port ${port}`);
});
// Centralized logic
// Returns a URL friendly slug
function createSlug(value) {
return value
.replace(/[^a-z0-9_]+/gi, "-")
.replace(/^-|-$/g, "")
.toLowerCase();
}
function validateCourse(course) {
if (!course.title) return "Title is required.";
if (!course.authorId) return "Author is required.";
if (!course.category) return "Category is required.";
return "";
}

12
tools/createMockDb.js Normal file
View File

@ -0,0 +1,12 @@
/* eslint-disable no-console */
const fs = require("fs");
const path = require("path");
const mockData = require("./mockData");
const { courses, authors } = mockData;
const data = JSON.stringify({ courses, authors });
const filepath = path.join(__dirname, "db.json");
fs.writeFile(filepath, data, function (err) {
err ? console.log(err) : console.log("Mock DB created.");
});

92
tools/mockData.js Normal file
View File

@ -0,0 +1,92 @@
const courses = [
{
id: 1,
title: "Securing React Apps with Auth0",
slug: "react-auth0-authentication-security",
authorId: 1,
category: "JavaScript"
},
{
id: 2,
title: "React: The Big Picture",
slug: "react-big-picture",
authorId: 1,
category: "JavaScript"
},
{
id: 3,
title: "Creating Reusable React Components",
slug: "react-creating-reusable-components",
authorId: 1,
category: "JavaScript"
},
{
id: 4,
title: "Building a JavaScript Development Environment",
slug: "javascript-development-environment",
authorId: 1,
category: "JavaScript"
},
{
id: 5,
title: "Building Applications with React and Redux",
slug: "react-redux-react-router-es6",
authorId: 1,
category: "JavaScript"
},
{
id: 6,
title: "Building Applications in React and Flux",
slug: "react-flux-building-applications",
authorId: 1,
category: "JavaScript"
},
{
id: 7,
title: "Clean Code: Writing Code for Humans",
slug: "writing-clean-code-humans",
authorId: 1,
category: "Software Practices"
},
{
id: 8,
title: "Architecting Applications for the Real World",
slug: "architecting-applications-dotnet",
authorId: 1,
category: "Software Architecture"
},
{
id: 9,
title: "Becoming an Outlier: Reprogramming the Developer Mind",
slug: "career-reboot-for-developer-mind",
authorId: 1,
category: "Career"
},
{
id: 10,
title: "Web Component Fundamentals",
slug: "web-components-shadow-dom",
authorId: 1,
category: "HTML5"
}
];
const authors = [
{ id: 1, name: "Cory House" },
{ id: 2, name: "Scott Allen" },
{ id: 3, name: "Dan Wahlin" }
];
const newCourse = {
id: null,
title: "",
authorId: null,
category: ""
};
// Using CommonJS style export so we can consume via Node (without using Babel-node)
module.exports = {
newCourse,
courses,
authors
};