# How to Define Services and Routes in Easegress: A Complete Guide

> Learn to define services and routes in Easegress. Create Service and HTTPServer YAML files and apply them using egctl or the REST API for seamless traffic management.

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

---

**To define services and routes in Easegress, create a Service YAML for mesh registration and an HTTPServer YAML with routing rules, then apply them via `egctl` or the REST API.**

Easegress uses a declarative, API-driven model to configure traffic management. According to the easegress-io/easegress source code, services are managed by the **mesh controller** for service discovery, while routes are handled by the **HTTP server** object that maps incoming requests to backend pipelines. This architecture separates service registration from traffic routing, allowing you to define services and routes in Easegress independently using YAML specifications or the command-line interface.

## Understanding the Service Mesh Architecture

The platform splits concerns between service definitions and routing logic. This separation enables flexible traffic management without coupling service discovery to request handling.

### Service Definitions in the Mesh Controller

Services in Easegress are defined by the `Service` struct in [`pkg/object/meshcontroller/spec/spec.go`](https://github.com/easegress-io/easegress/blob/main/pkg/object/meshcontroller/spec/spec.go). This specification includes the service name, registry information, sidecar configuration, and optional resilience features like load balancing and observability. 

When you define a service, the mesh controller persists the specification in the underlying registry (etcd, Zookeeper, or similar) via the storage layer in [`pkg/object/meshcontroller/service/service.go`](https://github.com/easegress-io/easegress/blob/main/pkg/object/meshcontroller/service/service.go). This allows sidecars and gateways to discover service instances dynamically.

### Route Definitions in the HTTP Server

Routes belong to the `HTTPServer` specification defined in [`pkg/object/httpserver/spec.go`](https://github.com/easegress-io/easegress/blob/main/pkg/object/httpserver/spec.go). The spec contains a `RouterKind` field that determines which algorithm interprets the rules—either **Ordered** or **RadixTree**—and a slice of `routers.Rules`.

Each rule, defined in [`pkg/object/httpserver/routers/spec.go`](https://github.com/easegress-io/easegress/blob/main/pkg/object/httpserver/routers/spec.go), contains `Path` objects that map URL patterns, HTTP methods, and headers to specific backend pipelines. The router implementation is registered at runtime in [`pkg/object/httpserver/routers/routers.go`](https://github.com/easegress-io/easegress/blob/main/pkg/object/httpserver/routers/routers.go), allowing the system to instantiate the correct matching engine based on your configuration.

## Defining Services with YAML

To register a service in the mesh, create a YAML file that populates the `Service` struct. The following example defines a service named `demo-service` with a sidecar listening on port 10080:

```yaml
apiVersion: easegress.io/v2
kind: Service
metadata:
  name: demo-service
spec:
  registryName: etcd-service-registry-example
  name: demo-service
  registerTenant: default
  sidecar:
    discoveryType: static
    address: 127.0.0.1
    ingressPort: 10080
    ingressProtocol: http
    egressPort: 10081
    egressProtocol: http

```

In [`pkg/object/meshcontroller/spec/spec.go`](https://github.com/easegress-io/easegress/blob/main/pkg/object/meshcontroller/spec/spec.go), the `Service` struct stores this metadata, including the sidecar ports and registry connection details. The `registryName` field links the service to a specific service registry instance, while the `sidecar` block configures the proxy that handles traffic interception.

## Configuring Routes and Rules

Routes are defined within an `HTTPServer` object. You must specify the `routerKind`—**Ordered** for sequential rule evaluation or **RadixTree** for high-performance prefix matching—and define rules that map requests to backend services.

The following YAML creates an HTTP server that routes requests to the previously defined service:

```yaml
apiVersion: easegress.io/v2
kind: HTTPServer
metadata:
  name: demo-http
spec:
  address: 0.0.0.0
  port: 8080
  routerKind: RadixTree
  rules:
    - hosts: ["*"]
      paths:
        - path: /api/v1/hello
          methods: ["GET"]
          backend: demo-service
          rewrite: /hello

```

The `rules` field corresponds to the `routers.Rules` type in [`pkg/object/httpserver/routers/spec.go`](https://github.com/easegress-io/easegress/blob/main/pkg/object/httpserver/routers/spec.go). Each `Path` object within a rule specifies the URL pattern, permitted HTTP methods, and the target `backend`, which references the pipeline name that forwards traffic to your service. The optional `rewrite` field modifies the request path before forwarding.

## Deploying with the Easegress CLI

You can apply these configurations using the `egctl` command-line tool, which converts CLI arguments into the underlying API calls. The implementation in [`cmd/client/commandv2/create/createhttpproxy.go`](https://github.com/easegress-io/easegress/blob/main/cmd/client/commandv2/create/createhttpproxy.go) handles the translation from user flags to `httpproxy.Spec` objects.

Create the service using the mesh controller commands:

```bash
egctl create service demo-service --registry etcd-service-registry-example \
    --sidecar-address 127.0.0.1 --ingress-port 10080 --egress-port 10081

```

Then create the HTTP server with routing rules:

```bash
egctl create httpproxy demo-http --port 8080 \
    --router-kind RadixTree \
    --rule "host=* path=/api/v1/hello method=GET backend=demo-service"

```

The `create httpproxy` command constructs the HTTPServer specification and populates the `routers.Rule` objects that the RadixTree engine will evaluate at runtime.

## Summary

Defining services and routes in Easegress requires understanding two core abstractions:

- **Service specifications** live in [`pkg/object/meshcontroller/spec/spec.go`](https://github.com/easegress-io/easegress/blob/main/pkg/object/meshcontroller/spec/spec.go) and describe mesh service metadata, sidecar configuration, and registry connections.
- **Route specifications** are part of the HTTPServer object in [`pkg/object/httpserver/spec.go`](https://github.com/easegress-io/easegress/blob/main/pkg/object/httpserver/spec.go), using either Ordered or RadixTree routers defined in `pkg/object/httpserver/routers/`.
- Apply configurations via YAML manifests or the `egctl` CLI, which interfaces with the control plane to persist objects in the registry.
- The router implementation is pluggable, registered in [`pkg/object/httpserver/routers/routers.go`](https://github.com/easegress-io/easegress/blob/main/pkg/object/httpserver/routers/routers.go), and selected via the `routerKind` field.

## Frequently Asked Questions

### What is the difference between Ordered and RadixTree routers?

**Ordered** routers evaluate rules sequentially in the order they appear in the YAML, making them ideal for complex precedence logic but slower for large rule sets. **RadixTree** routers use a prefix tree data structure for O(log n) lookup performance, which is optimal for high-throughput scenarios with many routes. You configure the router type in the `routerKind` field of the HTTPServer spec, as defined in [`pkg/object/httpserver/spec.go`](https://github.com/easegress-io/easegress/blob/main/pkg/object/httpserver/spec.go).

### How do I register a service with multiple ports?

The `Service` struct in [`pkg/object/meshcontroller/spec/spec.go`](https://github.com/easegress-io/easegress/blob/main/pkg/object/meshcontroller/spec/spec.go) supports defining multiple ports within the `sidecar` configuration block, including separate `ingressPort` and `egressPort` values for handling incoming and outgoing traffic differently. For additional service instances, register multiple services with the same logical name but different endpoint addresses in the registry.

### Can I use wildcards in route host matching?

Yes, the `hosts` field in a rule accepts wildcard patterns such as `*.example.com` to match subdomains. The host matching logic is implemented in the router specifications within [`pkg/object/httpserver/routers/spec.go`](https://github.com/easegress-io/easegress/blob/main/pkg/object/httpserver/routers/spec.go), where the `Rule` struct processes host arrays against the incoming request's Host header.

### Where are service definitions stored in Easegress?

Service definitions are persisted in the configured mesh registry—typically etcd, Consul, or Zookeeper—via the storage layer in [`pkg/object/meshcontroller/service/service.go`](https://github.com/easegress-io/easegress/blob/main/pkg/object/meshcontroller/service/service.go). The mesh controller watches these registry entries to update sidecar configurations dynamically, ensuring that traffic routing remains consistent with the current service topology.