mirror of
https://github.com/typicode/json-server.git
synced 2025-07-28 12:43:18 +08:00
Add route GET /resources?_embed&_expand
This commit is contained in:
@ -8,11 +8,37 @@ module.exports = function (db, name) {
|
|||||||
// Create router
|
// Create router
|
||||||
var router = express.Router()
|
var router = express.Router()
|
||||||
|
|
||||||
|
// Embed function used in GET /name and GET /name/id
|
||||||
|
function embed (resource, e) {
|
||||||
|
e && [].concat(e)
|
||||||
|
.forEach(function (externalResource) {
|
||||||
|
if (db.object[externalResource]) {
|
||||||
|
var query = {}
|
||||||
|
var singularResource = pluralize.singular(name)
|
||||||
|
query[singularResource + 'Id'] = resource.id
|
||||||
|
resource[externalResource] = db(externalResource).where(query)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expand function used in GET /name and GET /name/id
|
||||||
|
function expand (resource, e) {
|
||||||
|
e && [].concat(e)
|
||||||
|
.forEach(function (innerResource) {
|
||||||
|
var plural = pluralize(innerResource)
|
||||||
|
if (db.object[plural]) {
|
||||||
|
var prop = innerResource + 'Id'
|
||||||
|
resource[innerResource] = db(plural).getById(resource[prop])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// GET /name
|
// GET /name
|
||||||
// GET /name?q=
|
// GET /name?q=
|
||||||
// GET /name?attr=&attr=
|
// GET /name?attr=&attr=
|
||||||
// GET /name?_end=&*
|
// GET /name?_end=&
|
||||||
// GET /name?_start=&_end=&*
|
// GET /name?_start=&_end=&
|
||||||
|
// GET /name?_embed=&_expand=
|
||||||
function list (req, res, next) {
|
function list (req, res, next) {
|
||||||
|
|
||||||
// Filters list
|
// Filters list
|
||||||
@ -29,12 +55,16 @@ module.exports = function (db, name) {
|
|||||||
var _sort = req.query._sort
|
var _sort = req.query._sort
|
||||||
var _order = req.query._order
|
var _order = req.query._order
|
||||||
var _limit = req.query._limit
|
var _limit = req.query._limit
|
||||||
|
var _embed = req.query._embed
|
||||||
|
var _expand = req.query._expand
|
||||||
delete req.query.q
|
delete req.query.q
|
||||||
delete req.query._start
|
delete req.query._start
|
||||||
delete req.query._end
|
delete req.query._end
|
||||||
delete req.query._sort
|
delete req.query._sort
|
||||||
delete req.query._order
|
delete req.query._order
|
||||||
delete req.query._limit
|
delete req.query._limit
|
||||||
|
delete req.query._embed
|
||||||
|
delete req.query._expand
|
||||||
|
|
||||||
if (q) {
|
if (q) {
|
||||||
|
|
||||||
@ -99,6 +129,14 @@ module.exports = function (db, name) {
|
|||||||
chain = chain.slice(_start, _start + _limit)
|
chain = chain.slice(_start, _start + _limit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// embed and expand
|
||||||
|
chain = chain
|
||||||
|
.cloneDeep()
|
||||||
|
.forEach(function (element) {
|
||||||
|
embed(element, _embed)
|
||||||
|
expand(element, _expand)
|
||||||
|
})
|
||||||
|
|
||||||
res.locals.data = chain.value()
|
res.locals.data = chain.value()
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
@ -111,43 +149,17 @@ module.exports = function (db, name) {
|
|||||||
var id = utils.toNative(req.params.id)
|
var id = utils.toNative(req.params.id)
|
||||||
var resource = db(name).getById(id)
|
var resource = db(name).getById(id)
|
||||||
|
|
||||||
// Filter empty params
|
|
||||||
function filter (p) {
|
|
||||||
return p && p.trim().length > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resource) {
|
if (resource) {
|
||||||
// Clone resource to avoid making changes to the underlying object
|
// Clone resource to avoid making changes to the underlying object
|
||||||
resource = _.cloneDeep(resource)
|
resource = _.cloneDeep(resource)
|
||||||
|
|
||||||
// Always use an array
|
|
||||||
_embed = [].concat(_embed)
|
|
||||||
_expand = [].concat(_expand)
|
|
||||||
|
|
||||||
// Embed other resources based on resource id
|
// Embed other resources based on resource id
|
||||||
// /posts/1?_embed=comments
|
// /posts/1?_embed=comments
|
||||||
_embed
|
embed(resource, _embed)
|
||||||
.filter(filter)
|
|
||||||
.forEach(function (otherResource) {
|
|
||||||
if (db.object[otherResource]) {
|
|
||||||
var query = {}
|
|
||||||
var singularResource = pluralize.singular(name)
|
|
||||||
query[singularResource + 'Id'] = id
|
|
||||||
resource[otherResource] = db(otherResource).where(query)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Expand inner resources based on id
|
// Expand inner resources based on id
|
||||||
// /posts/1?_expand=user
|
// /posts/1?_expand=user
|
||||||
_expand
|
expand(resource, _expand)
|
||||||
.filter(filter)
|
|
||||||
.forEach(function (innerResource) {
|
|
||||||
var plural = pluralize(innerResource)
|
|
||||||
if (db.object[plural]) {
|
|
||||||
var prop = innerResource + 'Id'
|
|
||||||
resource[innerResource] = db(plural).getById(resource[prop])
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
res.locals.data = resource
|
res.locals.data = resource
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
var request = require('supertest')
|
|
||||||
var assert = require('assert')
|
var assert = require('assert')
|
||||||
|
var _ = require('lodash')
|
||||||
|
var request = require('supertest')
|
||||||
var jsonServer = require('../../src/server')
|
var jsonServer = require('../../src/server')
|
||||||
|
|
||||||
/* global beforeEach, describe, it */
|
/* global beforeEach, describe, it */
|
||||||
@ -38,7 +39,7 @@ describe('Server', function () {
|
|||||||
]
|
]
|
||||||
|
|
||||||
db.refs = [
|
db.refs = [
|
||||||
{id: 'abcd-1234', url: 'http://example.com', postId: 1}
|
{id: 'abcd-1234', url: 'http://example.com', postId: 1, userId: 1}
|
||||||
]
|
]
|
||||||
|
|
||||||
db.deep = [
|
db.deep = [
|
||||||
@ -238,8 +239,36 @@ describe('Server', function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('GET /:resource?_embed=', function () {
|
||||||
|
it('should respond with corresponding resources and embedded resources', function (done) {
|
||||||
|
var posts = _.cloneDeep(db.posts)
|
||||||
|
posts[0].comments = [db.comments[0], db.comments[1]]
|
||||||
|
posts[1].comments = [db.comments[2], db.comments[3], db.comments[4]]
|
||||||
|
request(server)
|
||||||
|
.get('/posts?_embed=comments')
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(posts)
|
||||||
|
.expect(200, done)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('GET /:resource?_embed&_embed=', function () {
|
||||||
|
it('should respond with corresponding resources and embedded resources', function (done) {
|
||||||
|
var posts = _.cloneDeep(db.posts)
|
||||||
|
posts[0].comments = [db.comments[0], db.comments[1]]
|
||||||
|
posts[0].refs = [db.refs[0]]
|
||||||
|
posts[1].comments = [db.comments[2], db.comments[3], db.comments[4]]
|
||||||
|
posts[1].refs = []
|
||||||
|
request(server)
|
||||||
|
.get('/posts?_embed=comments&_embed=refs')
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(posts)
|
||||||
|
.expect(200, done)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('GET /:resource/:id?_embed=', function () {
|
describe('GET /:resource/:id?_embed=', function () {
|
||||||
it('should respond with corresponding resource and embedded other resource', function (done) {
|
it('should respond with corresponding resources and embedded resources', function (done) {
|
||||||
var posts = db.posts[0]
|
var posts = db.posts[0]
|
||||||
posts.comments = [db.comments[0], db.comments[1]]
|
posts.comments = [db.comments[0], db.comments[1]]
|
||||||
request(server)
|
request(server)
|
||||||
@ -251,7 +280,7 @@ describe('Server', function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('GET /:resource/:id?_embed=&_embed=', function () {
|
describe('GET /:resource/:id?_embed=&_embed=', function () {
|
||||||
it('should respond with corresponding resource and embedded other resources', function (done) {
|
it('should respond with corresponding resource and embedded resources', function (done) {
|
||||||
var posts = db.posts[0]
|
var posts = db.posts[0]
|
||||||
posts.comments = [db.comments[0], db.comments[1]]
|
posts.comments = [db.comments[0], db.comments[1]]
|
||||||
posts.refs = [db.refs[0]]
|
posts.refs = [db.refs[0]]
|
||||||
@ -263,6 +292,18 @@ describe('Server', function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('GET /:resource?_expand=', function () {
|
||||||
|
it('should respond with corresponding resource and expanded inner resources', function (done) {
|
||||||
|
var refs = _.cloneDeep(db.refs)
|
||||||
|
refs[0].post = db.posts[0]
|
||||||
|
request(server)
|
||||||
|
.get('/refs?_expand=post')
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(refs)
|
||||||
|
.expect(200, done)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('GET /:resource/:id?_expand=', function () {
|
describe('GET /:resource/:id?_expand=', function () {
|
||||||
it('should respond with corresponding resource and expanded inner resources', function (done) {
|
it('should respond with corresponding resource and expanded inner resources', function (done) {
|
||||||
var comments = db.comments[0]
|
var comments = db.comments[0]
|
||||||
@ -275,6 +316,19 @@ describe('Server', function () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('GET /:resource?_expand=&_expand', function () {
|
||||||
|
it('should respond with corresponding resource and expanded inner resources', function (done) {
|
||||||
|
var refs = _.cloneDeep(db.refs)
|
||||||
|
refs[0].post = db.posts[0]
|
||||||
|
refs[0].user = db.users[0]
|
||||||
|
request(server)
|
||||||
|
.get('/refs?_expand=post&_expand=user')
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(refs)
|
||||||
|
.expect(200, done)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('GET /:resource/:id?_expand=&_expand=', function () {
|
describe('GET /:resource/:id?_expand=&_expand=', function () {
|
||||||
it('should respond with corresponding resource and expanded inner resources', function (done) {
|
it('should respond with corresponding resource and expanded inner resources', function (done) {
|
||||||
var comments = db.comments[0]
|
var comments = db.comments[0]
|
||||||
|
Reference in New Issue
Block a user