Go API

This reference covers the Go packages for integrating DTRules into your applications.

Installation

go get github.com/dtrules/dtrules/go

Core Packages

session

High-level API for rule execution.

import "github.com/dtrules/dtrules/go/pkg/dtrules/session"

// Create a rule set
rs := session.NewRuleSet("MyRules")

// Load EDD
eddFile, _ := os.Open("EDD.xml")
rs.LoadEDD(eddFile)
eddFile.Close()

// Load decision tables
dtFile, _ := os.Open("DecisionTables.xml")
rs.LoadDecisionTables(dtFile)
dtFile.Close()

// Create session
sess, _ := rs.NewSession()
rsess := sess.(*session.RSession)

// Execute
rsess.Execute("Main")

entity

Entity data model.

import "github.com/dtrules/dtrules/go/pkg/dtrules/entity"

// Get entity by name
person := state.GetEntity("person")

// Get attribute
name, _ := person.GetAttribute("name")
age, _ := person.GetAttribute("age")

// Set attribute
person.SetAttribute("eligible", true)
person.SetAttribute("benefit_amount", 250.00)

// Work with arrays
members, _ := household.GetAttribute("members")
memberList := members.([]interface{})

interpreter

Low-level execution engine.

import "github.com/dtrules/dtrules/go/pkg/dtrules/interpreter"

// The interpreter uses a stack-based execution model
// Most users interact through the session package

Loading Rules

From Files

rs := session.NewRuleSet("MyRules")

// Load EDD
eddFile, err := os.Open("/path/to/rules/MyRules_edd.xml")
if err != nil {
    return err
}
defer eddFile.Close()
rs.LoadEDD(eddFile)

// Load decision tables
dtFile, err := os.Open("/path/to/rules/MyRules_dt.xml")
if err != nil {
    return err
}
defer dtFile.Close()
rs.LoadDecisionTables(dtFile)

From Directory

// Load all XML files from a directory
rs := session.NewRuleSet("MyRules")
err := rs.LoadFromDirectory("/path/to/rules/xml")
if err != nil {
    return err
}

Executing Rules

Basic Execution

sess, _ := rs.NewSession()
rsess := sess.(*session.RSession)

// Execute a decision table
err := rsess.Execute("Determine_Eligibility")
if err != nil {
    log.Printf("Execution error: %v", err)
}

With Tracing

rsess.SetTrace(true)
rsess.Execute("Main")
trace := rsess.GetTrace()
fmt.Println(trace)

Working with Entities

Getting Values

state := rsess.GetState()

// Get entity
app := state.GetEntity("application")

// Get primitive values
eligible, _ := app.GetBool("eligible")
amount, _ := app.GetFloat64("benefit_amount")
status, _ := app.GetString("status")
count, _ := app.GetInt("dependent_count")

// Get nested entity
household, _ := app.GetEntity("household")
head, _ := household.GetEntity("head")
headName, _ := head.GetString("name")

Setting Values

// Set primitive values
app.SetAttribute("eligible", true)
app.SetAttribute("benefit_amount", 250.00)
app.SetAttribute("status", "approved")

// Create new entity
person := state.CreateEntity("Person")
person.SetAttribute("name", "John Doe")
person.SetAttribute("age", 35)

// Add to array
household.AddToArray("members", person)

CLI Tool

# Build the CLI
go build -o dtrules ./cmd/dtrules

# List decision tables
./dtrules -rules /path/to/rules -list

# Validate rules
./dtrules -rules /path/to/rules -validate

# Execute
./dtrules -rules /path/to/rules -entry Main

# Execute with trace
./dtrules -rules /path/to/rules -entry Main -trace

Example: Service Integration

package eligibility

import (
    "github.com/dtrules/dtrules/go/pkg/dtrules/session"
)

type EligibilityService struct {
    ruleSet *session.RuleSet
}

func NewEligibilityService(rulesPath string) (*EligibilityService, error) {
    rs := session.NewRuleSet("Eligibility")
    if err := rs.LoadFromDirectory(rulesPath); err != nil {
        return nil, err
    }
    return &EligibilityService{ruleSet: rs}, nil
}

type Application struct {
    ApplicantName string
    ApplicantAge  int
    Income        float64
}

type Result struct {
    Eligible      bool
    Reason        string
    BenefitAmount float64
}

func (s *EligibilityService) Determine(app Application) (*Result, error) {
    sess, _ := s.ruleSet.NewSession()
    rsess := sess.(*session.RSession)

    // Set up input data
    state := rsess.GetState()
    appEntity := state.GetEntity("application")
    applicant := state.CreateEntity("Person")

    applicant.SetAttribute("name", app.ApplicantName)
    applicant.SetAttribute("age", app.ApplicantAge)
    applicant.SetAttribute("income", app.Income)
    appEntity.SetAttribute("applicant", applicant)

    // Execute rules
    if err := rsess.Execute("Determine_Eligibility"); err != nil {
        return nil, err
    }

    // Extract results
    eligible, _ := appEntity.GetBool("eligible")
    reason, _ := appEntity.GetString("reason_code")
    amount, _ := appEntity.GetFloat64("benefit_amount")

    return &Result{
        Eligible:      eligible,
        Reason:        reason,
        BenefitAmount: amount,
    }, nil
}

Performance Tips

  • Reuse RuleSet instances - they're thread-safe after loading
  • Create new RSession for each execution
  • Use value-based execution for high-throughput scenarios
  • Disable tracing in production unless needed

Next Steps