Body parameter in ArangoDB

53 views Asked by At

I wrote the following router in Foxx Microservices:

router.post('/PersonInformation', function (req, res) {
    const keys = db._query(aql`
    FOR p IN Personal
                FILTER (p.stateId IN ${req.queryParams.statePar} OR IS_NULL(${req.queryParams.statePar}))
                AND p.empDate >= TO_NUMBER(${req.queryParams.fromDatePar}) AND p.empDate <= TO_NUMBER(${req.queryParams.toDatePar})
                          RETURN p
  `);
  res.send(keys);
  })
  .queryParam('statePar', joi.array().default(null), 'State Parameter')
  .queryParam ('fromDatePar', joi.string().required(), 'FromDate Parameter')
  .queryParam('toDatePar', joi.string().required(), 'ToDate Parameter')
  .response(joi.array().items(
  joi.string().required()
  ).required(), 'List of entry keys.')
  .summary('List entry keys')
  .description('Assembles a list of keys of entries in the collection.');

How i can convert queryParam to body parameter. I used .body instead of .queryParam, but it does not answer. I also wrote the table as follows, but it still does not work:

router.post('/PersonInformation', function (req, res) {
  const distributorIdPar = req.body;
  const cityPar = req.body;
  const productIdPar = req.body;
  const fromDatePar = req.body;
  const toDatePar = req.body;
  const keys = db._query(aql`
    const keys = db._query(aql`
    FOR p IN Personal
                FILTER (p.stateId IN ${req.body.statePar} OR IS_NULL(${req.body.statePar}))
                AND p.empDate >= TO_NUMBER(${req.body.fromDatePar}) AND p.empDate <= TO_NUMBER(${req.body.toDatePar})
                          RETURN p
  `);
  res.send(keys);
  })
  .response(joi.array().items(
  joi.string().required()
  ).required(), 'List of entry keys.')
  .summary('List entry keys')
  .description('Assembles a list of keys of entries in the collection.');
1

There are 1 answers

0
CodeManX On BEST ANSWER

You have a duplicate line const keys = db._query(aql` that breaks the syntax. Furthermore, you are not setting .body(joi.object()) or .body(['application/json']), which leads to req.body being a Buffer:

If no body has been defined for the current route, the value will be identical to rawBody – docs

You also assign req.body to various variables but don't actually use them.

I would assign the body parameters to local variables using destructuring for the guaranteed values, and use a regular assignment for statePar so that it can default to null if it is omitted from the body. Furthermore, I would enforce numeric values for fromDatePar and toDatePar (note that this requires strict() in joi or it will happily accept number strings) and remove TO_NUMBER() from the query. Below code accepts either an array of strings for statePar or expects the attribute to not be present. It disallows "statePar":null, "statePar":[], and "statePar":[null], but you could change that if desired.

'use strict';
const joi = require('joi');
const { db, aql } = require('@arangodb');
const createRouter = require('@arangodb/foxx/router');
const router = createRouter();

router.post('/PersonInformation', function (req, res) {
  const statePar = req.body.statePar || null;
  const { fromDatePar, toDatePar } = req.body;
  const keys = db._query(aql`
    FOR p IN Personal
      FILTER (p.stateId IN ${statePar} OR IS_NULL(${statePar}))
      AND p.empDate >= ${fromDatePar} AND p.empDate <= ${toDatePar}
      RETURN p
  `);
  res.send(keys);
})
.body(joi.object({
  statePar: joi.array().items(
    joi.string().required()
  ),
  fromDatePar: joi.number().required(),
  toDatePar: joi.number().required(),
}).required().strict(), 'Search parameters')
.response(joi.array().items(
  joi.string().required()
).required(), 'List of entry keys.')
.summary('List entry keys')
.description('Assembles a list of keys of entries in the collection.');

module.context.use(router);