1---
2layout: "docs"
3page_title: "Discovery Chain"
4sidebar_current: "docs-internals-discovery-chain"
5description: |-
6  The service discovery process can be modeled as a "discovery chain" which passes through three distinct stages: routing, splitting, and resolution. Each of these stages is controlled by a set of configuration entries.
7---
8
9-> **1.6.0+:**  This feature is available in Consul versions 1.6.0 and newer.
10
11# Discovery Chain
12
13~> This topic is part of a [low-level API](/api/discovery-chain.html)
14primarily targeted at developers building external [Connect proxy
15integrations](/docs/connect/proxies/integrate.html).
16
17The service discovery process can be modeled as a "discovery chain" which
18passes through three distinct stages: routing, splitting, and resolution. Each
19of these stages is controlled by a set of [configuration
20entries](/docs/agent/config_entries.html). By configuring different phases of
21the discovery chain a user can control how proxy upstreams are ultimately
22resolved to specific instances for load balancing.
23
24-> **Note:** The discovery chain is currently only used to discover
25[Connect](/docs/connect/index.html) proxy upstreams.
26
27## Configuration
28
29The configuration entries used in the discovery chain are designed to be simple
30to read and modify for narrowly tailored changes, but at discovery-time the
31various configuration entries interact in more complex ways. For example:
32
33* If a [`service-resolver`](/docs/agent/config-entries/service-resolver.html)
34  is created with a [service
35  redirect](/docs/agent/config-entries/service-resolver.html#service) defined,
36  then all references made to the original service in any other configuration
37  entry is replaced with the redirect destination.
38
39* If a [`service-resolver`](/docs/agent/config-entries/service-resolver.html)
40  is created with a [default
41  subset](/docs/agent/config-entries/service-resolver.html#defaultsubset)
42  defined then all references made to the original service in any other
43  configuration entry that did not specify a subset will be replaced with the
44  default.
45
46* If a [`service-splitter`](/docs/agent/config-entries/service-splitter.html)
47  is created with a [service
48  split](/docs/agent/config-entries/service-splitter.html#splits), and the target service has its
49  own `service-splitter` then the overall effect is flattened and only a single
50  aggregate traffic split is ultimately configured in the proxy.
51
52* [`service-resolver`](/docs/agent/config-entries/service-resolver.html)
53  redirect loops must be rejected as invalid.
54
55* [`service-router`](/docs/agent/config-entries/service-router.html) and
56  [`service-splitter`](/docs/agent/config-entries/service-splitter.html)
57  configuration entries require an L7 compatible protocol be set for the
58  service via either a
59  [`service-defaults`](/docs/agent/config-entries/service-defaults.html) or
60  [`proxy-defaults`](/docs/agent/config-entries/proxy-defaults.html) config
61  entry. Violations must be rejected as invalid.
62
63* If an [upstream
64  configuration](/docs/connect/registration/service-registration.html#upstream-configuration-reference)
65  [`datacenter`](/docs/connect/registration/service-registration.html#datacenter)
66  parameter is defined then any configuration entry that does not explicitly
67  refer to a desired datacenter should use that value from the upstream.
68
69## Compilation
70
71To correctly interpret a collection of configuration entries as a valid
72discovery chain, we first compile them into a form more directly usable by the
73layers responsible for configuring Connect sidecar proxies.
74
75You can interact with the compiler directly using the [discovery-chain
76API](/api/discovery-chain.html).
77
78### Compilation Parameters
79
80* **Service Name** - The service being discovered by name.
81* **Datacenter** - The datacenter to use as the basis of compilation.
82* **Overrides** - Discovery-time tweaks to apply when compiling. These should
83  be derived from either the
84  [proxy](/docs/connect/registration/service-registration.html#complete-configuration-example)
85  or
86  [upstream](/docs/connect/registration/service-registration.html#upstream-configuration-reference)
87  configurations if either are set.
88
89### Compilation Results
90
91The response is a single wrapped `CompiledDiscoveryChain` field:
92
93```json
94{
95    "Chain": {...<CompiledDiscoveryChain>...}
96}
97```
98
99#### `CompiledDiscoveryChain`
100
101The chain encodes a digraph of [nodes](#discoverygraphnode) and
102[targets](#discoverytarget). Nodes are the compiled representation of various
103discovery chain stages and targets are instructions on how to use the [health
104API](/api/health.html#list-nodes-for-connect-capable-service) to retrieve
105relevant service instance lists.
106
107You should traverse the nodes starting with [`StartNode`](#startnode). The
108nodes can be resolved by name using the [`Nodes`](#nodes) field. Targets can be
109resolved by name using the [`Targets`](#targets) field.
110
111- `ServiceName` `(string)` - The requested service.
112- `Namespace` `(string)` - The requested namespace.
113- `Datacenter` `(string)` - The requested datacenter.
114
115- `CustomizationHash` `(string: <optional>)` - A unique hash of any overrides
116  that affected the compilation of the discovery chain.
117
118    If set, this value should be used to prefix/suffix any generated load
119    balancer data plane objects to avoid sharing customized and non-customized
120    versions.
121
122- `Protocol` `(string)` - The overall protocol shared by everything in the
123  chain.
124
125- `StartNode` `(string)` - The first key into the `Nodes` map that should be
126  followed when traversing the discovery chain.
127
128- `Nodes` `(map<string|DiscoveryGraphNode>)` - All nodes available for traversal in
129  the chain keyed by a unique name. You can walk this by starting with
130  `StartNode`.
131
132    -> The names should be treated as opaque values and are only guaranteed to be
133    consistent within a single compilation.
134
135- `Targets` `(map<string|DiscoveryTarget>)` - A list of all targets used in this chain.
136
137    -> The names should be treated as opaque values and are only guaranteed to be
138    consistent within a single compilation.
139
140#### `DiscoveryGraphNode`
141
142A single node in the compiled discovery chain.
143
144- `Type` `(string)` - The type of the node. Valid values are: `router`,
145  `splitter`, and `resolver`.
146
147- `Name` `(string)` - The unique name of the node.
148
149- `Routes` `(array<DiscoveryRoute>)` - Only set for `Type:router`. List of routes to
150  render.
151
152  - `Definition` `(ServiceRoute)` - Relevant portion of underlying
153    `service-router`
154    [route](/docs/agent/config-entries/service-router.html#routes).
155
156  - `NextNode` `(string)` - The name of the next node in the chain in [`Nodes`](#nodes).
157
158- `Splits` `(array<DiscoverySplit>)` - Only set for `Type:splitter`. List of traffic
159  splits.
160
161  - `Weight` `(float32)` - Copy of underlying `service-splitter`
162    [`weight`](/docs/agent/config-entries/service-splitter.html#weight) field.
163
164  - `NextNode` `(string)` - The name of the next node in the chain in [`Nodes`](#nodes).
165
166- `Resolver` `(DiscoveryResolver: <optional>)` - Only set for `Type:resolver`. How
167  to resolve the service instances.
168
169  - `Default` `(bool)` - Set to true if no `service-resolver` config entry is
170    defined for this node and the default was synthesized.
171
172  - `ConnectTimeout` `(duration)` - Copy of the underlying `service-resolver`
173    [`ConnectTimeout`](/docs/agent/config-entries/service-resolver.html#connecttimeout)
174    field. If one is not defined the default of `5s` is returned.
175
176  - `Target` `(string)` - The name of the target to use found in [`Targets`](#targets).
177
178  - `Failover` `(DiscoveryFailover: <optional>)` - Compiled form of the
179    underlying `service-resolver`
180    [`Failover`](/docs/agent/config-entries/service-resolver.html#failover)
181    definition to use for this request.
182
183    - `Targets` `(array<string>)` - List of targets found in
184      [`Targets`](#targets) to failover to in order of preference.
185
186#### `DiscoveryTarget`
187
188- `ID` `(string)` - The unique name of this target.
189
190- `Service` `(string)` - The service to query when resolving a list of service instances.
191
192- `ServiceSubset` `(string: <optional>)` - The
193  [subset](/docs/agent/config-entries/service-resolver.html#service-subsets) of
194  the service to resolve.
195
196- `Namespace` `(string)` - The namespace to use when resolving a list of service instances.
197
198- `Datacenter` `(string)` - The datacenter to use when resolving a list of service instances.
199
200- `Subset` `(ServiceResolverSubset)` - Copy of the underlying
201  `service-resolver`
202  [`Subsets`](/docs/agent/config-entries/service-resolver.html#subsets)
203  definition for this target.
204
205  - `Filter` `(string: "")` - The
206    [filter expression](/api/features/filtering.html) to be used for selecting
207    instances of the requested service. If empty all healthy instances are
208    returned.
209
210  - `OnlyPassing` `(bool: false)` - Specifies the behavior of the resolver's
211    health check interpretation. If this is set to false, instances with checks
212    in the passing as well as the warning states will be considered healthy. If
213    this is set to true, only instances with checks in the passing state will
214    be considered healthy.
215
216- `MeshGateway` `(MeshGatewayConfig)` - The [mesh gateway
217  configuration](/docs/connect/mesh_gateway.html#connect-proxy-configuration)
218  to use when connecting to this target's service instances.
219
220  - `Mode` `(string: "")` - One of `none`, `local`, or `remote`.
221
222- `External` `(bool: false)` - True if this target is outside of this consul cluster.
223
224- `SNI` `(string)` - This value should be used as the
225  [SNI](https://en.wikipedia.org/wiki/Server_Name_Indication) value when
226  connecting to this set of endpoints over TLS.
227
228- `Name` `(string)` - The unique name for this target for use when generating
229  load balancer objects. This has a structure similar to [SNI](#sni), but will
230  not be affected by SNI customizations such as
231  [`ExternalSNI`](/docs/agent/config-entries/service-defaults.html#externalsni).
232