admin 管理员组

文章数量: 1086019

I want to make a API which have 5 optional query parameters, I want to know if there is a better way to handle this, right now I check each one of them with if conditions, which is kind of dirty! is there any way that I can handle all scenarios without using lot's of if conditions?

let songName = req.query.songName
let singerName = req.query.singerName
let albumName = req.query.albumName
let publishDate = req.query.publishDate

if(songName && singerName && albumName && publishDate) {
   const response = songs.filter(c => { 
      return c.songName === songName && c.singerName === singerName && c.albumName === albumName && c.publishDate === publishDate
   }
   res.send({
      "Data" : response
   })
}

if(songName && singerName && albumName && !publishDate) {
   const response = songs.filter(c => { 
      return c.songName === songName && c.singerName === singerName && c.albumName === albumName
   }
   res.send({
      "Data" : response
   })
}

if(songName && singerName && !albumName && publishDate) {
   const response = songs.filter(c => { 
      return c.songName === songName && c.singerName === singerName && c.publishDate === publishDate
   }
   res.send({
      "Data" : response
   })
}

if(songName && !singerName && albumName && publishDate) {
   const response = songs.filter(c => { 
      return c.songName === songName && c.albumName === albumName && c.publishDate === publishDate
   }
   res.send({
      "Data" : response
   })
}

if(!songName && singerName && albumName && publishDate) {
   const response = songs.filter(c => { 
      return c.singerName === singerName && c.albumName === albumName && c.publishDate === publishDate
   }
   res.send({
      "Data" : response
   })
}
.
.
.

I want to make a API which have 5 optional query parameters, I want to know if there is a better way to handle this, right now I check each one of them with if conditions, which is kind of dirty! is there any way that I can handle all scenarios without using lot's of if conditions?

let songName = req.query.songName
let singerName = req.query.singerName
let albumName = req.query.albumName
let publishDate = req.query.publishDate

if(songName && singerName && albumName && publishDate) {
   const response = songs.filter(c => { 
      return c.songName === songName && c.singerName === singerName && c.albumName === albumName && c.publishDate === publishDate
   }
   res.send({
      "Data" : response
   })
}

if(songName && singerName && albumName && !publishDate) {
   const response = songs.filter(c => { 
      return c.songName === songName && c.singerName === singerName && c.albumName === albumName
   }
   res.send({
      "Data" : response
   })
}

if(songName && singerName && !albumName && publishDate) {
   const response = songs.filter(c => { 
      return c.songName === songName && c.singerName === singerName && c.publishDate === publishDate
   }
   res.send({
      "Data" : response
   })
}

if(songName && !singerName && albumName && publishDate) {
   const response = songs.filter(c => { 
      return c.songName === songName && c.albumName === albumName && c.publishDate === publishDate
   }
   res.send({
      "Data" : response
   })
}

if(!songName && singerName && albumName && publishDate) {
   const response = songs.filter(c => { 
      return c.singerName === singerName && c.albumName === albumName && c.publishDate === publishDate
   }
   res.send({
      "Data" : response
   })
}
.
.
.
Share Improve this question asked Aug 11, 2018 at 9:02 Emad DehnaviEmad Dehnavi 3,4515 gold badges23 silver badges47 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 2

You could use the ternary operator to do this all in one query. If the parameter is defined you check for equality and else you just return true. This could look like this:

const response = songs.filter(c => {
    return (songName ? (c.songName === songName) : true) &&
           (singerName ? (c.singerName === singerName) : true) &&
           (albumName ? (c.albumName === albumName) : true);
});

res.send({
    "Data": response
})

I may find Lodash to be useful for this one:

const response = songs.filter(song => {
   return _.isEqual(req.query, _.pick(song, Object.keys(req.query)))
})

I suggest you to use Joi

It is very powerful library for javascript validations. You can make even conditional validations using it. See the plete docs.

I created basic schema for your scenario here.

// validation
const schema = Joi.object().keys({
    songName: Joi.string()
    singerName: Joi.string()
    albumName: Joi.string()
    publishDate: Joi.date()
});

const { error, value } = Joi.validate(req.query, schema, { abortEarly: false, allowUnknown: false });
if (error !== null) return res.send(400, { code: 400, message: "validation error", error: error.details });

It is easier to read and understand for other developers too. You can standardized the validations in the overall project.

本文标签: javascriptNodejsExpressBest practice to handle optional querystring parameters in APIStack Overflow