Skip to content

Commit

Permalink
Merge pull request #10 from nemtsov/feature/pr_8
Browse files Browse the repository at this point in the history
Fixes from qm3ster & NialBunting
  • Loading branch information
nemtsov committed Dec 14, 2019
2 parents 131ca24 + d8f335b commit 8c657f9
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 68 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
package-lock.json
53 changes: 29 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# Express Partial Response Middleware [![NPM version](https://badge.fury.io/js/express-partial-response.png)](http://badge.fury.io/js/express-partial-response)

This Express Middleware will allow you to send a subset of a JSON object
instead of an entire object from your HTTP services. To do so, your services
instead of the entire object from your HTTP services. To do so, your services
will begin accepting the `?fields=` query-string that, using a simple language,
will specify which fields and sub-feelds to keep and which to ignore.
will specify which fields and sub-fields to keep and which to ignore.

If you've used the Google APIs, provided a `?fields=` query-string to get a
[Partial Response](https://developers.google.com/+/api/#partial-responses),
and wanted to do the same for your own server, now you can do so with this
middleware.

*Underneath, this middleware uses [json-mask](https://github.com/nemtsov/json-mask).
Use it directly without this middleware if you need more flexibility.*
_Underneath, this middleware uses [json-mask](https://github.com/nemtsov/json-mask).
Use it directly without this middleware if you need more flexibility._

# Installation

Expand All @@ -22,26 +22,29 @@ npm install express-partial-response
# Usage

```js
var express = require('express')
, partialResponse = require('express-partial-response')
, app = express()
const express = require('express');
const partialResponse = require('express-partial-response');
const app = express();

app.use(partialResponse())
app.use(partialResponse());

app.get('/', function (res, res, next) {
app.get('/', (req, res) => {
res.json({
firstName: 'Mohandas'
, lastName: 'Gandhi'
, aliases: [{
firstName: 'Mahatma'
, lastName: 'Gandhi'
}, {
firstName: 'Bapu'
}]
})
})

app.listen(4000)
firstName: 'Mohandas',
lastName: 'Gandhi',
aliases: [
{
firstName: 'Mahatma',
lastName: 'Gandhi'
},
{
firstName: 'Bapu'
}
]
});
});

app.listen(4000);
```

Let's test it:
Expand Down Expand Up @@ -70,9 +73,11 @@ Look at [json-mask](https://github.com/nemtsov/json-mask) for the available synt
`query` specifies the query-string to use. Defaults to `fields`

```js
app.use(partialResponse({
query: 'filter'
}))
app.use(
partialResponse({
query: 'filter'
})
);
```

# License
Expand Down
11 changes: 11 additions & 0 deletions example/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "example",
"version": "1.0.0",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.17.1"
}
}
47 changes: 25 additions & 22 deletions example/server.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
var express = require('express')
, partialResponse = require('../')
, app = express()
const express = require('express');
const partialResponse = require('../');
const app = express();

app.use(partialResponse())
app.use(partialResponse());

app.get('/', function (res, res, next) {
app.get('/', (req, res) => {
res.json({
firstName: 'Mohandas'
, lastName: 'Gandhi'
, aliases: [{
firstName: 'Mahatma'
, lastName: 'Gandhi'
}, {
firstName: 'Bapu'
}]
})
})
firstName: 'Mohandas',
lastName: 'Gandhi',
aliases: [
{
firstName: 'Mahatma',
lastName: 'Gandhi'
},
{
firstName: 'Bapu'
}
]
});
});

app.listen(4000, function () {
var prefix = 'curl \'http://localhost:4000?fields=%s\''
console.log('Server runnong on :4000, try the following:');
console.log(prefix, '*')
console.log(prefix, 'lastName')
console.log(prefix, 'firstName,aliases(firstName)')
})
app.listen(4000, () => {
const prefix = "curl 'http://localhost:4000?fields=%s'";
console.log('Server running on :4000, try the following:');
console.log(prefix, '*');
console.log(prefix, 'lastName');
console.log(prefix, 'firstName,aliases(firstName)');
});
47 changes: 27 additions & 20 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,38 @@
var jsonMask = require('json-mask'),
compile = jsonMask.compile,
filter = jsonMask.filter;
const jsonMask = require('json-mask');

module.exports = function (opt) {
opt = opt || {};
function isBadCode(statusCode) {
return statusCode < 200 || statusCode >= 300;
}

function partialResponse(obj, fields) {
if (!fields) return obj;
return filter(obj, compile(fields));
}
module.exports = function(options = {}) {
options = { query: 'fields', ...options };

function wrap(resJson) {
return function(obj) {
const fields = this.req.query[options.query];

// deprecated API that are still supported in v4
if (arguments.length > 1) {
// res.json(obj, status)
if ('number' === typeof arguments[1] && !isBadCode(arguments[1])) {
return resJson(jsonMask(obj, fields), arguments[1]);
}

function wrap(orig) {
return function (obj) {
var param = this.req.query[opt.query || 'fields'];
if (1 === arguments.length) {
orig(partialResponse(obj, param));
} else if (2 === arguments.length) {
if ('number' === typeof arguments[1]) {
orig(arguments[1], partialResponse(obj, param));
} else {
orig(obj, partialResponse(arguments[1], param));
// res.json(status, obj)
if ('number' === typeof obj && !isBadCode(obj)) {
return resJson(obj, jsonMask(arguments[1], fields));
}

return resJson(...arguments);
}

return isBadCode(this.statusCode)
? resJson(...arguments)
: resJson(jsonMask(obj, fields));
};
}

return function (req, res, next) {
return function(req, res, next) {
if (!res.__isJSONMaskWrapped) {
res.json = wrap(res.json.bind(res));
if (req.jsonp) res.jsonp = wrap(res.jsonp.bind(res));
Expand Down
21 changes: 19 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@
"name": "express-partial-response",
"version": "0.3.4",
"description": "Express middleware for filtering-out parts of JSON responses based on the `fields` query-string.",
"dependencies": {
"json-mask": "^0.3.9"
},
"main": "index.js",
"keywords": [
"express",
"partial-response",
"filter",
"mask",
Expand All @@ -13,13 +17,26 @@
"query",
"json"
],
"dependencies": {
"json-mask": "0.3.8"
"engines": {
"node": ">=10"
},
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged"
}
},
"prettier": {
"singleQuote": true
},
"author": "nemtsov@gmail.com",
"license": "MIT",
"repository": {
"type": "git",
"url": "git://github.com/nemtsov/express-partial-response.git"
},
"devDependencies": {
"husky": "^3.1.0",
"prettier": "1.19.1",
"pretty-quick": "^2.0.1"
}
}

0 comments on commit 8c657f9

Please sign in to comment.