Architecture

Architecture diagram

YAO based on the flow-based programming idea, YAO encapsulates a series of atomic operations into processes; these processes can be called in YAO DSL or JavaScript scripts.

According to business characteristics, YAO defines a set of YAO DSL to describe functional modules such as data structure, data flow, API interface, concurrent tasks, scheduled tasks, and Socket services. These functional modules are defined as Widgets.

When the engine starts, it is parsed into a set of API interfaces and a set of handlers according to the Widget logic. In application development, by writing a Widget DSL to describe the differences, the corresponding functional modules can be implemented, thereby improving coding efficiency.

YAO DSL and YAO Widget support the definition of extensions according to their own business characteristics, which makes it easier to build a low-code platform based on YAO that meets their own business characteristics.

core code

Yao App Engine

App Engine Command Line Tool & Scenario-Specific process Yao App Engine

Gou Framework

Engine core logic & general process Gou Framework

Xun Database

Database ORM Xun Database

Kun

Common Data Structures & Toolkits Kun

[View source code compilation document](../Expert/Source Code Compilation)

Create Process

For some specific scenarios, you need to add a new process to the engine, use the gou.RegisterProcessHandler method to register a Golang function as a process.

It is recommended to set a specific namespace to prevent conflicts, so that it can be merged with the latest YAO code at any time.

add a handler file

mkdir -p /code/root/yao/myprocesses
touch /code/root/yao/myprocesses/hello.go
touch /code/root/yao/myprocesses/hello_test.go

The process func

/code/root/yao/myprocesses/hello.go

package myprocesses
import(
"github.com/yaoapp/gou"
)
func init() {
gou.RegisterProcessHandler("mycom.myprocesses.hello", processHello) // register the process
}
// processHello processing logic
func processHello(process *gou.Process) interface{} {
args := process.Args
return map[string]interface{}{"args": process.Args}
}

referenced in the main program

Edit /code/root/yao/main.go

package main
import (
"github.com/yaoapp/yao/cmd"
_ "github.com/yaoapp/gou/encoding"
_ "github.com/yaoapp/yao/crypto"
_ "github.com/yaoapp/yao/helper"
_ "github.com/yaoapp/yao/network"
_ "github.com/yaoapp/yao/system"
_ "github.com/yaoapp/yao/user"
_ "github.com/yaoapp/yao/xfs"
_ "github.com/yaoapp/yao/myprocesses"
)
// main program
func main() {
cmd.Execute()
}

unit test

/code/root/yao/myprocesses/hello_test.go

package myprocesses
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/yaoapp/gou"
)
func TestProcessHello(t *testing.T) {
args := []interface{}{"hello world", "foo", "bar", 0.618}
res, err := gou.NewProcess("mycom.myprocesses.hello", args...).Exec()
if err != nil {
t. Fatal(err)
}
assert. Equal(t, []interface{}{"hello world", "foo", "bar", 0.618}, res.(map[string]interface{})["args"])
}

run the test

cd /code/root/yao/myprocesses
go test -run TestProcessHello

Calling the example in the application

Use in data flow

Add dataflow file

mkdir -p /code/root/yao/tests/flows/mycom
touch /code/root/yao/tests/flows/mycom/hello.flow.json

Write logic /code/root/yao/tests/flows/mycom/hello.flow.json

{
"label": "Hello",
"version": "1.0.0",
"description": "Hello",
"nodes": [
{
"name": "hello",
"process": "mycom.myprocesses.hello",
"args": ["hello world", "foo", "bar", 0.618]
}
],
"output": "{{$res.args}}"
}

run the test

cd /code/root/yao/
go run . run flows.mycom.hello

Use in JavaScript scripts

add script file

mkdir -p /code/root/yao/tests/scripts/mycom
touch /code/root/yao/tests/scripts/mycom/hello.js

write script /code/root/yao/tests/scripts/mycom/hello.js

function Hi() {
return Process("mycom.myprocesses.hello", "hello world", "foo", "bar", 0.618);
}

run the test

cd /code/root/yao/
go run . run scripts.mycom.hello.Hi

related information

Next, it is recommended to study the following chapters:

