var fs = require('fs'); // Filesystem var express = require('express'); // Express var bodyParser = require('body-parser'); // Data conversion, JSON parsing // Set up Express var app = express(); app.use(express.static("./static/")); // Serve static files from /static app.use(express.json()); // Parse JSON in requests // Posts route, return posts.json app.get("/api/posts", function(req, res) { res.json(JSON.parse(fs.readFileSync('./data/posts.json'))); }); // Posts route, digest incoming post app.post("/api/posts", function(req, res) { // Read in posts.json var postsFile = fs.readFileSync('./data/posts.json'); var posts = JSON.parse(postsFile); // Verify incoming post matches expected schema var incomingData = req.body; if (validatePost(incomingData)) { // Prepend the incoming post to the post list posts.unshift(incomingData); } else { // Complain that we haven't been given what we're expecting res.status(400).json({"error":"Failed to validate post"}); return; } // Try to save the updated posts object fs.writeFile('./data/posts.json', JSON.stringify(posts), (e) => { if (e) { // Tell the client we've hit a snag and dump the error to the console res.sendStatus(500); throw e; } }); // Tell the client all is good and that they shouldn't expect any content res.sendStatus(204); }); // About route, return about.json app.get("/api/about", (req, res) => { res.json(JSON.parse(fs.readFileSync('./data/about.json'))); }); // FAQ route, return faq.json app.get("/api/faq", (req, res) => { res.json(JSON.parse(fs.readFileSync('./data/faq.json'))); }); // Default route, serve static index.html and let AngularJS handle the remainder app.get("/*", (req, res) => { res.sendFile("./static/index.html", {root: __dirname}) }); // Start listening app.listen(8080, function() { console.log("Listening on port 8080"); }); // Verifies the post object conforms to the standard we're expecting // Each post should conform to the following template: // { // "title":"", // "author":"", // "date":0, // "tags":[ // "" // ], // "content":"" // } function validatePost(post) { try { // Check types of each expected property and assume they're there return (typeof post.title === "string" && typeof post.author === "string" && typeof post.date === "number" && Array.isArray(post.tags) && typeof post.content === "string"); } catch (e) { // Object clearly isn't what we're expecting return false; } }