What Are Easegress Plugins and How to Use Them: A Complete Guide
Easegress plugins are modular Go packages that extend the traffic orchestration platform's core functionality through filters (request processors) and controllers (pipeline managers), registered at runtime via the internal registry system.
Easegress is a cloud-native traffic orchestration system where all core features—routing, load balancing, observability, and transformation—are implemented as plugins. These independent units allow developers to extend the platform without modifying the core codebase. Whether you need to process HTTP requests with custom logic or manage pipeline lifecycles, understanding how to create and register Easegress plugins is essential for advanced deployments.
Understanding Easegress Plugin Architecture
The plugin system in Easegress is built around a registry pattern that dynamically loads compiled Go packages at runtime. According to the source code in easegress-io/easegress, plugins are categorized into two primary types and registered through specific registry mechanisms.
Plugin Types: Filters and Controllers
Filters are request/response processors that operate within HTTP pipelines. They implement business logic such as authentication, transformation, or proxying. In pkg/filters/registry.go, filters register themselves using filters.Register("name", constructorFunction).
Controllers are pipeline managers that control how traffic flows through multiple filters. They are registered in pkg/api/registry.go via api.RegisterController("name", constructorFunction). Controllers determine routing rules, canary release strategies, and pipeline orchestration.
Core Registry System
The registry system acts as a factory for plugin instantiation. When Easegress starts, it scans registered plugins and makes them available by name. The Plugin struct defined in cmd/builder/build/config.go (lines 50-55) describes how external modules are linked:
type Plugin struct {
Module string // Go module path
Version string // Semantic version
Replacement string // Local path for development
}
This structure allows the egbuilder tool to resolve dependencies and compile custom Easegress binaries that include your plugins.
How to Create Easegress Plugins with egbuilder
The egbuilder CLI tool streamlines the plugin development workflow through a standardized init-add-build-run cycle. This approach eliminates manual Makefile configuration and ensures proper registration boilerplate.
Step 1: Initialize a Plugin Project
Create a new directory and scaffold the project structure:
mkdir myplugin && cd myplugin
egbuilder init
This generates a Go module with the following structure:
myplugin/
├── go.mod
└── plugins/
└── myfilter/
├── filter.go
└── registry/
└── registry.go
The generated registry/registry.go automatically handles registration:
package registry
import "github.com/megaease/easegress/v2/pkg/filters"
func init() {
filters.Register("myFilter", NewMyFilter)
}
Step 2: Add Filters and Controllers
Add additional components to the same project using the add command:
egbuilder add filter myfilter2
egbuilder add controller mycontroller
These commands create the necessary Go files and registry stubs, automatically wiring them into the build configuration.
Step 3: Build the Custom Easegress Binary
Create a builder configuration file builder.yaml:
egVersion: "2.0.0"
plugins:
- module: "./"
version: "v0.1.0"
replacement: "." # Forces local build
output: "easegress-with-myplugin"
Execute the build:
egbuilder build -c builder.yaml
The tool parses the Plugin struct entries, sets up Go module replacements, and invokes go build to produce easegress-with-myplugin.
Step 4: Run Easegress with Your Plugins
Launch the server using the custom binary:
egbuilder run -c builder.yaml -f your-easegress-config.yaml
Reference your plugin in the Easegress configuration:
pipeline:
name: demo-pipeline
filters:
- name: myFilter # Your custom filter
- name: proxy
Manual Plugin Implementation Example
For developers who prefer manual implementation over scaffolding, here is a complete filter that logs request paths. This example demonstrates the required interfaces and registration pattern used in pkg/filters.
Create myfilter/filter.go:
package myfilter
import (
"github.com/megaease/easegress/v2/pkg/filters"
"github.com/megaease/easegress/v2/pkg/object/httppipeline"
"log"
)
type MyFilter struct {
filters.BaseFilter
}
// NewMyFilter creates a new instance; required by the registry.
func NewMyFilter(name string) filters.Filter {
return &MyFilter{BaseFilter: filters.NewBaseFilter(name)}
}
// Request processes incoming HTTP requests.
func (f *MyFilter) Request(ctx *httppipeline.FilterContext) string {
log.Printf("Request path: %s", ctx.Request().Path())
return ""
}
Create myfilter/registry/registry.go:
package registry
import (
"github.com/megaease/easegress/v2/pkg/filters"
"myplugin/myfilter"
)
func init() {
filters.Register("myFilter", func(name string) filters.Filter {
return myfilter.NewMyFilter(name)
})
}
Place these files in the plugins/myfilter/ directory of your project, then build using egbuilder as described above.
Key Source Files for Plugin Development
Understanding these core files in the easegress-io/easegress repository helps when debugging or extending plugin functionality:
| File | Purpose | Location |
|---|---|---|
cmd/builder/build/config.go |
Defines the Plugin struct used by egbuilder to resolve module paths and versions. |
View source |
pkg/filters/registry.go |
Core filter registry where plugins call filters.Register to make themselves discoverable. |
View source |
pkg/api/registry.go |
Controller registry for pipeline management components using api.RegisterController. |
View source |
docs/06.Development-for-Easegress/6.3.egbuilder.md |
Complete documentation for the egbuilder CLI workflow. |
View source |
Summary
- Easegress plugins are modular Go packages that extend the platform as filters (request processors) or controllers (pipeline managers), registered via
pkg/filters/registry.goandpkg/api/registry.go. - The egbuilder CLI automates the development workflow:
initscaffolds projects,addcreates components,buildcompiles custom binaries, andrunlaunches the server with your plugins. - Plugins must implement the
FilterorControllerinterface and register themselves in aninit()function usingfilters.Register()orapi.RegisterController(). - The
Pluginstruct incmd/builder/build/config.godefines how external modules are linked during the build process, supporting local development via thereplacementfield.
Frequently Asked Questions
What is the difference between a filter and a controller in Easegress?
A filter is a request/response processor that operates within an HTTP pipeline to transform, validate, or route traffic, while a controller is a pipeline manager that orchestrates how traffic flows through multiple filters and handles high-level routing strategies like canary releases. Filters register via pkg/filters/registry.go and controllers via pkg/api/registry.go.
How do I register a custom plugin so Easegress can find it?
You must create a registry/registry.go file within your plugin package that imports github.com/megaease/easegress/v2/pkg/filters (or pkg/api for controllers) and calls the registration function in an init() block: filters.Register("myFilter", NewMyFilter). When the plugin is compiled into the binary, this registration makes the component discoverable by name in YAML configurations.
Can I develop plugins without using the egbuilder tool?
Yes, though it requires manual setup. You can write standard Go packages that implement the Filter or Controller interfaces, manually handle the registration in init() functions, and use Go module replace directives to link your code into the Easegress binary. However, egbuilder automates the scaffolding, dependency management, and build process defined in cmd/builder/build/config.go, making development significantly faster.
What Go interfaces must I implement to create a working filter?
At minimum, your filter must embed filters.BaseFilter and implement the Request(ctx *httppipeline.FilterContext) string method. The constructor function (e.g., NewMyFilter) must return a filters.Filter interface type. For controllers, you implement the controller interface defined in pkg/api and register via api.RegisterController.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →