Browse Source

API : Replace (PUT) in plural route and replace put with replace in singular route.

npm v0.2.4
pull/13/head
oof1lab 7 years ago
parent
commit
7f783a7347
  1. 3
      README.md
  2. BIN
      assets/log.gif
  3. 2
      lib/util/cmd.helper.js
  4. 59
      lib/xapi.js
  5. 3
      lib/xsql.js
  6. 2
      package.json
  7. 35
      tests/tests.js

3
README.md

@ -96,8 +96,9 @@ Root URL (localhost:3000/) returns all REST API urls for each table in schema.
## CRUD APIs Usual Suspects
* GET       /api/tableName
* POST      /api/tableName
* PUT       /api/tableName ( acts as REPLACE )
* GET       /api/tableName/:id
* PUT       /api/tableName/:id
* PATCH       /api/tableName/:id ( acts as UPDATE )
* GET       /api/tableName/findOne
* GET       /api/tableName/count
* GET       /api/tableName/:id/exists

BIN
assets/log.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

2
lib/util/cmd.helper.js

@ -11,7 +11,7 @@ program.on('--help', () => {
})
program
.version('0.2.3')
.version('0.2.4')
.option('-h, --host <n>', 'hostname')
.option('-d, --database <n>', 'database schema name')
.option('-u, --user <n>', 'username of database / root by default')

59
lib/xapi.js

@ -112,7 +112,6 @@ class Xapi {
/**************** START : setup routes for each table ****************/
let resources = [];
resources = this.mysql.getSchemaRoutes(true, '/api/');
@ -150,6 +149,11 @@ class Xapi {
.get(this.asyncMiddleware(this.read.bind(this)));
break;
case 'patch':
this.app.route(routes[i]['routeUrl'])
.patch(this.asyncMiddleware(this.patch.bind(this)));
break;
case 'update':
this.app.route(routes[i]['routeUrl'])
.put(this.asyncMiddleware(this.update.bind(this)));
@ -246,6 +250,7 @@ class Xapi {
}
/**
*
* @param req
@ -412,8 +417,22 @@ class Xapi {
}
async update(req, res) {
let query = 'REPLACE INTO ?? SET ?';
let params = [];
params.push(req.app.locals._tableName);
params.push(req.body);
var results = await this.mysql.exec(query, params);
res.status(200).json(results);
}
async patch(req, res) {
let query = 'UPDATE ?? SET ';
let keys = Object.keys(req.body);
@ -449,6 +468,44 @@ class Xapi {
}
// async update(req, res) {
//
// let query = 'UPDATE ?? SET ';
// let keys = Object.keys(req.body);
//
// // SET clause
// let updateKeys = '';
// for (let i = 0; i < keys.length; ++i) {
// updateKeys += keys[i] + ' = ? '
// if (i !== keys.length - 1)
// updateKeys += ', '
// }
//
// // where clause
// query += updateKeys + ' where '
// let clause = this.mysql.getPrimaryKeyWhereClause(req.app.locals._tableName,
// req.params.id.split('___'));
//
// if (!clause) {
// return res.status(400).send({
// error: "Table is made of composite primary keys - all keys were not in input"
// })
// }
//
// query += clause;
//
// // params
// let params = [];
// params.push(req.app.locals._tableName);
// params = params.concat(Object.values(req.body));
//
// let results = await this.mysql.exec(query, params);
// res.status(200).json(results);
//
//
// }
async delete(req, res) {
let query = 'DELETE FROM ?? WHERE ';

3
lib/xsql.js

@ -462,8 +462,9 @@ class Xsql {
routes.push(this.prepareRoute(internal, 'get', apiPrefix, tableName + '/findOne', 'findOne'))
routes.push(this.prepareRoute(internal, 'post', apiPrefix, tableName, 'create'))
routes.push(this.prepareRoute(internal, 'get', apiPrefix, tableName, 'list'))
routes.push(this.prepareRoute(internal, 'put', apiPrefix, tableName, 'update'))
routes.push(this.prepareRoute(internal, 'get', apiPrefix, tableName + '/:id', 'read'))
routes.push(this.prepareRoute(internal, 'put', apiPrefix, tableName + '/:id', 'update'))
routes.push(this.prepareRoute(internal, 'patch', apiPrefix, tableName + '/:id', 'patch'))
routes.push(this.prepareRoute(internal, 'delete', apiPrefix, tableName + '/:id', 'delete'))
routes.push(this.prepareRoute(internal, 'get', apiPrefix, tableName + '/:id/exists', 'exists'))

2
package.json

@ -1,6 +1,6 @@
{
"name": "xmysql",
"version": "0.2.3",
"version": "0.2.4",
"description": "One command to generate REST APIs for any MySql database",
"main": "index.js",
"scripts": {

35
tests/tests.js

@ -455,8 +455,36 @@ describe('xmysql : tests', function () {
return done();
});
});
it('PUT /api/productlines should PASS', function (done) {
var obj = {};
obj['productLine'] = 'Hyperloop'
obj['textDescription'] = 'Hyperloop is essentially a train system that ElonMusk calls \"a cross between ' +
'a Concorde, a railgun, and an air hockey table\". ' +
'It\'s based on the very high-speed transit (VHST) system proposed in 1972,' +
'which combines a magnetic levitation train and a low pressure transit tube.' +
'It evolves some of the original ideas of VHST, but it still uses tunnels' +
'and pods or capsules to move from place to place.'
//post to an url with data
agent.put('/api/productlines') //enter url
.send(obj) //postdata
.expect(200)//200 for success 4xx for failure
.end(function (err, res) {
// Handle /api/v error
if (err) {
return done(err);
}
//validate response
res.body['affectedRows'].should.be.equals(2)
return done();
});
});
it('POST /dynamic should PASS', function (done) {
@ -477,7 +505,6 @@ describe('xmysql : tests', function () {
}
//validate response
res.body.length.should.be.equals(5)
return done();
@ -537,7 +564,9 @@ describe('xmysql : tests', function () {
});
});
it('PUT /api/customers/:id should PASS', function (done) {
it('PATCH /api/productlines/Hyperloop should PASS', function (done) {
var obj = {};
@ -549,7 +578,7 @@ describe('xmysql : tests', function () {
'and pods or capsules to move from place to place.'
//post to an url with data
agent.put('/api/productlines/Hyperloop') //enter url
agent.patch('/api/productlines/Hyperloop') //enter url
.send(obj) //postdata
.expect(200)//200 for success 4xx for failure
.end(function (err, res) {

Loading…
Cancel
Save