Architecture

Architecture diagram

YAO based on the flow-based programming idea, YAO encapsulates a series of atomic operations into processes; these processes can be called in YAO DSL or JavaScript scripts.

According to business characteristics, YAO defines a set of YAO DSL to describe functional modules such as data structure, data flow, API interface, concurrent tasks, scheduled tasks, and Socket services. These functional modules are defined as Widgets.

When the engine starts, it is parsed into a set of API interfaces and a set of handlers according to the Widget logic. In application development, by writing a Widget DSL to describe the differences, the corresponding functional modules can be implemented, thereby improving coding efficiency.

YAO DSL and YAO Widget support the definition of extensions according to their own business characteristics, which makes it easier to build a low-code platform based on YAO that meets their own business characteristics.

core code

Yao App Engine

App Engine Command Line Tool & Scenario-Specific process Yao App Engine

Gou Framework

Engine core logic & general process Gou Framework

Xun Database

Database ORM Xun Database

Kun

Common Data Structures & Toolkits Kun

[View source code compilation document](../Expert/Source Code Compilation)

Create Process

For some specific scenarios, you need to add a new process to the engine, use the gou.RegisterProcessHandler method to register a Golang function as a process.

It is recommended to set a specific namespace to prevent conflicts, so that it can be merged with the latest YAO code at any time.

add a handler file

mkdir -p /code/root/yao/myprocesses
touch /code/root/yao/myprocesses/hello.go
touch /code/root/yao/myprocesses/hello_test.go

The process func

/code/root/yao/myprocesses/hello.go

package myprocesses
import(
"github.com/yaoapp/gou"
)
func init() {
gou.RegisterProcessHandler("mycom.myprocesses.hello", processHello) // register the process
}
// processHello processing logic
func processHello(process *gou.Process) interface{} {
args := process.Args
return map[string]interface{}{"args": process.Args}
}

referenced in the main program

Edit /code/root/yao/main.go

package main
import (
"github.com/yaoapp/yao/cmd"
_ "github.com/yaoapp/gou/encoding"
_ "github.com/yaoapp/yao/crypto"
_ "github.com/yaoapp/yao/helper"
_ "github.com/yaoapp/yao/network"
_ "github.com/yaoapp/yao/system"
_ "github.com/yaoapp/yao/user"
_ "github.com/yaoapp/yao/xfs"
_ "github.com/yaoapp/yao/myprocesses"
)
// main program
func main() {
cmd.Execute()
}

unit test

/code/root/yao/myprocesses/hello_test.go

package myprocesses
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/yaoapp/gou"
)
func TestProcessHello(t *testing.T) {
args := []interface{}{"hello world", "foo", "bar", 0.618}
res, err := gou.NewProcess("mycom.myprocesses.hello", args...).Exec()
if err != nil {
t. Fatal(err)
}
assert. Equal(t, []interface{}{"hello world", "foo", "bar", 0.618}, res.(map[string]interface{})["args"])
}

run the test

cd /code/root/yao/myprocesses
go test -run TestProcessHello

Calling the example in the application

Use in data flow

Add dataflow file

mkdir -p /code/root/yao/tests/flows/mycom
touch /code/root/yao/tests/flows/mycom/hello.flow.json

Write logic /code/root/yao/tests/flows/mycom/hello.flow.json

{
"label": "Hello",
"version": "1.0.0",
"description": "Hello",
"nodes": [
{
"name": "hello",
"process": "mycom.myprocesses.hello",
"args": ["hello world", "foo", "bar", 0.618]
}
],
"output": "{{$res.args}}"
}

run the test

cd /code/root/yao/
go run . run flows.mycom.hello

Use in JavaScript scripts

add script file

mkdir -p /code/root/yao/tests/scripts/mycom
touch /code/root/yao/tests/scripts/mycom/hello.js

write script /code/root/yao/tests/scripts/mycom/hello.js

function Hi() {
return Process("mycom.myprocesses.hello", "hello world", "foo", "bar", 0.618);
}

run the test

cd /code/root/yao/
go run . run scripts.mycom.hello.Hi

related information

Next, it is recommended to study the following chapters: