LoginSignup
0

More than 3 years have passed since last update.

GoのBRMS(Grule)でビジネスロジックを管理する

Posted at

この記事は、株式会社アトラエ アドベントカレンダー21日目の記事です。

BRMS

ビジネスルールをアプリケーションと切り離して管理するためのもので、業務要件やビジネスの制約をルールとして定義してアプリケーションで実行することができます。

BRMSを調査した背景

レガシーなサービスの大規模なリファクタを行っているのですが、その時に頭を悩ます問題なのが、 何に使われているデータなのか分からない ものと遭遇することです。
状態を表すカラムが存在し、さらにパッと見同じようなカラムが複数存在したり、抽象的な名前だったりで、コードを読みながら挙動を確認して理解するという調査の過程が作業時間のほとんどを占めています。
データの構造を理解した上でリファクタと同時にテストコードを書いていますが、進めるに連れて過去にリファクタした機能のビジネスルールが記憶から薄れていきました。
ビジネスルールをテストコードで確認するのはいささか辛いなと思い(ドキュメントにまとめてないのがいけないのですが。。。)、BRMSを用いてビジネスルールをまとめつつリファクタできないかと調査することにしました。

Gruleの使い方

Articleに is_openstatus というデータがある場合の例、、、

Ruleを定義する

salience は優先度を定義しています。複数ある場合値が大きい方が優先されます。

article.grl

rule CheckActive "Check Active" salience 100 {
    when
        A.IsOpen && A.Status ==  1
    then
        A.IsActive = true
}

公開状態を表す値として isActive を用意しています。

import (
    "fmt"
    "github.com/hyperjumptech/grule-rule-engine/ast"
    "github.com/hyperjumptech/grule-rule-engine/builder"
    "github.com/hyperjumptech/grule-rule-engine/engine"
    "github.com/hyperjumptech/grule-rule-engine/pkg"
)

func main() {
    lib := ast.NewKnowledgeLibrary()
    rb := builder.NewRuleBuilder(lib)
    err := rb.BuildRuleFromResource("ArticleRule", "1.0", pkg.NewFileResource("path/to/article.grl"))
    e := engine.NewGruleEngine()
    knowledgeBase := lib.NewKnowledgeBaseInstance("ArticleRule", "1.0")
    err = e.Execute(dataCtx, knowledgeBase)

    if err != nil {
        log.Printf("error: %v", err)
        return
    }

    a := models.Article{
        IsOpen: true,
        Status: 0,
    }
    dataCtx := ast.NewDataContext()
    err = dataCtx.Add("A", a)
    if err != nil {
        log.Printf("error: %v", err)
        return
    }

    fmt.Printf("isActive: %v", a.IsActive)
    // isActive: true
}

まだプロダクションに載せていませんが、仕様を理解しながらルールをまとめてドキュメントとしても活用できないか模索したいと思います。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0