|
|
@ -2,15 +2,33 @@ |
|
|
var express = require("express"); |
|
|
var express = require("express"); |
|
|
var _ = require("underscore"); |
|
|
var _ = require("underscore"); |
|
|
var bodyParser = require('body-parser'); |
|
|
var bodyParser = require('body-parser'); |
|
|
|
|
|
var util = require('util'); |
|
|
|
|
|
|
|
|
// ExpressJS Setup
|
|
|
// ExpressJS Setup
|
|
|
var app = express(); |
|
|
var app = express(); |
|
|
var router = express.Router(); |
|
|
var router = express.Router(); |
|
|
var port = 8080; |
|
|
var port = 8080; |
|
|
|
|
|
|
|
|
// Our global list of "Things"
|
|
|
// Default config
|
|
|
var things = { }; |
|
|
var config = { |
|
|
var counter = 1; |
|
|
"things": { |
|
|
|
|
|
"state": { |
|
|
|
|
|
"storage": {}, |
|
|
|
|
|
"counter": 1 |
|
|
|
|
|
}, |
|
|
|
|
|
"config": { |
|
|
|
|
|
"fields": { |
|
|
|
|
|
"name": { "required": true }, |
|
|
|
|
|
"price": { "required": true } |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
var admin_endpoints = [ |
|
|
|
|
|
{ "url": "/debug/state", "verbs": [ "GET" ] }, |
|
|
|
|
|
{ "url": "/config/", "verbs": [ "GET" ] } |
|
|
|
|
|
]; |
|
|
|
|
|
|
|
|
// Log every request
|
|
|
// Log every request
|
|
|
router.use(function (req,res,next) { |
|
|
router.use(function (req,res,next) { |
|
|
@ -18,14 +36,38 @@ router.use(function (req,res,next) { |
|
|
console.log("%s %s => %d", req.method, req.originalUrl, res.statusCode); |
|
|
console.log("%s %s => %d", req.method, req.originalUrl, res.statusCode); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// Dump the current state
|
|
|
|
|
|
router.get("/debug/state",function(req,res){ |
|
|
|
|
|
success(res, 200, |
|
|
|
|
|
_.mapObject(config, (val, key) => { |
|
|
|
|
|
return val.state; |
|
|
|
|
|
}) |
|
|
|
|
|
); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// Dump the current config
|
|
|
|
|
|
router.get("/config",function(req,res){ |
|
|
|
|
|
success(res, 200, |
|
|
|
|
|
_.mapObject(config, (val, key) => { |
|
|
|
|
|
return val.config; |
|
|
|
|
|
}) |
|
|
|
|
|
); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
// Any GET on / ends up with a nice documentation as JSON
|
|
|
// Any GET on / ends up with a nice documentation as JSON
|
|
|
router.get("/",function(req,res){ |
|
|
router.get("/",function(req,res){ |
|
|
var response = { |
|
|
var response = { |
|
|
name: "API Mockup", |
|
|
name: "API Mockup", |
|
|
description: "A simple API Mockup tool", |
|
|
description: "A simple API Mockup tool", |
|
|
endpoints: { |
|
|
endpoints: _.chain(config) |
|
|
things: "/things/" |
|
|
.map((item, key) => { |
|
|
}, |
|
|
return { |
|
|
|
|
|
"url": util.format("/%s/", key), |
|
|
|
|
|
"verbs": [ "GET", "POST", "PUT", "DELETE" ] |
|
|
|
|
|
}; |
|
|
|
|
|
}) |
|
|
|
|
|
.union(admin_endpoints) |
|
|
|
|
|
.value(), |
|
|
documentation: { |
|
|
documentation: { |
|
|
"GitHub": "https://github.com/nmasse-itix/API-Mockup.git" |
|
|
"GitHub": "https://github.com/nmasse-itix/API-Mockup.git" |
|
|
} |
|
|
} |
|
|
@ -34,61 +76,85 @@ router.get("/",function(req,res){ |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
// Get all things
|
|
|
// Get all things
|
|
|
router.get("/things",function(req,res){ |
|
|
router.get("/:object/",function(req,res){ |
|
|
success(res, 200, _.values(things)); |
|
|
var resource = req.params.object; |
|
|
|
|
|
if (! (resource in config)) { |
|
|
|
|
|
return error(res, 400, util.format("There is no resource '%s', try one of those resources : %s", resource, _.keys(config).join(", "))); |
|
|
|
|
|
} |
|
|
|
|
|
success(res, 200, _.values(config[resource].state.storage)); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
// Get a thing
|
|
|
// Get a thing
|
|
|
router.get("/things/:id",function(req,res){ |
|
|
router.get("/:object/:id",function(req,res){ |
|
|
|
|
|
var resource = req.params.object; |
|
|
|
|
|
if (! (resource in config)) { |
|
|
|
|
|
return error(res, 400, util.format("There is no resource '%s', try one of those resources : %s", resource, _.keys(config).join(", "))); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
var id = req.params.id; |
|
|
var id = req.params.id; |
|
|
if (! (id in things)) { |
|
|
if (! (id in config[resource].state.storage)) { |
|
|
return error(res, 404, "No thing with this id"); |
|
|
return error(res, 404, util.format("No such resource '%s' with id '%s' !", resource, id)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
success(res, 200, things[id]); |
|
|
success(res, 200, config[resource].state.storage[id]); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
// Create a thing
|
|
|
// Create a thing
|
|
|
router.post("/things",function(req,res){ |
|
|
router.post("/:object/",function(req,res){ |
|
|
|
|
|
var resource = req.params.object; |
|
|
|
|
|
if (! (resource in config)) { |
|
|
|
|
|
return error(res, 400, util.format("There is no resource '%s', try one of those resources : %s", resource, _.keys(config).join(", "))); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
var thing = req.body; |
|
|
var thing = req.body; |
|
|
if (thing == null) { |
|
|
if (thing == null) { |
|
|
return error(res, 400, "No body sent !"); |
|
|
return error(res, 400, "No body sent !"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
thing.id = counter++; |
|
|
thing.id = config[resource].state.counter++; |
|
|
things[thing.id] = thing; |
|
|
config[resource].state.storage[thing.id] = thing; |
|
|
success(res, 201, thing); |
|
|
success(res, 201, thing); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
// Delete a thing
|
|
|
// Delete a thing
|
|
|
router.delete("/things/:id",function(req,res){ |
|
|
router.delete("/:object/:id",function(req,res){ |
|
|
|
|
|
var resource = req.params.object; |
|
|
|
|
|
if (! (resource in config)) { |
|
|
|
|
|
return error(res, 400, util.format("There is no resource '%s', try one of those resources : %s", resource, _.keys(config).join(", "))); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
var id = req.params.id; |
|
|
var id = req.params.id; |
|
|
if (! (id in things)) { |
|
|
if (! (id in config[resource].state.storage)) { |
|
|
return error(res, 404, "No thing with this id"); |
|
|
return error(res, 404, util.format("No such resource '%s' with id '%s' !", resource, id)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var thing = things[id]; |
|
|
var thing = config[resource].state.storage[id]; |
|
|
delete things[id] |
|
|
delete config[resource].state.storage[id] |
|
|
success(res, 202, thing); |
|
|
success(res, 202, thing); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
// Update a thing
|
|
|
// Update a thing
|
|
|
router.put("/things/:id",function(req,res){ |
|
|
router.put("/:object/:id",function(req,res){ |
|
|
|
|
|
var resource = req.params.object; |
|
|
|
|
|
if (! (resource in config)) { |
|
|
|
|
|
return error(res, 400, util.format("There is no resource '%s', try one of those resources : %s", resource, _.keys(config).join(", "))); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
var thing = req.body; |
|
|
var thing = req.body; |
|
|
if (thing == null) { |
|
|
if (thing == null) { |
|
|
return error(res, 400, "No body sent !"); |
|
|
return error(res, 400, "No body sent !"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
var id = req.params.id; |
|
|
var id = req.params.id; |
|
|
if (! (id in things)) { |
|
|
if (! (id in config[resource].state.storage)) { |
|
|
return error(res, 404, "No thing with this id"); |
|
|
return error(res, 404, util.format("No such resource '%s' with id '%s' !", resource, id)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (thing.id != id) { |
|
|
if (thing.id != id) { |
|
|
return error(res, 400, "The id cannot be updated"); |
|
|
return error(res, 400, util.format("The id cannot be updated: '%s' vs '%s'", thing.id, id)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
things[id] = thing; |
|
|
config[resource].state.storage[id] = thing; |
|
|
success(res, 202, thing); |
|
|
success(res, 202, thing); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
@ -108,7 +174,7 @@ app.use("*",function(req,res){ |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
// Start the HTTP Server
|
|
|
// Start the HTTP Server
|
|
|
app.listen(port,function(){ |
|
|
var server = app.listen(port,function(){ |
|
|
console.log("API Mockup listening at port %d", port); |
|
|
console.log("API Mockup listening at port %d", port); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
@ -127,3 +193,5 @@ function success(res, code, response) { |
|
|
.type("application/json") |
|
|
.type("application/json") |
|
|
.send(JSON.stringify(response)); |
|
|
.send(JSON.stringify(response)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
module.exports = server; // Export the expressJS server object, to be used in unit tests
|
|
|
|