在REST中查询时,挂钩太多了。有任何想法吗?

时间:2018-03-01 07:27:13

标签: feathersjs

我刚刚开始使用羽毛来构建REST服务器。我需要你的帮助来查询提示。文件说

  

通过REST URL使用时,所有查询值都是字符串。根据服务的不同,params.query中的值可能必须在before hook中转换为正确的类型。 (https://docs.feathersjs.com/api/databases/querying.html

,这让我很困惑。 find({query: {value: 1} })的意思是value === "1"而不是value === 1?以下是令我困惑的示例客户端代码:

const feathers = require('@feathersjs/feathers')
const fetch = require('node-fetch')
const restCli = require('@feathersjs/rest-client')
const rest = restCli('http://localhost:8888')
const app = feathers().configure(rest.fetch(fetch))
async function main () {
  const Items = app.service('myitems')
  await Items.create( {name:'one', value:1} )

  //works fine. returns [ { name: 'one', value: 1, id: 0 } ]
  console.log(await Items.find({query:{ name:"one" }}))

  //wow!  no data returned. []
  console.log(await Items.find({query:{ value:1 }})) // []
}
main()

服务器端代码在这里:

const express = require('@feathersjs/express')
const feathers = require('@feathersjs/feathers')
const memory = require('feathers-memory')
const app = express(feathers())
            .configure(express.rest())
            .use(express.json())
            .use(express.errorHandler())
            .use('myitems', memory())
app.listen(8888)
.on('listening',()=>console.log('listen on 8888'))

我已经制作了钩子,它工作得很好,但它太缺乏了,我想我错过了什么。有什么想法吗?

钩子代码:

app.service('myitems').hooks({
  before: { find:  async (context) => {
    const value = context.params.query.value
    if (value) context.params.query.value = parseInt(value)
    return context
    }
  }
})

1 个答案:

答案 0 :(得分:1)

此行为取决于您使用的数据库和ORM。一些具有架构(如feathers-mongoosefeathers-sequelizefeathers-knex)的内容会自动转换这样的值。

Feathers本身并不知道您的数据格式,大多数适配器(如您在此处使用的feathers-memory)都进行了严格的比较,因此必须进行转换。解决这个问题的常用方法是创建一些可重用的钩子(而不是每个场的一个),如下所示:

const queryToNumber = (...fields) => {
  return context => {
    const { params: { query = {} } } = context;

    fields.forEach(field => {
      const value = query[field];
      if(value) {
        query[field] = parseInt(value, 10)
      }
    });
  }
}

app.service('myitems').hooks({
  before: {
    find: [
      queryToNumber('age', 'value')
    ]
  }
});

或使用JSON schema之类的内容,例如通过validateSchema common hook