commit 8c7d93e11b5c26934cb58abc98e3b6b1a2678d31 Author: Nicolas Massé Date: Mon Jun 19 21:21:52 2017 +0200 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9dddb3e --- /dev/null +++ b/.gitignore @@ -0,0 +1,57 @@ +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..6b1d0bf --- /dev/null +++ b/.npmignore @@ -0,0 +1 @@ +LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3153fe0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Nicolas MASSE + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/package.json b/package.json new file mode 100644 index 0000000..4ae9c82 --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "api-mockup", + "version": "0.0.1", + "description": "A simple API Mockup tool", + "main": "server.js", + "scripts": { + }, + "author": "Nicolas MASSE", + "repository": "https://github.com/nmasse-itix/API-Mockup.git", + "license": "MIT", + "dependencies": { + "body-parser": "^1.17.2", + "express": "latest", + "underscore": "^1.8.3" + } +} diff --git a/server.js b/server.js new file mode 100644 index 0000000..535a400 --- /dev/null +++ b/server.js @@ -0,0 +1,129 @@ +// Dependencies +var express = require("express"); +var _ = require("underscore"); +var bodyParser = require('body-parser'); + +// ExpressJS Setup +var app = express(); +var router = express.Router(); +var port = 8080; + +// Our global list of "Things" +var things = { }; +var counter = 1; + +// Log every request +router.use(function (req,res,next) { + next(); + console.log("%s %s => %d", req.method, req.originalUrl, res.statusCode); +}); + +// Any GET on / ends up with a nice documentation as JSON +router.get("/",function(req,res){ + var response = { + name: "API Mockup", + description: "A simple API Mockup tool", + endpoints: { + things: "/things/" + }, + documentation: { + "GitHub": "https://github.com/nmasse-itix/API-Mockup.git" + } + }; + success(res, 200, response); +}); + +// Get all things +router.get("/things",function(req,res){ + success(res, 200, _.values(things)); +}); + +// Get a thing +router.get("/things/:id",function(req,res){ + var id = req.params.id; + if (! (id in things)) { + return error(res, 404, "No thing with this id"); + } + + success(res, 200, things[id]); +}); + +// Create a thing +router.post("/things",function(req,res){ + var thing = req.body; + if (thing == null) { + return error(res, 400, "No body sent !"); + } + + thing.id = counter++; + things[thing.id] = thing; + success(res, 201, thing); +}); + +// Delete a thing +router.delete("/things/:id",function(req,res){ + var id = req.params.id; + if (! (id in things)) { + return error(res, 404, "No thing with this id"); + } + + var thing = things[id]; + delete things[id] + success(res, 202, thing); +}); + +// Update a thing +router.put("/things/:id",function(req,res){ + var thing = req.body; + if (thing == null) { + return error(res, 400, "No body sent !"); + } + + var id = req.params.id; + if (! (id in things)) { + return error(res, 404, "No thing with this id"); + } + + if (thing.id != id) { + return error(res, 400, "The id cannot be updated"); + } + + things[id] = thing; + success(res, 202, thing); +}); + +// +// Please find below the plumbing code +// + +// Register the JSON Parser for POST and PUT requests +app.use(bodyParser.json()); + +// Register the router +app.use("/",router); + +// 404 Handler (Not Found) +app.use("*",function(req,res){ + error(res, 404, "Not found"); +}); + +// Start the HTTP Server +app.listen(port,function(){ + console.log("API Mockup listening at port %d", port); +}); + +function error(res, code, message) { + var response = { + status: code, + message: message + }; + return res.status(code) + .type("application/json") + .send(JSON.stringify(response)); +} + +function success(res, code, response) { + return res.status(code) + .type("application/json") + .send(JSON.stringify(response)); +}