Support OR in lists

This commit is contained in:
Typicode
2015-09-03 00:22:11 +02:00
parent f731f014f7
commit 9fc0ef5bce
5 changed files with 59 additions and 26 deletions

View File

@ -1,5 +1,21 @@
# Change Log
## [0.7.27][2015-09-02]
### Added
```bash
# Support OR
GET /posts?id=1&id2
GET /posts?category=javascript&category=html
```
## [0.7.26][2015-09-01]
### Added
- `GET /posts?embed=comments`
- `GET /posts?expand=user`
```bash
# Support embed and expand in lists
GET /posts?embed=comments
GET /posts?expand=user
```

View File

@ -74,10 +74,11 @@ To filter resources (use `.` to access deep properties)
```
GET /posts?title=json-server&author=typicode
GET /posts?id=1&id=2
GET /comments?author.name=typicode
```
To slice resources, add `_start` and `_end` or `_limit` (an `X-Total-Count` header is included in the response).
To slice resources, add `_start` and `_end` or `_limit` (an `X-Total-Count` header is included in the response)
```
GET /posts?_start=20&_end=30
@ -92,33 +93,33 @@ GET /posts?_sort=views&_order=DESC
GET /posts/1/comments?_sort=votes&_order=ASC
```
To make a full-text search on resources, add `q`.
To make a full-text search on resources, add `q`
```
GET /posts?q=internet
```
To embed resources, add `_embed`.
To include children resources, add `_embed`
```
GET /posts?_embed=comments
GET /posts/1?_embed=comments
```
To expand inner resources, add `_expand`.
To include parent resource, add `_expand`.
```
GET /comments?_expand=post
GET /comments/1?_expand=post
```
Returns database.
Returns database
```
GET /db
```
Returns default index file or serves `./public` directory.
Returns default index file or serves `./public` directory
```
GET /

View File

@ -41,9 +41,6 @@ module.exports = function (db, name) {
// GET /name?_embed=&_expand=
function list (req, res, next) {
// Filters list
var filters = {}
// Resource chain
var chain = db(name).chain()
@ -82,23 +79,24 @@ module.exports = function (db, name) {
}
// Add query parameters filters
// Convert query parameters to their native counterparts
for (var key in req.query) {
// don't take into account JSONP query parameters
Object.keys(req.query).forEach(function (key) {
// Don't take into account JSONP query parameters
// jQuery adds a '_' query parameter too
if (key !== 'callback' && key !== '_') {
filters[key] = utils.toNative(req.query[key])
}
}
// Always use an array, in case req.query is an array
var arr = [].concat(req.query[key])
// Filter
if (!_(filters).isEmpty()) {
for (var f in filters) {
// This syntax allow for deep filtering using lodash (i.e. a.b.c[0])
chain = chain.filter(f, filters[f])
chain = chain.filter(function (element) {
return arr
.map(utils.toNative)
.map(function (value) {
return _.matchesProperty(key, value)(element)
}).reduce(function (a, b) {
return a || b
})
})
}
}
})
// Sort
if (_sort) {

View File

@ -6,7 +6,9 @@ var request = require('supertest')
var rmrf = require('rimraf')
var pkg = require('../../package.json')
request = request('http://localhost:3000')
var PORT = 3100
request = request('http://localhost:' + PORT)
var tmpDir = path.join(__dirname, '../../tmp')
var dbFile = path.join(tmpDir, 'db.json')
@ -14,7 +16,7 @@ var routesFile = path.join(tmpDir, 'routes.json')
function cli (args) {
var bin = path.join(__dirname, '../..', pkg.bin)
return cp.spawn('node', [bin].concat(args), {
return cp.spawn('node', [bin, '-p', PORT].concat(args), {
stdio: 'inherit',
cwd: __dirname
})

View File

@ -95,6 +95,14 @@ describe('Server', function () {
.expect(200, done)
})
it('should support multiple filters', function (done) {
request(server)
.get('/comments?id=1&id=2')
.expect('Content-Type', /json/)
.expect([db.comments[0], db.comments[1]])
.expect(200, done)
})
it('should support deep filter', function (done) {
request(server)
.get('/deep?a.b=1')
@ -102,6 +110,14 @@ describe('Server', function () {
.expect([db.deep[0]])
.expect(200, done)
})
it('should ignore JSONP query parameters callback and _ ', function (done) {
request(server)
.get('/comments?callback=1&_=1')
.expect('Content-Type', /text/)
.expect(new RegExp(db.comments[0].body)) // JSONP returns text
.expect(200, done)
})
})
describe('GET /:resource?q=', function () {