How to Configure Pipeline Filters for Request/Response Transformation in Easegress

Configure pipeline filters in Easegress by declaring RequestAdaptor and ResponseAdaptor entries in the filters section, referencing them in the flow sequence, and setting transformation rules for headers, paths, body content, or compression.

Easegress uses a pipeline architecture to process HTTP traffic, where traffic flows through a sequence of filters that can inspect, transform, or route requests and responses. To configure pipeline filters for request/response transformation in Easegress, you define two sections: flow (execution order) and filters (configuration objects), placing RequestAdaptor before the backend proxy and ResponseAdaptor after it.

Understanding Easegress Pipeline Architecture

Every pipeline processes traffic through two mandatory configuration blocks. The flow section declares the execution order and conditional jumpIf logic, while the filters section provides the concrete configuration for each filter referenced in the flow.

According to the source code in pkg/filters/builder/requestadaptor.go and pkg/filters/builder/responseadaptor.go, transformation filters follow a consistent architectural pattern:

  1. Spec struct – Holds user-provided configuration (RequestAdaptorSpec or ResponseAdaptorSpec)
  2. Builder – Generates a runtime adaptor object from the spec
  3. Handle – Executes during the pipeline run, applying configured transformations

Core Transformation Filters

Easegress provides two specialized filters for modifying HTTP traffic. Both support static configuration fields and dynamic Go templates for runtime value generation.

RequestAdaptor Configuration

The RequestAdaptor filter modifies inbound HTTP requests before they reach the backend. In pkg/filters/builder/requestadaptor.go, the implementation supports these key fields:

  • host – Override the request Host header
  • method – Replace the HTTP method (GET, POST, etc.)
  • path – A PathAdaptor spec to add, replace, or regexp-replace the URL path
  • header – An httpheader.AdaptSpec to add, delete, or set headers
  • body – Replace the request body with a literal string
  • compress / decompress – Apply or remove gzip compression
  • sign – Sign the request using AWS Signature V4
  • template – A Go text/template that dynamically generates any of the above fields, taking precedence over static values

ResponseAdaptor Configuration

The ResponseAdaptor filter, implemented in pkg/filters/builder/responseadaptor.go, mirrors the request filter but omits connection-specific fields. Available options include:

  • header – Add, delete, or set response headers
  • body – Replace the response body content
  • compress / decompress – Gzip compression handling for responses
  • template – Dynamic template generation for response modifications

Structuring the Pipeline Configuration

To wire transformation filters into a working pipeline, you must reference them in both the flow and filters sections of your YAML configuration.

The flow list determines execution order. Place RequestAdaptor before your proxy filter and ResponseAdaptor after it. Use jumpIf to conditionally skip remaining filters based on result codes.

flow:
  - filter: requestAdaptor
  - filter: proxy
  - filter: responseAdaptor
    jumpIf: { compressFail: END }

Under the filters: section, define each adaptor with its kind and transformation rules:

filters:
  - name: requestAdaptor
    kind: RequestAdaptor
    # transformation rules here

Complete Configuration Examples

Full Pipeline with Both Adaptors

This complete pipeline example, adapted from example/config/pipeline-example.yaml, demonstrates a production-ready flow with validation, rate limiting, transformation, and proxying:

name: http-pipeline-example
kind: Pipeline

flow:
  - filter: validator
    jumpIf: { invalid: END }
  - filter: rateLimiter
  - filter: requestAdaptor
  - filter: proxy
    jumpIf: { clientError: END }
  - filter: responseAdaptor

filters:
  - name: validator
    kind: Validator

  - name: rateLimiter
    kind: RateLimiter

  - name: requestAdaptor
    kind: RequestAdaptor
    host: dev.megaease.com
    path:
      addPrefix: /v3
    header:
      del: ["X-Version"]
      set:
        X-Adapt-Key: goodplan

  - name: proxy
    kind: Proxy

  - name: responseAdaptor
    kind: ResponseAdaptor
    header:
      set:
        Server: Easegress v1.0.0
      add:
        X-Proxy-Name: http-proxy-example

Path Prefix Transformation

To prepend a version prefix to all incoming request paths, configure the path field with addPrefix:

kind: RequestAdaptor
name: add-prefix
path:
  addPrefix: /v3

This configuration lives in the filters section and ensures all backend requests include the /v3 prefix without requiring client-side changes.

Dynamic Template Injection

For runtime value injection, use the template field with Go template syntax. The template context provides access to the request object:

kind: RequestAdaptor
name: tmpl-header
template: |
  header:
    set:
      X-User: '{{ .req.Header.Get "X-Original-User" }}'
      X-Request-ID: '{{ .req.ID }}'

The template engine evaluates during the Handle phase, allowing you to propagate request IDs or extract values from incoming headers dynamically.

Validation and Error Codes

Both adaptors implement a Validate() method that enforces configuration constraints. For example, the compress field only accepts "gzip" as a valid value.

When operations fail, the filters return specific result codes that you can handle via jumpIf:

  • compressFail – Gzip compression failed
  • decompressFail – Gzip decompression failed
  • signFail – Request signing failed (RequestAdaptor only)

These codes allow your pipeline to terminate early or skip transformations when prerequisites aren't met.

Summary

  • Pipeline structure requires both flow (execution order) and filters (configuration) sections
  • RequestAdaptor transforms inbound requests via pkg/filters/builder/requestadaptor.go, supporting host, method, path, header, body, and signature modifications
  • ResponseAdaptor transforms outbound responses via pkg/filters/builder/responseadaptor.go, focusing on headers and body compression
  • Templates enable dynamic transformation using Go text/template syntax with access to request context
  • Error handling uses result codes like compressFail and decompressFail with jumpIf for conditional flow control

Frequently Asked Questions

How do I add a URL prefix to all incoming requests in Easegress?

Use the RequestAdaptor filter with the path.addPrefix field. Define a filter with kind: RequestAdaptor and specify path: { addPrefix: /your/prefix } in the configuration. Reference this filter in your pipeline's flow section before the proxy filter.

Can I modify response headers before sending them to the client?

Yes. Add a ResponseAdaptor filter after your proxy in the pipeline flow. Use the header.set or header.add fields to inject or modify headers. The implementation in pkg/filters/builder/responseadaptor.go processes these modifications after receiving the backend response.

What compression formats does Easegress support for request/response transformation?

Easegress supports gzip compression and decompression for both requests and responses. Set compress: gzip or decompress: gzip in your adaptor configuration. The Validate() method specifically checks that only "gzip" is specified, rejecting other compression formats.

How do I dynamically set header values based on the incoming request?

Use the template field in either adaptor. The template accepts Go text/template syntax and provides access to the request context via .req. For example, use '{{ .req.Header.Get "X-User" }}' to copy values from incoming headers or '{{ .req.ID }}' to inject unique request identifiers.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →