Transition is a Golang state machine implementation
Switch branches/tags
Nothing to show
Clone or download
Latest commit 4015a3e Oct 31, 2017


Transition is a Golang state machine implementation.

it can be used standalone, but it integrates nicely with GORM models. When integrated with GORM, it will also store state change logs in the database automatically.



Enable Transition for your struct

Embed transition.Transition into your struct, it will enable the state machine feature for the struct:

import ""

type Order struct {
  ID uint

Define States and Events

var OrderStateMachine = transition.New(&Order{})

// Define initial state

// Define a State

// Define another State and what to do when entering and exiting that state.
OrderStateMachine.State("paid").Enter(func(order interface{}, tx *gorm.DB) error {
  // To get order object use 'order.(*Order)'
  // business logic here
}).Exit(func(order interface{}, tx *gorm.DB) error {
  // business logic here

// Define more States

// Define an Event

// Define another event and what to do before and after performing the transition.
OrderStateMachine.Event("paid").To("paid").From("checkout").Before(func(order interface{}, tx *gorm.DB) error {
  // business logic here
  return nil
}).After(func(order interface{}, tx *gorm.DB) error {
  // business logic here
  return nil

// Different state transitions for one event
cancellEvent := OrderStateMachine.Event("cancel")
cancellEvent.To("cancelled").From("draft", "checkout")
cancellEvent.To("paid_cancelled").From("paid").After(func(order interface{}, tx *gorm.DB) error {
  // Refund

Trigger an Event

// func (*StateMachine) Trigger(name string, value Stater, tx *gorm.DB, notes ...string) error
OrderStatemachine.Trigger("paid", &order, db, "charged offline by jinzhu")
// notes will be used to generate state change logs when works with GORM

// When using without GORM, just pass nil to the db, like
OrderStatemachine.Trigger("cancel", &order, nil)

OrderStatemachine.Trigger("cancel", &order, db)
// order's state will be changed to cancelled if current state is "draft"
// order's state will be changed to paid_cancelled if current state is "paid"

Get/Set State

var order Order

// Get Current State

// Set State
order.SetState("finished") // this will only update order's state, won't save it into database

State change logs

When working with GORM, Transition will store all state change logs in the database. Use GetStateChangeLogs to get those logs.

// create the table used to store logs first

// get order's state change logs
var stateChangeLogs = transition.GetStateChangeLogs(&order, db)

// type StateChangeLog struct {
//   From       string  // from state
//   To         string  // to state
//   Note       string  // notes
// }


Released under the MIT License.