> ## Documentation Index
> Fetch the complete documentation index at: https://sequinstream.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Routing functions

> Dynamically direct your data to its downstream destination

Routing functions allow you to dynamically direct messages to different destinations based on the content of the message. This is useful for:

* Interacting with REST APIs which assign each record its own resource path
* Using different HTTP methods based on the change action
* Implementing custom routing logic based on record contents
* Customizing message routing for various messaging systems

## How routing functions work

When you create a routing function, you define an Elixir function that returns routing information. Sequin will use this information to determine the destination for each message.

For each message, your routing function receives the same parameters as a [transform function](/reference/transforms) and must return a map containing the sink-specific routing information:

```elixir theme={null}
def route(action, record, changes, metadata) do
  # Return a map with sink-specific routing parameters
  %{
    # Sink-specific routing parameters
  }
end
```

In general, some details of how the message is processed will be static and fixed by the sink.  Routing functions enable you to customize the behavior of a sink, but they are not intended to replace the idea of multiple sinks where necessary.
For example, for the HTTP Webhook sink, the base URL is a static property - this improves batching and enables other performance optimizations such as connection pooling and request pipelining.

## Sinks

Each sink type has different fields that can be routed:

### Kafka sink

For [Kafka](/reference/sinks/kafka), your routing function must return a map with these keys:

| Key           | Type   | Description                   | Example           |
| ------------- | ------ | ----------------------------- | ----------------- |
| `topic`       | String | The topic to publish to       | `"users.created"` |
| `message_key` | String | The message key to publish to | `"users:123"`     |

### HTTP Webhook sink

For [HTTP webhooks](/reference/sinks/webhooks), your routing function must return a map with these keys:

| Key             | Type   | Description                                 | Example                       |
| --------------- | ------ | ------------------------------------------- | ----------------------------- |
| `method`        | String | The HTTP method to use                      | `"POST"`, `"PUT"`, `"DELETE"` |
| `endpoint_path` | String | The path to append to your webhook base URL | `"/users/123"`                |

The `endpoint_path` you specify will be appended to the base URL of your webhook endpoint. For example, if your webhook endpoint is `https://api.example.com` and your routing function returns `endpoint_path: "/users/123"`, the message will be sent to `https://api.example.com/users/123`.

### Redis String sink

For [Redis String](/reference/sinks/redis-string), your routing function must return a map with these keys:

| Key   | Type   | Description                    | Example       |
| ----- | ------ | ------------------------------ | ------------- |
| `key` | String | The key to use for the message | `"users:123"` |

The `key` is used to determine the key in Redis where the message will be stored in the `SET` operation:

```redis theme={null}
SET key value
```

### Redis Stream sink

For [Redis Stream](/reference/sinks/redis-stream), your routing function must return a map with these keys:

| Key          | Type   | Description                  | Example   |
| ------------ | ------ | ---------------------------- | --------- |
| `stream_key` | String | The stream key to publish to | `"users"` |

### NATS sink

For [NATS](/reference/sinks/nats), your routing function must return a map with these keys:

| Key       | Type   | Description               | Example           |
| --------- | ------ | ------------------------- | ----------------- |
| `subject` | String | The subject to publish to | `"users.created"` |

### GCP PubSub sink

For [GCP PubSub](/reference/sinks/gcp-pubsub), your routing function must return a map with these keys:

| Key        | Type   | Description                | Example           |
| ---------- | ------ | -------------------------- | ----------------- |
| `topic_id` | String | The topic ID to publish to | `"users.created"` |

### Elasticsearch sink

For [Elasticsearch](/reference/sinks/elasticsearch), your routing function must return a map with these keys:

| Key          | Type   | Description             | Example   |
| ------------ | ------ | ----------------------- | --------- |
| `index_name` | String | The index to publish to | `"users"` |

### Typesense sink

For [Typesense](/reference/sinks/typesense), your routing function must return a map with these keys:

| Key               | Type   | Description                             | Example               |
| ----------------- | ------ | --------------------------------------- | --------------------- |
| `action`          | String | The action to perform on the collection | `"index"`, `"delete"` |
| `collection_name` | String | The collection name to index into       | `"users"`             |

### Meilisearch sink

