yarn add @soufantech/queopsor
npm install @soufantech/queopsThe example below demonstrates how filters can be set up for querying an "event" (like in the sense of a "show" or "festival").
Examples of possible queries that can go into the querystring URI are:
event_date=bet:2020..2020-11-15- any event between 2020-01-01T00:00:00 and 2020-11-15T00:00:00. The operatornbetcould be used in place ofbetas well.capacity=gt:1000- any event with capacity greater than 1000. The operatorsgte,lt,lte,neandeqcould have been used in place ofgtas well.capacity=asc:1- order the results by capacity in ascendant order. The operatordesccould be used in place ofascas well.genre=in:rock,folk,blues- any event which genre is rock, folk or blues. The operatornincould have been used in place ofinas well.offset=3- paginates the results.limit=10- limits the results.name=spring- brings any event that contains the substring "spring" in its title or description.exclude=description,capacity- excludes the "description" and "capacitity" properties from the returned result.
All the above queries MAY be put together in one single query to narrow down the results, obeying a disjunctive logic (AND): event_date=bet:2020..2020-11-15&capacity=gt:1000&capacity=asc:1&genre=in:rock,folk,blues&offset=3&limit=10&name=spring&exclude=description,capacity
Here is how it can be set up:
// Set up a QuerySchema object somewhere in your project.
// (this must be done only once during the lifetime of your app).
import { QuerySchema, Q } from '@soufantech/queops';
// The schema describes the possible filters in your query string, how
// their values are parsed and constrained. The presence of a field in
// the schema only makes it aknowledgeable when que query is processed,
// it does not state that the field is in anyway required.
const schema = new QuerySchema({
event_date: rangeDate({
bindingName: 'eventDate',
}),
capacity: [logicalInt(), queryOrder()]
genre: [stringElement(), queryOrder()],
limit: queryLimit({
max: 50,
defaultValue: 25,
}),
offset: queryOffset(),
populate: queryPopulate({
acceptedElements(['location'])
}),
name: querySearch(),
exclude: queryExclude({
minElements: 1, // if present, must contain at least one element
acceptedElements: ['description', 'capacity', 'genre'], // allow callers to exclude only the 'description', 'capacity', and 'genre' fields of the targeted resource
})
});
// Set up a query builder object somewhere in your project
// (this must be done only once during the lifetime of your app).
import { createQueryBuilder } from '@soufantech/queops';
const queryBuilder = createQueryBuilder({
populators: { // only needed if you're using `queryPopulate`
location: () => {
return {
model: Address,
as: 'location',
};
}
},
searches: { // only needed if you're using `queryPopulate`
name: ['title', 'description']
},
})
// Set 'query parser' to 'simple' on your express app configuration.
app.set('query parser', 'simple');
// In your request handler, process the querystring and pass
// the returned `action` to the query builder:
app.get('/promoters/:promoterId/events/', async (req, res) => {
// `action` is a function to be passed to the builder.
// `notices` is an array of `Notice` objects, that may
// contain warnings of possible non-desirable behaviours
// assumed by the processor, such as the use of a default
// value or that a query will not be applied due
// to some constraint.
const { action, notices } = schema.process(req.query);
// These are some fixed query parameters that will be
// merged with the query built from que querystring.
const baseFindOptions = {
where: {
promoterId: req.params.promoterId
},
};
// baseFindOptions is optional
const findOptions = queryBuilder.build(action, baseFindOptions);
const events = await Event.findAll(findOptions);
// return notices along with the data, if desirable.
return res.json({ data: events, notices });
});- chore: set up semantic-release.
Built with ❤︎ by query string experts at SouFan