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

> Learn to configure pipeline filters for request response transformation in Easegress. Adapt Easegress pipelines for header, path, body, and compression transformations.

- Repository: [MegaEase/easegress](https://github.com/megaease/easegress)
- Tags: how-to-guide
- Published: 2026-03-07

---

**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`](https://github.com/megaease/easegress/blob/main/pkg/filters/builder/requestadaptor.go) and [`pkg/filters/builder/responseadaptor.go`](https://github.com/megaease/easegress/blob/main/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`](https://github.com/megaease/easegress/blob/main/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`](https://github.com/megaease/easegress/blob/main/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.

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

```

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

```yaml
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`](https://github.com/megaease/easegress/blob/main/example/config/pipeline-example.yaml), demonstrates a production-ready flow with validation, rate limiting, transformation, and proxying:

```yaml
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`:

```yaml
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:

```yaml
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`](https://github.com/megaease/easegress/blob/main/pkg/filters/builder/requestadaptor.go), supporting host, method, path, header, body, and signature modifications
- **ResponseAdaptor** transforms outbound responses via [`pkg/filters/builder/responseadaptor.go`](https://github.com/megaease/easegress/blob/main/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`](https://github.com/megaease/easegress/blob/main/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.