For [Meilisearch](/reference/sinks/meilisearch), your routing function must return a map with these keys:

| Key          | Type   | Description                             | Example               |
| ------------ | ------ | --------------------------------------- | --------------------- |
| `action`     | String | The action to perform on the collection | `"index"`, `"delete"` |
| `index_name` | String | The index to publish to                 | `"users"`             |

### AWS SQS sink

For [AWS SQS](/reference/sinks/sqs), your routing function must return a map with these keys:

| Key         | Type   | Description                 | Example                                                    |
| ----------- | ------ | --------------------------- | ---------------------------------------------------------- |
| `queue_url` | String | The queue URL to publish to | `"https://sqs.us-east-1.amazonaws.com/123456789012/users"` |

### AWS Kinesis sink

For [AWS Kinesis](/reference/sinks/kinesis), your routing function must return a map with these keys:

| Key          | Type   | Description                          | Example                                                     |
| ------------ | ------ | ------------------------------------ | ----------------------------------------------------------- |
| `stream_arn` | String | The Kinesis stream ARN to publish to | `"arn:aws:kinesis:us-east-1:123456789012:stream/my-stream"` |

### S2 sink

For [S2](/reference/sinks/s2), your routing function must return a map with these keys:

| Key      | Type   | Description                        | Example      |
| -------- | ------ | ---------------------------------- | ------------ |
| `basin`  | String | The S2 basin to publish to         | `"my-basin"` |
| `stream` | String | The S2 stream to append records to | `"users"`    |

### RabbitMQ sink

For [RabbitMQ](/reference/sinks/rabbitmq), your routing function must return a map with these keys:

| Key           | Type   | Description                   | Example                 |
| ------------- | ------ | ----------------------------- | ----------------------- |
| `exchange`    | String | The exchange to publish to    | `"sequin"`              |
| `routing_key` | String | The routing key to publish to | `"sequin.users.insert"` |
| `headers`     | Map    | AMQP headers to include       | `%{"x-key" => "value"}` |

### Azure Event Hub sink

For [Azure Event Hubs](/reference/sinks/azure-event-hubs), your routing function must return a map with these keys:

| Key              | Type   | Description                      | Example                    |
| ---------------- | ------ | -------------------------------- | -------------------------- |
| `event_hub_name` | String | The Event Hub name to publish to | `"sequin.db.public.users"` |

## Common routing patterns

### Routing to REST APIs

Route messages to RESTful endpoints based on record ID and action:

```elixir theme={null}
def route(action, record, changes, metadata) do
  endpoint_path = "/api/users/#{record["external_id"]}"

  method = case action do
    "insert" -> "POST"
    "update" -> "PUT"
    "delete" -> "DELETE"
    _ -> "POST"
  end

  %{
    method: method,
    endpoint_path: endpoint_path
  }
end
```

### Content-based routing

Route messages based on their content:

```elixir theme={null}
def route(action, record, changes, metadata) do
  # Route high-priority messages to a different endpoint
  if record["priority"] == "high" do
    %{
      method: "POST",
      endpoint_path: "/api/priority-events"
    }
  else
    %{
      method: "POST",
      endpoint_path: "/api/events"
    }
  end
end
```

## Testing routing functions

When creating or editing a routing function, you can test it with real data from your database. Sequin will capture recent events and show you the effective routing parameters for each message.

"Effective" means that Sequin will show the routing parameters that will actually be used downstream, inclusive of any defaulting or validation which happens after your routing function runs.

## Limitations and considerations

* Routing can impact batching if your routing function generates different destinations for each message.

## Related

<CardGroup>
  <Card title="Function Transforms" icon="code" href="/reference/transforms#function-transform">
    Learn about function transforms and how to use them to modify your message content.
  </Card>

  <Card title="Messages reference" icon="message-dots" href="/reference/messages">
    Learn about the different fields you can use in routing functions.
  </Card>

  <Card title="Sequin YAML config" icon="pencil" href="/reference/sequin-yaml">
    Learn about configuring functions in your sequin.yaml file.
  </Card>

  <Card title="HTTP Webhooks" icon="globe" href="/reference/sinks#http-webhook-sink">
    Learn more about configuring HTTP webhook destinations.
  </Card>
</CardGroup>
