Pipeline

Pipeline is an innovative and powerful tool invented by us. It provides data validation, transformation, and custom callbacks. Developers can attach pipelines to both models and to model fields.

A simple pipeline

Let's see a simple pipeline. This is a model field's @onSet pipeline. When a new value is set on this field, firstly, it trims leading and trailing whitespaces. Then it validates its content against an email regular expression.

model Demo {
  @onSet($trim.isEmail)
  email: String
}

Common stages

There are various stages to trigger pipelines, common stages include:

  • Model stages
    • beforeSave before this object is saved into the database
    • afterSave after this object is saved into the database
    • beforeDelete before this object is deleted from the database
    • afterDelete after this object is deleted from the database
  • Model field stages
    • onSet when a new value is set
    • onSave when this object is being saved into the database
    • identityChecker is for identity checker fields only
    • onOutput when a value is being outputed into the result JSON

Pipeline item

A pipeline is composed of one or more pipeline items. Each pipeline item do exactly one thing. Pipeline items can be piped in any orders as long as the input of next item matches the output of previous item.

Kinds of pipeline items

Although a pipeline item can do transform, validation and callback. Normally there are four main kinds of pipeline items:

  • Transform pipeline item transforms value
  • Validator pipeline item validates value
  • Callback pipeline item performs custom code callback
  • Compare pipeline item compares the old and the new value, when the value is updated, perform callback and return a validating result

Declare a pipeline item

Use the 'declare' keyword to declare a pipeline item. Argument types, input type, and output type are required. The argument list can be omitted.

declare pipeline item identical<T>: T -> T

Implement a pipeline item

Use the server API to implement a pipeline item:

app.main_namespace().define_pipeline_item("identical", |value: Value| async move {
  Ok(value)
});