Skip to content

a rule engine package in golang, it helps you to isolate your rule based logic from your business logic.

License

Notifications You must be signed in to change notification settings

nurettintopal/rule

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nurettintopal - rule GitHub release
stars - rule forks - rule

Rule

a basic rule engine package in Golang

what is a rule engine?

Rules engines or rule expressions serve as pluggable software components which execute business rules that a business rules approach has externalized or separated from application code. This externalization or separation allows business users to modify the rules without the need for a big effort.

if you want to look into the details, follow this link, please.

usage

basic example

package main

import (
	"fmt"

	"github.com/nurettintopal/rule"
)

func main() {
	input := `{
		"country": "Turkey"
	}`

	rules := `{
	   "conditions":[
		  {
			 "any":[
				{
				   "field":"country",
				   "operator":"in",
				   "value": ["Turkey", "England"]
				}
			 ]
		  }
	   ]
	}`

	if rule.Execute(input, rules, nil) {
		fmt.Printf("Rules have been executed. it passed!")
	} else {
		fmt.Printf("Rules have been executed. it failed!")
	}
}

input:

{
  "country": "Turkey",
  "city": "Istanbul",
  "district": "Kadikoy",
  "population": 20000,
  "language": "Turkish"
}

rules:

{
  "conditions":[
    {
      "all":[
        {
          "field":"country",
          "operator":"equals",
          "value":"Turkey"
        },
        {
          "field":"city",
          "operator":"equals",
          "value":"Istanbul"
        },
        {
          "field":"district",
          "operator":"equals",
          "value":"Kadikoy"
        },
        {
          "field":"population",
          "operator":"equals",
          "value":20000.00
        },
        {
          "field":"population",
          "operator":"notEquals",
          "value":50000.00
        },
        {
          "field":"population",
          "operator":"lessThan",
          "value":21000.00
        },
        {
          "field":"population",
          "operator":"lessThanInclusive",
          "value":20000.00
        },
        {
          "field":"population",
          "operator":"greaterThan",
          "value":19000.00
        },
        {
          "field":"population",
          "operator":"greaterThanInclusive",
          "value":20000.00
        },
        {
          "field":"country",
          "operator":"in",
          "value":[
            "Turkey"
          ]
        },
        {
          "field":"country",
          "operator":"notIn",
          "value":[
            "Germany"
          ]
        }
      ],
      "any":[
        {
          "field":"country",
          "operator":"equals",
          "value":"England"
        },
        {
          "field":"city",
          "operator":"equals",
          "value":"London"
        },
        {
          "field":"population",
          "operator":"equals",
          "value":200000.00
        },
        {
          "field":"country",
          "operator":"equals",
          "value":"Turkey"
        },
        {
          "field":"city",
          "operator":"equals",
          "value":"Madrid"
        },
        {
          "field":"population",
          "operator":"equals",
          "value":1000.00
        }
      ]
    }
  ]
}

result:

Rules have been executed. it passed!

operators

operator meaning
equals equals to
notEquals not equal to
lessThan less than
greaterThan greater than
lessThanInclusive less than or equal to
greaterThanInclusive greater than or equal to
in in a list
notIn not in a list
startsWith starts with
endsWith ends with
contains contains
notContains not contains
regex contains any match of the regular expression pattern

how to add custom operator

it has been already supporting a few rules that can be used in your projects, but sometimes, you may need to use custom controls based on your own business rules. do not worry, if you need to add some additional control, you can do it easly. you need to create your own function, then, inject the function to the package, that is all.

input := `{
		"country": "Turkey",
		"city": "Istanbul",
		"district": "Kadikoy",
		"population": 2000000.00,
		"language": "Turkish"
	}`

rules := `{
	   "conditions":[
		  {
			 "all":[
				{
				   "field":"population",
				   "operator":"custom.eligible",
				   "value": true
				}
			 ]
		  }
	   ]
	}`

custom := map[string]rule.CustomOperation{
    "eligible": &CustomRuleEligible{},
}

if rule.Execute(input, rules, custom) {
    fmt.Printf("Rules have been executed. it passed!")
} else {
    fmt.Printf("Rules have been executed. it failed!")
}


// CustomOperation implementations
type CustomRuleEligible struct{}

func (o *CustomRuleEligible) Execute(input, value interface{}) interface{} {
	// your own logics & controls
	return true
}

how to add custom input

you need to send inputs that should be used for rules, but sometimes, you may need to use custom sources based on your own business rules. do not worry, if you need to add some additional sources for inputs, you can do it easly. you need to create your own function, then, inject the function to the package, that is all.

input := `{
		"country": "Turkey",
		"city": "Istanbul",
		"district": "Kadikoy",
		"population": 2000000.00,
		"language": "Turkish"
	}`

rules := `{
	   "conditions":[
		  {
			 "all":[
				{
				   "field":"external.score",
				   "operator":"greaterThan",
				   "value":4
				}
			 ]
		  }
	   ]
	}`

custom := map[string]rule.CustomOperation{
    "score":    &CustomCountryScore{},
}

if rule.Execute(input, rules, custom) {
    fmt.Printf("Rules have been executed. it passed!")
} else {
    fmt.Printf("Rules have been executed. it failed!")
}


// CustomOperation implementations
type CustomCountryScore struct{}

func (o *CustomCountryScore) Execute(input, value interface{}) interface{} {
    // your own logics & controls
    return "your value that is retrieved from a different source"
}

dependencies

  • Go

contributing

  • if you want to add anything, contributions are welcome.
  • Open a pull request that has your explanations

license

leaderboard is open-sourced software licensed under the MIT license.

About

a rule engine package in golang, it helps you to isolate your rule based logic from your business logic.

Topics

Resources

License

Stars

Watchers

Forks