![Oracle Drags Its Feet in the JavaScript Trademark Dispute](https://cdn.sanity.io/images/cgdhsj6q/production/919c3b22c24f93884c548d60cbb338e819ff2435-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
json-rules-engine
Advanced tools
The json-rules-engine npm package is a powerful tool for creating and executing business rules in JavaScript. It allows you to define rules in JSON format and evaluate them against a set of facts. This can be useful for a variety of applications, including decision-making systems, workflow automation, and more.
Defining Rules
You can define rules using JSON format. Each rule consists of conditions and an event. The conditions specify the criteria that need to be met, and the event specifies what happens when the conditions are met.
{"rules":[{"conditions":{"all":[{"fact":"temperature","operator":"greaterThanInclusive","value":100}]},"event":{"type":"highTemperature","params":{"message":"Temperature is too high!"}}}]}
Evaluating Rules
You can evaluate rules against a set of facts. If the facts meet the conditions specified in the rules, the corresponding event will be triggered.
{"facts":{"temperature":101},"engine":{"addRule":"rule","run":"facts"}}
Combining Multiple Conditions
You can combine multiple conditions using logical operators like 'all' and 'any'. This allows you to create complex rules that evaluate multiple criteria.
{"rules":[{"conditions":{"all":[{"fact":"temperature","operator":"greaterThanInclusive","value":100},{"fact":"humidity","operator":"lessThan","value":30}]},"event":{"type":"alert","params":{"message":"High temperature and low humidity!"}}}]}
nools is a rules engine for JavaScript that uses a domain-specific language (DSL) for defining rules. It is more powerful and flexible than json-rules-engine but has a steeper learning curve. It is suitable for complex rule-based systems.
A rules engine expressed in JSON
json-rules-engine
is a powerful, lightweight rules engine. Rules are composed of simple json structures, making them human readable and easy to persist. Performance controls and built-in caching mechanisms help make the engine sufficiently performant to handle most use cases.
ALL
and ANY
boolean operators, including recursive nestingequal
, notEqual
, in
, notIn
, lessThan
, lessThanInclusive
, greaterThan
, greaterThanInclusive
$ npm install json-rules-engine
An engine is composed of 4 basic building blocks: rules, rule conditions, rule actions, and facts.
Engine - executes rules, emits actions, and maintains state. Most applications will have a single instance.
let engine = new Engine()
Rule - contains a set of conditions and a single action. When the engine is run, each rule condition is evaluated. If the results are truthy, the rule's action is triggered.
let rule = new Rule({ priority: 25 }) // the higher the priority, the earlier the rule will run. default=1
Rule Condition - Each condition consists of a constant value, an operator, a fact, and (optionally) fact params. The operator compares the fact result to the value.
// engine will call the "new-years" method at runtime with "params" and compare the results to "true"
rule.setConditions({
fact: 'new-years',
params: {
calendar: 'gregorian'
}
operator: 'equal',
value: true
})
Rule Action - Actions are event emissions triggered by the engine when conditions are met. Actions must have a type property which acts as an identifier. Optionally, actions may also have params.
rule.setAction({
type: 'celebrate',
params: {
balloons: true,
cake: false
}
})
engine.on('celebrate', function (params) {
// handle action business logic
// params = { balloons: true, cake: false }
})
Fact - Methods or constants registered with the engine prior to runtime, and referenced within rule conditions. Each fact method is a pure function that may return a computed value or promise. As rule conditions are evaluated during runtime, they retrieve fact values dynamically and use the condition operator to compare the fact result with the condition value.
let fact = function(params, engine) {
// business logic for computing fact value based on params
return dayOfYearByCalendar(params.calendar)
}
engine.addFact('year', fact)
let Engine = require('json-rules-engine')
let engine = new Engine()
Rules are composed of two components: conditions and actions. Conditions are a set of requirements that must be met to trigger the rule's action. Actions are emitted as events and may subscribed to by the application (see step 4).
let action = {
type: 'young-adult-rocky-mnts',
params: { // optional
giftCard: 'amazon',
value: 50
}
}
let conditions = {
all: [
{
fact: 'age',
operator: 'greaterThanInclusive',
value: 18
}, {
fact: 'age',
operator: 'lessThanInclusive',
value: 25
},
any: [
{
fact: 'state',
params: {
country: 'us'
},
operator: 'equal',
value: 'colorado'
}, {
fact: 'state',
params: {
country: 'us'
},
operator: 'equal',
value: 'utah'
}
]
]
}
let rule = new Rule({ conditions, action})
engine.addRule(rule)
The example above demonstrates a rule that detects male users between the ages of 18 and 25.
More on rules can be found here
Facts are constants or pure functions that may return different results during run-time. Using the current example, if the engine were to be run, it would throw an error: "Undefined fact: 'age'". So let's define some facts!
/*
* Define the 'state' fact
*/
let stateFact = function(params, engine) {
// rule "params" value is passed to the fact
// other fact values accessible via engine.factValue()
return stateLookupByZip(params.country, engine.factValue('zip-code'))
}
engine.addFact('state', stateFact)
/*
* Define the 'age' fact
*/
let ageFact = function(params, engine) {
// facts may return a promise when performing asynchronous operations
// such as database calls, http requests, etc to gather data
return engine.factValue('userId').then((userId) => {
return db.getUser(userId)
}).then((user) => {
return user.age
})
}
engine.addFact('age', ageFact)
Now when the engine is run, it will call the methods above whenever it encounters the fact: "age"
or fact: "state"
properties.
Important: facts should be pure functions, meaning their values will always evaluate based on the params
argument. By establishing facts are pure functions, it allows the rules engine to cache results throughout a run()
; if the same fact is called multiple times with the same params
, it will trigger the computation once and cache the results for future calls. If fact caching not desired, this behavior can be turned off via the options; see the docs.
More on facts can be found here
When rule conditions are met, the application needs to respond to the action that is emitted.
// subscribe directly to the 'young-adult' action from Step 1
engine.on('young-adult', (params) => {
// params: {
// giftCard: 'amazon',
// value: 50
// }
})
// - OR -
// subscribe to any action emitted by the engine
engine.on('action', function (action, engine) {
// action: {
// type: "young-adult",
// params: { // optional
// giftCard: 'amazon',
// value: 50
// }
// }
})
Running an engine executes the rules, and fires off action events for conditions that were met. The fact results cache will be cleared with each run()
// evaluate the rules
engine.run()
// Optionally, constant facts may be provided
engine.run({ userId: 1 }) // any time a rule condition requires 'userId', '1' will be returned
// run() returns a promise
engine.run().then(() => {
console.log('all rules executed')
})
To see what the engine is doing under the hood, debug output can be turned on via:
DEBUG=json-rules-engine
FAQs
Rules Engine expressed in simple json
The npm package json-rules-engine receives a total of 0 weekly downloads. As such, json-rules-engine popularity was classified as not popular.
We found that json-rules-engine demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.