Search Consul documentation 1.6.0+: The discovery chain API is available in Consul versions 1.6.0 and newer.
» Discovery Chain HTTP EndpointThis is a low-level API primarily targeted at developers building external
Connect proxy integrations . Future
high-level proxy integration APIs may obviate the need for this API over time.
The /discovery-chain
endpoint returns the compiled discovery
chain for a service.
This will fetch all related configuration
entries and render them into a form suitable
for use by a connect proxy implementation. This
is a key component of L7 Traffic
Management .
» Read Compiled Discovery ChainIf overrides are needed they are passed as the JSON-encoded request body and
the POST
method must be used, otherwise GET
is sufficient.
Method Path Produces GET
/discovery-chain/:service_name
application/json
POST
1 /discovery-chain/:service_name
application/json
1 Both GET and POST are for read operations. GET requests do not permit request bodies so a POST is required if override parameters are needed.
The table below shows this endpoint's support for
blocking queries ,
consistency modes ,
agent caching , and
required ACLs .
Blocking Queries Consistency Modes Agent Caching ACL Required YES
all
background refresh
service:read
» Path Parametersservice_name
(string: <required>)
- Specifies the service to query when
compiling the discovery chain.» Query Parameters» JSON Request Body Schema» Sample CompilationsFull documentation for the output fields is found on the discovery chain
internals
page.
» Multi-Datacenter FailoverConfig entries defined:
kind = "service-resolver"
name = "web"
connect_timeout = "15s"
failover = {
"*" = {
datacenters = [ "dc3" , "dc4" ]
}
}
kind = "service-resolver"
name = "web"
connect_timeout = "15s"
failover = {
"*" = {
datacenters = [ "dc3" , "dc4" ]
}
}
Request:
$ curl http://127.0.0.1:8500/v1/discovery-chain/web
$ curl http://127.0.0.1:8500/v1/discovery-chain/web
Response:
{
"Chain" : {
"ServiceName" : "web" ,
"Namespace" : "default" ,
"Datacenter" : "dc1" ,
"Protocol" : "tcp" ,
"StartNode" : "resolver:web.default.dc1" ,
"Nodes" : {
"resolver:web.default.dc1" : {
"Type" : "resolver" ,
"Name" : "web.default.dc1" ,
"Resolver" : {
"ConnectTimeout" : "15s" ,
"Target" : "web.default.dc1" ,
"Failover" : {
"Targets" : [ "web.default.dc3" , "web.default.dc4" ]
}
}
}
} ,
"Targets" : {
"web.default.dc1" : {
"ID" : "web.default.dc1" ,
"Service" : "web" ,
"Namespace" : "default" ,
"Datacenter" : "dc1" ,
"MeshGateway" : { } ,
"Subset" : { } ,
"SNI" : "web.default.dc1.internal.47e25151-6212-ba25-8b7e-81adbbbab461.consul" ,
"Name" : "web.default.dc1.internal.47e25151-6212-ba25-8b7e-81adbbbab461.consul"
} ,
"web.default.dc3" : {
"ID" : "web.default.dc3" ,
"Service" : "web" ,
"Namespace" : "default" ,
"Datacenter" : "dc3" ,
"MeshGateway" : { } ,
"Subset" : { } ,
"SNI" : "web.default.dc3.internal.47e25151-6212-ba25-8b7e-81adbbbab461.consul" ,
"Name" : "web.default.dc3.internal.47e25151-6212-ba25-8b7e-81adbbbab461.consul"
} ,
"web.default.dc4" : {
"ID" : "web.default.dc4" ,
"Service" : "web" ,
"Namespace" : "default" ,
"Datacenter" : "dc4" ,
"MeshGateway" : { } ,
"Subset" : { } ,
"SNI" : "web.default.dc4.internal.47e25151-6212-ba25-8b7e-81adbbbab461.consul" ,
"Name" : "web.default.dc4.internal.47e25151-6212-ba25-8b7e-81adbbbab461.consul"
}
}
}
}
{
"Chain" : {
"ServiceName" : "web" ,
"Namespace" : "default" ,
"Datacenter" : "dc1" ,
"Protocol" : "tcp" ,
"StartNode" : "resolver:web.default.dc1" ,
"Nodes" : {
"resolver:web.default.dc1" : {
"Type" : "resolver" ,
"Name" : "web.default.dc1" ,
"Resolver" : {
"ConnectTimeout" : "15s" ,
"Target" : "web.default.dc1" ,
"Failover" : {
"Targets" : [ "web.default.dc3" , "web.default.dc4" ]
}
}
}
} ,
"Targets" : {
"web.default.dc1" : {
"ID" : "web.default.dc1" ,
"Service" : "web" ,
"Namespace" : "default" ,
"Datacenter" : "dc1" ,
"MeshGateway" : { } ,
"Subset" : { } ,
"SNI" : "web.default.dc1.internal.47e25151-6212-ba25-8b7e-81adbbbab461.consul" ,
"Name" : "web.default.dc1.internal.47e25151-6212-ba25-8b7e-81adbbbab461.consul"
} ,
"web.default.dc3" : {
"ID" : "web.default.dc3" ,
"Service" : "web" ,
"Namespace" : "default" ,
"Datacenter" : "dc3" ,
"MeshGateway" : { } ,
"Subset" : { } ,
"SNI" : "web.default.dc3.internal.47e25151-6212-ba25-8b7e-81adbbbab461.consul" ,
"Name" : "web.default.dc3.internal.47e25151-6212-ba25-8b7e-81adbbbab461.consul"
} ,
"web.default.dc4" : {
"ID" : "web.default.dc4" ,
"Service" : "web" ,
"Namespace" : "default" ,
"Datacenter" : "dc4" ,
"MeshGateway" : { } ,
"Subset" : { } ,
"SNI" : "web.default.dc4.internal.47e25151-6212-ba25-8b7e-81adbbbab461.consul" ,
"Name" : "web.default.dc4.internal.47e25151-6212-ba25-8b7e-81adbbbab461.consul"
}
}
}
}
» Datacenter Redirect with OverridesConfig entries defined:
kind = "service-resolver"
name = "web"
redirect {
datacenter = "dc2"
}
kind = "service-resolver"
name = "web"
redirect {
datacenter = "dc2"
}
Request:
$ curl --request POST \
--data '
{
"OverrideConnectTimeout": "7s",
"OverrideProtocol": "grpc",
"OverrideMeshGateway": {
"Mode": "remote"
}
}
' http://127.0.0.1:8500/v1/discovery-chain/web
$ curl --request POST \
--data '
{
"OverrideConnectTimeout": "7s",
"OverrideProtocol": "grpc",
"OverrideMeshGateway": {
"Mode": "remote"
}
}
' http://127.0.0.1:8500/v1/discovery-chain/web
Response:
{
"Chain" : {
"ServiceName" : "web" ,
"Namespace" : "default" ,
"Datacenter" : "dc1" ,
"CustomizationHash" : "b94f529a" ,
"Protocol" : "grpc" ,
"StartNode" : "resolver:web.default.dc2" ,
"Nodes" : {
"resolver:web.default.dc2" : {
"Type" : "resolver" ,
"Name" : "web.default.dc2" ,
"Resolver" : {
"ConnectTimeout" : "7s" ,
"Target" : "web.default.dc2"
}
}
} ,
"Targets" : {
"web.default.dc2" : {
"ID" : "web.default.dc2" ,
"Service" : "web" ,
"Namespace" : "default" ,
"Datacenter" : "dc2" ,
"MeshGateway" : {
"Mode" : "remote"
} ,
"Subset" : { } ,
"SNI" : "web.default.dc2.internal.59c17fd4-8dfa-f54a-ae71-855b26faf637.consul" ,
"Name" : "web.default.dc2.internal.59c17fd4-8dfa-f54a-ae71-855b26faf637.consul"
}
}
}
}
{
"Chain" : {
"ServiceName" : "web" ,
"Namespace" : "default" ,
"Datacenter" : "dc1" ,
"CustomizationHash" : "b94f529a" ,
"Protocol" : "grpc" ,
"StartNode" : "resolver:web.default.dc2" ,
"Nodes" : {
"resolver:web.default.dc2" : {
"Type" : "resolver" ,
"Name" : "web.default.dc2" ,
"Resolver" : {
"ConnectTimeout" : "7s" ,
"Target" : "web.default.dc2"
}
}
} ,
"Targets" : {
"web.default.dc2" : {
"ID" : "web.default.dc2" ,
"Service" : "web" ,
"Namespace" : "default" ,
"Datacenter" : "dc2" ,
"MeshGateway" : {
"Mode" : "remote"
} ,
"Subset" : { } ,
"SNI" : "web.default.dc2.internal.59c17fd4-8dfa-f54a-ae71-855b26faf637.consul" ,
"Name" : "web.default.dc2.internal.59c17fd4-8dfa-f54a-ae71-855b26faf637.consul"
}
}
}
}
» Version Split For Alternate DatacenterConfig entries defined:
kind = "service-resolver"
name = "web"
default_subset = "v1"
subsets = {
"v1" = {
filter = "Service.Meta.version == v1"
}
"v2" = {
filter = "Service.Meta.version == v2"
}
}
kind = "service-defaults"
name = "web"
protocol = "http"
kind = "service-splitter"
name = "web"
splits = [
{
weight = 90
service_subset = "v1"
} ,
{
weight = 10
service_subset = "v2"
} ,
]
kind = "service-resolver"
name = "web"
default_subset = "v1"
subsets = {
"v1" = {
filter = "Service.Meta.version == v1"
}
"v2" = {
filter = "Service.Meta.version == v2"
}
}
kind = "service-defaults"
name = "web"
protocol = "http"
kind = "service-splitter"
name = "web"
splits = [
{
weight = 90
service_subset = "v1"
} ,
{
weight = 10
service_subset = "v2"
} ,
]
Request:
$ curl http://127.0.0.1:8500/v1/discovery-chain/web?compile-dc= dc2
$ curl http://127.0.0.1:8500/v1/discovery-chain/web?compile-dc= dc2
Response:
{
"Chain" : {
"ServiceName" : "web" ,
"Namespace" : "default" ,
"Datacenter" : "dc2" ,
"Protocol" : "http" ,
"StartNode" : "splitter:web" ,
"Nodes" : {
"resolver:v1.web.default.dc2" : {
"Type" : "resolver" ,
"Name" : "v1.web.default.dc2" ,
"Resolver" : {
"ConnectTimeout" : "5s" ,
"Target" : "v1.web.default.dc2"
}
} ,
"resolver:v2.web.default.dc2" : {
"Type" : "resolver" ,
"Name" : "v2.web.default.dc2" ,
"Resolver" : {
"ConnectTimeout" : "5s" ,
"Target" : "v2.web.default.dc2"
}
} ,
"splitter:web" : {
"Type" : "splitter" ,
"Name" : "web" ,
"Splits" : [
{
"Weight" : 90 ,
"NextNode" : "resolver:v1.web.default.dc2"
} ,
{
"Weight" : 10 ,
"NextNode" : "resolver:v2.web.default.dc2"
}
]
}
} ,
"Targets" : {
"v1.web.default.dc2" : {
"ID" : "v1.web.default.dc2" ,
"Service" : "web" ,
"ServiceSubset" : "v1" ,
"Namespace" : "default" ,
"Datacenter" : "dc2" ,
"MeshGateway" : { } ,
"Subset" : {
"Filter" : "Service.Meta.version == v1"
} ,
"SNI" : "v1.web.default.dc2.internal.6c9594ec-d798-28b9-d084-aa03e81cf078.consul" ,
"Name" : "v1.web.default.dc2.internal.6c9594ec-d798-28b9-d084-aa03e81cf078.consul"
} ,
"v2.web.default.dc2" : {
"ID" : "v2.web.default.dc2" ,
"Service" : "web" ,
"ServiceSubset" : "v2" ,
"Namespace" : "default" ,
"Datacenter" : "dc2" ,
"MeshGateway" : { } ,
"Subset" : {
"Filter" : "Service.Meta.version == v2"
} ,
"SNI" : "v2.web.default.dc2.internal.6c9594ec-d798-28b9-d084-aa03e81cf078.consul" ,
"Name" : "v2.web.default.dc2.internal.6c9594ec-d798-28b9-d084-aa03e81cf078.consul"
}
}
}
}
{
"Chain" : {
"ServiceName" : "web" ,
"Namespace" : "default" ,
"Datacenter" : "dc2" ,
"Protocol" : "http" ,
"StartNode" : "splitter:web" ,
"Nodes" : {
"resolver:v1.web.default.dc2" : {
"Type" : "resolver" ,
"Name" : "v1.web.default.dc2" ,
"Resolver" : {
"ConnectTimeout" : "5s" ,
"Target" : "v1.web.default.dc2"
}
} ,
"resolver:v2.web.default.dc2" : {
"Type" : "resolver" ,
"Name" : "v2.web.default.dc2" ,
"Resolver" : {
"ConnectTimeout" : "5s" ,
"Target" : "v2.web.default.dc2"
}
} ,
"splitter:web" : {
"Type" : "splitter" ,
"Name" : "web" ,
"Splits" : [
{
"Weight" : 90 ,
"NextNode" : "resolver:v1.web.default.dc2"
} ,
{
"Weight" : 10 ,
"NextNode" : "resolver:v2.web.default.dc2"
}
]
}
} ,
"Targets" : {
"v1.web.default.dc2" : {
"ID" : "v1.web.default.dc2" ,
"Service" : "web" ,
"ServiceSubset" : "v1" ,
"Namespace" : "default" ,
"Datacenter" : "dc2" ,
"MeshGateway" : { } ,
"Subset" : {
"Filter" : "Service.Meta.version == v1"
} ,
"SNI" : "v1.web.default.dc2.internal.6c9594ec-d798-28b9-d084-aa03e81cf078.consul" ,
"Name" : "v1.web.default.dc2.internal.6c9594ec-d798-28b9-d084-aa03e81cf078.consul"
} ,
"v2.web.default.dc2" : {
"ID" : "v2.web.default.dc2" ,
"Service" : "web" ,
"ServiceSubset" : "v2" ,
"Namespace" : "default" ,
"Datacenter" : "dc2" ,
"MeshGateway" : { } ,
"Subset" : {
"Filter" : "Service.Meta.version == v2"
} ,
"SNI" : "v2.web.default.dc2.internal.6c9594ec-d798-28b9-d084-aa03e81cf078.consul" ,
"Name" : "v2.web.default.dc2.internal.6c9594ec-d798-28b9-d084-aa03e81cf078.consul"
}
}
}
}
» HTTP Path RoutingConfig entries defined:
kind = "service-resolver"
name = "web"
subsets = {
"canary" = {
filter = "Service.Meta.flavor == canary"
}
}
kind = "proxy-defaults"
name = "web"
config {
protocol = "http"
}
kind = "service-router"
name = "web"
routes = [
{
match {
http {
path_prefix = "/admin"
}
}
destination {
service = "admin"
prefix_rewrite = "/"
request_timeout = "15s"
}
} ,
{
match {
http {
header = [
{
name = "x-debug"
exact = "1"
} ,
]
}
}
destination {
service = "web"
service_subset = "canary"
num_retries = 5
retry_on_connect_failure = true
retry_on_status_codes = [ 401 , 409 ]
}
} ,
]
kind = "service-resolver"
name = "web"
subsets = {
"canary" = {
filter = "Service.Meta.flavor == canary"
}
}
kind = "proxy-defaults"
name = "web"
config {
protocol = "http"
}
kind = "service-router"
name = "web"
routes = [
{
match {
http {
path_prefix = "/admin"
}
}
destination {
service = "admin"
prefix_rewrite = "/"
request_timeout = "15s"
}
} ,
{
match {
http {
header = [
{
name = "x-debug"
exact = "1"
} ,
]
}
}
destination {
service = "web"
service_subset = "canary"
num_retries = 5
retry_on_connect_failure = true
retry_on_status_codes = [ 401 , 409 ]
}
} ,
]
Request:
$ curl http://127.0.0.1:8500/v1/discovery-chain/web
$ curl http://127.0.0.1:8500/v1/discovery-chain/web
Response:
{
"Chain" : {
"ServiceName" : "web" ,
"Namespace" : "default" ,
"Datacenter" : "dc1" ,
"Protocol" : "http" ,
"StartNode" : "router:web" ,
"Nodes" : {
"resolver:admin.default.dc1" : {
"Type" : "resolver" ,
"Name" : "admin.default.dc1" ,
"Resolver" : {
"ConnectTimeout" : "5s" ,
"Default" : true ,
"Target" : "admin.default.dc1"
}
} ,
"resolver:canary.web.default.dc1" : {
"Type" : "resolver" ,
"Name" : "canary.web.default.dc1" ,
"Resolver" : {
"ConnectTimeout" : "5s" ,
"Target" : "canary.web.default.dc1"
}
} ,
"resolver:web.default.dc1" : {
"Type" : "resolver" ,
"Name" : "web.default.dc1" ,
"Resolver" : {
"ConnectTimeout" : "5s" ,
"Target" : "web.default.dc1"
}
} ,
"router:web" : {
"Type" : "router" ,
"Name" : "web" ,
"Routes" : [
{
"Definition" : {
"Match" : {
"HTTP" : {
"PathPrefix" : "/admin"
}
} ,
"Destination" : {
"RequestTimeout" : "15s" ,
"Service" : "admin" ,
"PrefixRewrite" : "/"
}
} ,
"NextNode" : "resolver:admin.default.dc1"
} ,
{
"Definition" : {
"Match" : {
"HTTP" : {
"Header" : [
{
"Name" : "x-debug" ,
"Exact" : "1"
}
]
}
} ,
"Destination" : {
"Service" : "web" ,
"ServiceSubset" : "canary" ,
"NumRetries" : 5 ,
"RetryOnConnectFailure" : true ,
"RetryOnStatusCodes" : [ 401 , 409 ]
}
} ,
"NextNode" : "resolver:canary.web.default.dc1"
} ,
{
"Definition" : {
"Match" : {
"HTTP" : {
"PathPrefix" : "/"
}
} ,
"Destination" : {
"Service" : "web"
}
} ,
"NextNode" : "resolver:web.default.dc1"
}
]
}
} ,
"Targets" : {
"admin.default.dc1" : {
"ID" : "admin.default.dc1" ,
"Service" : "admin" ,
"Namespace" : "default" ,
"Datacenter" : "dc1" ,
"MeshGateway" : { } ,
"Subset" : { } ,
"SNI" : "admin.default.dc1.internal.fce8a058-0981-2c04-d23c-b7375af64ce8.consul" ,
"Name" : "admin.default.dc1.internal.fce8a058-0981-2c04-d23c-b7375af64ce8.consul"
} ,
"canary.web.default.dc1" : {
"ID" : "canary.web.default.dc1" ,
"Service" : "web" ,
"ServiceSubset" : "canary" ,
"Namespace" : "default" ,
"Datacenter" : "dc1" ,
"MeshGateway" : { } ,
"Subset" : {
"Filter" : "Service.Meta.flavor == canary"
} ,
"SNI" : "canary.web.default.dc1.internal.fce8a058-0981-2c04-d23c-b7375af64ce8.consul" ,
"Name" : "canary.web.default.dc1.internal.fce8a058-0981-2c04-d23c-b7375af64ce8.consul"
} ,
"web.default.dc1" : {
"ID" : "web.default.dc1" ,
"Service" : "web" ,
"Namespace" : "default" ,
"Datacenter" : "dc1" ,
"MeshGateway" : { } ,
"Subset" : { } ,
"SNI" : "web.default.dc1.internal.fce8a058-0981-2c04-d23c-b7375af64ce8.consul" ,
"Name" : "web.default.dc1.internal.fce8a058-0981-2c04-d23c-b7375af64ce8.consul"
}
}
}
}
{
"Chain" : {
"ServiceName" : "web" ,
"Namespace" : "default" ,
"Datacenter" : "dc1" ,
"Protocol" : "http" ,
"StartNode" : "router:web" ,
"Nodes" : {
"resolver:admin.default.dc1" : {
"Type" : "resolver" ,
"Name" : "admin.default.dc1" ,
"Resolver" : {
"ConnectTimeout" : "5s" ,
"Default" : true ,
"Target" : "admin.default.dc1"
}
} ,
"resolver:canary.web.default.dc1" : {
"Type" : "resolver" ,
"Name" : "canary.web.default.dc1" ,
"Resolver" : {
"ConnectTimeout" : "5s" ,
"Target" : "canary.web.default.dc1"
}
} ,
"resolver:web.default.dc1" : {
"Type" : "resolver" ,
"Name" : "web.default.dc1" ,
"Resolver" : {
"ConnectTimeout" : "5s" ,
"Target" : "web.default.dc1"
}
} ,
"router:web" : {
"Type" : "router" ,
"Name" : "web" ,
"Routes" : [
{
"Definition" : {
"Match" : {
"HTTP" : {
"PathPrefix" : "/admin"
}
} ,
"Destination" : {
"RequestTimeout" : "15s" ,
"Service" : "admin" ,
"PrefixRewrite" : "/"
}
} ,
"NextNode" : "resolver:admin.default.dc1"
} ,
{
"Definition" : {
"Match" : {
"HTTP" : {
"Header" : [
{
"Name" : "x-debug" ,
"Exact" : "1"
}
]
}
} ,
"Destination" : {
"Service" : "web" ,
"ServiceSubset" : "canary" ,
"NumRetries" : 5 ,
"RetryOnConnectFailure" : true ,
"RetryOnStatusCodes" : [ 401 , 409 ]
}
} ,
"NextNode" : "resolver:canary.web.default.dc1"
} ,
{
"Definition" : {
"Match" : {
"HTTP" : {
"PathPrefix" : "/"
}
} ,
"Destination" : {
"Service" : "web"
}
} ,
"NextNode" : "resolver:web.default.dc1"
}
]
}
} ,
"Targets" : {
"admin.default.dc1" : {
"ID" : "admin.default.dc1" ,
"Service" : "admin" ,
"Namespace" : "default" ,
"Datacenter" : "dc1" ,
"MeshGateway" : { } ,
"Subset" : { } ,
"SNI" : "admin.default.dc1.internal.fce8a058-0981-2c04-d23c-b7375af64ce8.consul" ,
"Name" : "admin.default.dc1.internal.fce8a058-0981-2c04-d23c-b7375af64ce8.consul"
} ,
"canary.web.default.dc1" : {
"ID" : "canary.web.default.dc1" ,
"Service" : "web" ,
"ServiceSubset" : "canary" ,
"Namespace" : "default" ,
"Datacenter" : "dc1" ,
"MeshGateway" : { } ,
"Subset" : {
"Filter" : "Service.Meta.flavor == canary"
} ,
"SNI" : "canary.web.default.dc1.internal.fce8a058-0981-2c04-d23c-b7375af64ce8.consul" ,
"Name" : "canary.web.default.dc1.internal.fce8a058-0981-2c04-d23c-b7375af64ce8.consul"
} ,
"web.default.dc1" : {
"ID" : "web.default.dc1" ,
"Service" : "web" ,
"Namespace" : "default" ,
"Datacenter" : "dc1" ,
"MeshGateway" : { } ,
"Subset" : { } ,
"SNI" : "web.default.dc1.internal.fce8a058-0981-2c04-d23c-b7375af64ce8.consul" ,
"Name" : "web.default.dc1.internal.fce8a058-0981-2c04-d23c-b7375af64ce8.consul"
}
}
}
}
» Methods to Specify Namespace Enterprise
The discovery chain endpoint
supports several methods for specifying the namespace to use as the basis of discovery chain compilation
with the following order of precedence:
ns
query parameterX-Consul-Namespace
request headerNamespace is inherited from the namespace of the request's ACL token (if any) The default
namespace