»Discovery Chain HTTP Endpoint

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 Chain

If overrides are needed they are passed as the JSON-encoded request body and the POST method must be used, otherwise GET is sufficient.

MethodPathProduces
GET/discovery-chain/:serviceapplication/json
POST1/discovery-chain/:serviceapplication/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 QueriesConsistency ModesAgent CachingACL Required
YESallbackground refreshservice:read

»URL Parameters

  • service (string: <required>) - Specifies the service to query when compiling the discovery chain. This is provided as part of the URL.

  • compile-dc (string: "") - Specifies the datacenter to use as the basis of compilation. This will default to the datacenter of the agent being queried. This is specified as part of the URL as a query parameter.

    This value comes from an upstream configuration datacenter parameter.

»POST Body Parameters

»Sample Compilations

Full documentation for the output fields is found on the discovery chain internals page.

»Multi-Datacenter Failover

Config 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 Overrides

Config entries defined:

kind            = "service-resolver"
name            = "web"
redirect {
  datacenter = "dc2"
}
kind            = "service-resolver"name            = "web"redirect {  datacenter = "dc2"}

Request:

$ curl -X POST \
    -d'
{
    "OverrideConnectTimeout": "7s",
    "OverrideProtocol": "grpc",
    "OverrideMeshGateway": {
        "Mode": "remote"
    }
}
' http://127.0.0.1:8500/v1/discovery-chain/web
$ curl -X POST \    -d'{    "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 Datacenter

Config 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 Routing

Config 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"      }    }  }}