github.com/outbrain/consul@v1.4.5/website/source/api/query.html.md (about) 1 --- 2 layout: api 3 page_title: Prepared Queries - HTTP API 4 sidebar_current: api-query 5 description: |- 6 The /query endpoints manage and execute prepared queries in Consul. 7 --- 8 9 # Prepared Query HTTP Endpoint 10 11 The `/query` endpoints create, update, destroy, and execute prepared queries. 12 13 Prepared queries allow you to register a complex service query and then execute 14 it later via its ID or name to get a set of healthy nodes that provide a given 15 service. This is particularly useful in combination with Consul's 16 [DNS Interface](/docs/agent/dns.html) as it allows for much richer queries than 17 would be possible given the limited entry points exposed by DNS. 18 19 See the [Geo Failover Guide](/docs/guides/geo-failover.html) for details and 20 examples for using prepared queries to implement geo failover for services. 21 22 See the [prepared query rules](/docs/agent/acl-rules.html#prepared-query-rules) 23 section of the agent ACL documentation for more details about how prepared 24 queries work with Consul's ACL system. 25 26 ### Prepared Query Templates 27 28 Consul 0.6.4 and later support prepared query templates. These are created 29 similar to static queries, except with some additional fields and features. 30 Here is an example prepared query template: 31 32 ```json 33 { 34 "Template": { 35 "Type": "name_prefix_match", 36 "Regexp": "^geo-db-(.*?)-([^\\-]+?)$", 37 "RemoveEmptyTags": false 38 } 39 } 40 ``` 41 42 The `Template` structure configures a prepared query as a template instead of a 43 static query. It has two fields: 44 45 - `Type` is the query type, which must be `name_prefix_match`. This means that 46 the template will apply to any query lookup with a name whose prefix matches 47 the `Name` field of the template. In this example, any query for `geo-db` will 48 match this query. Query templates are resolved using a longest prefix match, 49 so it's possible to have high-level templates that are overridden for specific 50 services. Static queries are always resolved first, so they can also override 51 templates. 52 53 - `Regexp` is an optional regular expression which is used to extract fields 54 from the entire name, once this template is selected. In this example, the 55 regular expression takes the first item after the "-" as the database name and 56 everything else after as a tag. See the 57 [RE2](https://github.com/google/re2/wiki/Syntax) reference for syntax of this 58 regular expression. 59 60 - `RemoveEmptyTags` is optional, and if set to true, will cause the `Tags` list 61 inside the `Service` structure to be stripped of any empty strings. This defaults 62 to false, meaning that empty strings will remain in the list. This is useful 63 when interpolating into tags in a way where the tag is optional, and where 64 searching for an empty tag would yield no results from the query. 65 66 All other fields of the query have the same meanings as for a static query, 67 except that several interpolation variables are available to dynamically 68 populate the query before it is executed. All of the string fields inside the 69 `Service` structure are interpolated, with the following variables available: 70 71 - `${name.full}` has the entire name that was queried. For example, a DNS lookup 72 for `geo-db-customer-primary.query.consul` in the example above would set this 73 variable to `geo-db-customer-primary`. 74 75 - `${name.prefix}` has the prefix that matched. This would always be `geo-db` 76 for the example above. 77 78 - `${name.suffix}` has the suffix after the prefix. For example, a DNS lookup 79 for `geo-db-customer-primary.query.consul` in the example above would set this 80 variable to `-customer-primary`. 81 82 - `${match(N)}` returns the regular expression match at the given index N. The 0 83 index will have the entire match, and >0 will have the results of each match 84 group. For example, a DNS lookup for `geo-db-customer-primary.query.consul` in 85 the example above with a `Regexp` field set to `^geo-db-(.*?)-([^\-]+?)$` 86 would return `geo-db-customer-primary` for `${match(0)}`, `customer` for 87 `${match(1)}`, and `primary` for `${match(2)}`. If the regular expression 88 doesn't match, or an invalid index is given, then `${match(N)}` will return an 89 empty string. 90 91 - `${agent.segment}` has the network segment (Enterprise-only) of the agent that 92 initiated the query. This can be used with the `NodeMeta` field to limit the results 93 of a query to service instances within its own network segment: 94 95 ```json 96 { 97 "Name": "", 98 "Template": { 99 "Type": "name_prefix_match" 100 }, 101 "Service": { 102 "Service": "${name.full}", 103 "NodeMeta": {"consul-network-segment": "${agent.segment}"} 104 } 105 } 106 ``` 107 This will map all names of the form `<service>.query.consul` over DNS to a query 108 that will select an instance of the service in the agent's own network segment. 109 110 Using templates, it is possible to apply prepared query behaviors to many 111 services with a single template. Here's an example template that matches any 112 query and applies a failover policy to it: 113 114 ```json 115 { 116 "Name": "", 117 "Template": { 118 "Type": "name_prefix_match" 119 }, 120 "Service": { 121 "Service": "${name.full}", 122 "Failover": { 123 "NearestN": 3 124 } 125 } 126 } 127 ``` 128 129 This will match any lookup for `*.query.consul` and will attempt to find the 130 service locally, and otherwise attempt to find that service in the next three 131 closest datacenters. If ACLs are enabled, a catch-all template like this with 132 an empty `Name` requires an ACL token that can write to any query prefix. Also, 133 only a single catch-all template can be registered at any time. 134 135 ## Create Prepared Query 136 137 This endpoint creates a new prepared query and returns its ID if it is created 138 successfully. 139 140 | Method | Path | Produces | 141 | ------ | ---------------------------- | -------------------------- | 142 | `POST` | `/query` | `application/json` | 143 144 The table below shows this endpoint's support for 145 [blocking queries](/api/index.html#blocking-queries), 146 [consistency modes](/api/index.html#consistency-modes), 147 [agent caching](/api/index.html#agent-caching), and 148 [required ACLs](/api/index.html#acls). 149 150 | Blocking Queries | Consistency Modes | Agent Caching | ACL Required | 151 | ---------------- | ----------------- | ------------- | ------------- | 152 | `NO` | `none` | `none` | `query:write` | 153 154 ### Parameters 155 156 - `dc` `(string: "")` - Specifies the datacenter to query. This will default to 157 the datacenter of the agent being queried. This is specified as part of the 158 URL as a query parameter. 159 160 - `Name` `(string: "")` - Specifies an optional friendly name that can be used 161 to execute a query instead of using its ID. 162 163 - `Session` `(string: "")` - Specifies the ID of an existing session. This 164 provides a way to automatically remove a prepared query when the given session 165 is invalidated. If not given the prepared query must be manually removed when 166 no longer needed. 167 168 - `Token` `(string: "")` - Specifies the ACL token to use each time the query is 169 executed. This allows queries to be executed by clients with lesser or even no 170 ACL Token, so this should be used with care. The token itself can only be seen 171 by clients with a management token. If the `Token` field is left blank or 172 omitted, the client's ACL Token will be used to determine if they have access 173 to the service being queried. If the client does not supply an ACL Token, the 174 anonymous token will be used. 175 176 - `Service` `(Service: <required>)` - Specifies the structure to define the query's behavior. 177 178 - `Service` `(string: <required>)` - Specifies the name of the service to 179 query. 180 181 - `Failover` contains two fields, both of which are optional, and determine 182 what happens if no healthy nodes are available in the local datacenter when 183 the query is executed. It allows the use of nodes in other datacenters with 184 very little configuration. 185 186 - `NearestN` `(int: 0)` - Specifies that the query will be forwarded to up 187 to `NearestN` other datacenters based on their estimated network round 188 trip time using [Network Coordinates](/docs/internals/coordinates.html) 189 from the WAN gossip pool. The median round trip time from the server 190 handling the query to the servers in the remote datacenter is used to 191 determine the priority. 192 193 - `Datacenters` `(array<string>: nil)` - Specifies a fixed list of remote 194 datacenters to forward the query to if there are no healthy nodes in the 195 local datacenter. Datacenters are queried in the order given in the 196 list. If this option is combined with `NearestN`, then the `NearestN` 197 queries will be performed first, followed by the list given by 198 `Datacenters`. A given datacenter will only be queried one time during a 199 failover, even if it is selected by both `NearestN` and is listed in 200 `Datacenters`. 201 202 - `IgnoreCheckIDs` `(array<string>: nil)` - Specifies a list of check IDs that 203 should be ignored when filtering unhealthy instances. This is mostly useful 204 in an emergency or as a temporary measure when a health check is found to be 205 unreliable. Being able to ignore it in centrally-defined queries can be 206 simpler than de-registering the check as an interim solution until the check 207 can be fixed. 208 209 - `OnlyPassing` `(bool: false)` - Specifies the behavior of the query's health 210 check filtering. If this is set to false, the results will include nodes 211 with checks in the passing as well as the warning states. If this is set to 212 true, only nodes with checks in the passing state will be returned. 213 214 - `Near` `(string: "")` - Specifies a node to sort near based on distance 215 sorting using [Network Coordinates](/docs/internals/coordinates.html). The 216 nearest instance to the specified node will be returned first, and subsequent 217 nodes in the response will be sorted in ascending order of estimated 218 round-trip times. If the node given does not exist, the nodes in the response 219 will be shuffled. If unspecified, the response will be shuffled by default. 220 221 - `_agent` - Returns results nearest the agent servicing the request. 222 - `_ip` - Returns results nearest to the node associated with the source IP 223 where the query was executed from. For HTTP the source IP is the remote 224 peer's IP address or the value of the X-Forwarded-For header with the 225 header taking precedence. For DNS the source IP is the remote peer's IP 226 address or the value of the ENDS client IP with the EDNS client IP 227 taking precedence. 228 229 230 - `Tags` `(array<string>: nil)` - Specifies a list of service tags to filter 231 the query results. For a service to pass the tag filter it must have *all* 232 of the required tags, and *none* of the excluded tags (prefixed with `!`). 233 234 - `NodeMeta` `(map<string|string>: nil)` - Specifies a list of user-defined 235 key/value pairs that will be used for filtering the query results to nodes 236 with the given metadata values present. 237 238 - `ServiceMeta` `(map<string|string>: nil)` - Specifies a list of user-defined 239 key/value pairs that will be used for filtering the query results to services 240 with the given metadata values present. 241 242 - `Connect` `(bool: false)` - If true, only [Connect-capable](/docs/connect/index.html) services 243 for the specified service name will be returned. This includes both 244 natively integrated services and proxies. For proxies, the proxy name 245 may not match `Service`, because the proxy destination will. Any 246 constrains beyond the service name such as `Near`, `Tags`, and `NodeMeta` 247 are applied to Connect-capable service. 248 249 - `DNS` `(DNS: nil)` - Specifies DNS configuration 250 251 - `TTL` `(string: "")` - Specifies the TTL duration when query results are 252 served over DNS. If this is specified, it will take precedence over any 253 Consul agent-specific configuration. 254 255 ### Sample Payload 256 257 ```json 258 { 259 "Name": "my-query", 260 "Session": "adf4238a-882b-9ddc-4a9d-5b6758e4159e", 261 "Token": "", 262 "Service": { 263 "Service": "redis", 264 "Failover": { 265 "NearestN": 3, 266 "Datacenters": ["dc1", "dc2"] 267 }, 268 "Near": "node1", 269 "OnlyPassing": false, 270 "Tags": ["primary", "!experimental"], 271 "NodeMeta": {"instance_type": "m3.large"}, 272 "ServiceMeta": {"environment": "production"} 273 }, 274 "DNS": { 275 "TTL": "10s" 276 } 277 } 278 ``` 279 280 ### Sample Request 281 282 ```text 283 $ curl \ 284 --request POST \ 285 --data @payload.json \ 286 http://127.0.0.1:8500/v1/query 287 ``` 288 289 ### Sample Response 290 291 ```json 292 { 293 "ID": "8f246b77-f3e1-ff88-5b48-8ec93abf3e05" 294 } 295 ``` 296 297 ## Read Prepared Query 298 299 This endpoint returns a list of all prepared queries. 300 301 | Method | Path | Produces | 302 | ------ | ---------------------------- | -------------------------- | 303 | `GET` | `/query` | `application/json` | 304 305 The table below shows this endpoint's support for 306 [blocking queries](/api/index.html#blocking-queries), 307 [consistency modes](/api/index.html#consistency-modes), 308 [agent caching](/api/index.html#agent-caching), and 309 [required ACLs](/api/index.html#acls). 310 311 | Blocking Queries | Consistency Modes | Agent Caching | ACL Required | 312 | ---------------- | ----------------- | ------------- | ------------ | 313 | `NO` | `none` | `none` | `query:read` | 314 315 ### Parameters 316 317 - `dc` `(string: "")` - Specifies the datacenter to query. This will default to 318 the datacenter of the agent being queried. This is specified as part of the 319 URL as a query parameter. 320 321 ### Sample Request 322 323 ```text 324 $ curl \ 325 http://127.0.0.1:8500/v1/query 326 ``` 327 328 ### Sample Response 329 330 ```json 331 [ 332 { 333 "ID": "8f246b77-f3e1-ff88-5b48-8ec93abf3e05", 334 "Name": "my-query", 335 "Session": "adf4238a-882b-9ddc-4a9d-5b6758e4159e", 336 "Token": "<hidden>", 337 "Service": { 338 "Service": "redis", 339 "Failover": { 340 "NearestN": 3, 341 "Datacenters": ["dc1", "dc2"] 342 }, 343 "OnlyPassing": false, 344 "Tags": ["primary", "!experimental"], 345 "NodeMeta": {"instance_type": "m3.large"}, 346 "ServiceMeta": {"environment": "production"} 347 }, 348 "DNS": { 349 "TTL": "10s" 350 }, 351 "RaftIndex": { 352 "CreateIndex": 23, 353 "ModifyIndex": 42 354 } 355 } 356 ] 357 ``` 358 359 ### Update Prepared Query 360 361 This endpoint updates an existing prepared query. If no query exists by the 362 given ID, an error is returned. 363 364 | Method | Path | Produces | 365 | ------ | ---------------------------- | -------------------------- | 366 | `PUT` | `/query/:uuid` | `application/json` | 367 368 The table below shows this endpoint's support for 369 [blocking queries](/api/index.html#blocking-queries), 370 [consistency modes](/api/index.html#consistency-modes), 371 [agent caching](/api/index.html#agent-caching), and 372 [required ACLs](/api/index.html#acls). 373 374 | Blocking Queries | Consistency Modes | Agent Caching | ACL Required | 375 | ---------------- | ----------------- | ------------- | ------------- | 376 | `NO` | `none` | `none` | `query:write` | 377 378 ### Parameters 379 380 - `uuid` `(string: <required>)` - Specifies the UUID of the query to update. 381 This is required and is specified as part of the URL path. 382 383 - `dc` `(string: "")` - Specifies the datacenter to query. This will default to 384 the datacenter of the agent being queried. This is specified as part of the 385 URL as a query parameter. 386 387 The body is the same as is used to create a prepared query. Please see above for 388 more information. 389 390 ### Sample Request 391 392 ```text 393 $ curl \ 394 --request PUT \ 395 --data @payload.json \ 396 http://127.0.0.1:8500/v1/query/8f246b77-f3e1-ff88-5b48-8ec93abf3e05 397 ``` 398 399 ## Read Prepared Query 400 401 This endpoint reads an existing prepared query. If no query exists by the 402 given ID, an error is returned. 403 404 | Method | Path | Produces | 405 | ------ | ---------------------------- | -------------------------- | 406 | `GET` | `/query/:uuid` | `application/json` | 407 408 The table below shows this endpoint's support for 409 [blocking queries](/api/index.html#blocking-queries), 410 [consistency modes](/api/index.html#consistency-modes), 411 [agent caching](/api/index.html#agent-caching), and 412 [required ACLs](/api/index.html#acls). 413 414 | Blocking Queries | Consistency Modes | Agent Caching | ACL Required | 415 | ---------------- | ----------------- | ------------- | ------------ | 416 | `NO` | `none` | `none` | `query:read` | 417 418 ### Parameters 419 420 - `uuid` `(string: <required>)` - Specifies the UUID of the query to read. 421 This is required and is specified as part of the URL path. 422 423 - `dc` `(string: "")` - Specifies the datacenter to query. This will default to 424 the datacenter of the agent being queried. This is specified as part of the 425 URL as a query parameter. 426 427 ### Sample Request 428 429 ```text 430 $ curl \ 431 http://127.0.0.1:8500/v1/query/8f246b77-f3e1-ff88-5b48-8ec93abf3e05 432 ``` 433 434 ### Sample Response 435 436 The returned response is the same as the list of prepared queries above, only 437 with a single item present. 438 439 ## Delete Prepared Query 440 441 This endpoint deletes an existing prepared query. If no query exists by the 442 given ID, an error is returned. 443 444 | Method | Path | Produces | 445 | --------- | ---------------------------- | -------------------------- | 446 | `DELETE` | `/query/:uuid` | `application/json` | 447 448 The table below shows this endpoint's support for 449 [blocking queries](/api/index.html#blocking-queries), 450 [consistency modes](/api/index.html#consistency-modes), 451 [agent caching](/api/index.html#agent-caching), and 452 [required ACLs](/api/index.html#acls). 453 454 | Blocking Queries | Consistency Modes | Agent Caching | ACL Required | 455 | ---------------- | ----------------- | ------------- | ------------- | 456 | `NO` | `none` | `none` | `query:write` | 457 458 ### Parameters 459 460 - `uuid` `(string: <required>)` - Specifies the UUID of the query to delete. 461 This is required and is specified as part of the URL path. 462 463 - `dc` `(string: "")` - Specifies the datacenter to query. This will default to 464 the datacenter of the agent being queried. This is specified as part of the 465 URL as a query parameter. 466 467 ### Sample Request 468 469 ```text 470 $ curl \ 471 --request DELETE \ 472 http://127.0.0.1:8500/v1/query/8f246b77-f3e1-ff88-5b48-8ec93abf3e05 473 ``` 474 475 ## Execute Prepared Query 476 477 This endpoint executes an existing prepared query. If no query exists by the 478 given ID, an error is returned. 479 480 | Method | Path | Produces | 481 | ------ | ---------------------------- | -------------------------- | 482 | `GET` | `/query/:uuid/execute` | `application/json` | 483 484 The table below shows this endpoint's support for 485 [blocking queries](/api/index.html#blocking-queries), 486 [consistency modes](/api/index.html#consistency-modes), 487 [agent caching](/api/index.html#agent-caching), and 488 [required ACLs](/api/index.html#acls). 489 490 | Blocking Queries | Consistency Modes | Agent Caching | ACL Required | 491 | ---------------- | ----------------- | ------------- | ------------ | 492 | `NO` | `none` | `simple` | `depends`<sup>1</sup> | 493 494 <sup>1</sup> If an ACL Token was bound to the query when it was defined then it 495 will be used when executing the request. Otherwise, the client's supplied ACL 496 Token will be used. 497 498 ### Parameters 499 500 - `uuid` `(string: <required>)` - Specifies the UUID of the query to execute. 501 This is required and is specified as part of the URL path. This can also be 502 the name of an existing prepared query, or a name that matches a prefix name 503 for a prepared query template. 504 505 - `dc` `(string: "")` - Specifies the datacenter to query. This will default to 506 the datacenter of the agent being queried. This is specified as part of the 507 URL as a query parameter. 508 509 - `near` `(string: "")` - Specifies to sort the resulting list in ascending 510 order based on the estimated round trip time from that node. Passing 511 `?near=_agent` will use the agent's node for the sort. Passing `?near=_ip` 512 will use the source IP of the request or the value of the X-Forwarded-For 513 header to lookup the node to use for the sort. If this is not present, 514 the default behavior will shuffle the nodes randomly each time the query is 515 executed. 516 517 - `limit` `(int: 0)` - Limit the size of the list to the given number of nodes. 518 This is applied after any sorting or shuffling. 519 520 - `connect` `(bool: false)` - If true, limit results to nodes that are 521 Connect-capable only. This can also be specified directly on the template 522 itself to force all executions of a query to be Connect-only. See the 523 template documentation for more information. 524 525 ### Sample Request 526 527 ```text 528 $ curl \ 529 http://127.0.0.1:8500/v1/query/8f246b77-f3e1-ff88-5b48-8ec93abf3e05/execute?near=_agent 530 ``` 531 532 ### Sample Response 533 534 ```json 535 { 536 "Service": "redis", 537 "Nodes": [ 538 { 539 "Node": { 540 "ID": "40e4a748-2192-161a-0510-9bf59fe950b5", 541 "Node": "foobar", 542 "Address": "10.1.10.12", 543 "Datacenter": "dc1", 544 "TaggedAddresses": { 545 "lan": "10.1.10.12", 546 "wan": "10.1.10.12" 547 }, 548 "NodeMeta": {"instance_type": "m3.large"} 549 }, 550 "Service": { 551 "ID": "redis", 552 "Service": "redis", 553 "Tags": null, 554 "Meta": {"redis_version": "4.0"}, 555 "Port": 8000 556 }, 557 "Checks": [ 558 { 559 "Node": "foobar", 560 "CheckID": "service:redis", 561 "Name": "Service 'redis' check", 562 "Status": "passing", 563 "Notes": "", 564 "Output": "", 565 "ServiceID": "redis", 566 "ServiceName": "redis" 567 }, 568 { 569 "Node": "foobar", 570 "CheckID": "serfHealth", 571 "Name": "Serf Health Status", 572 "Status": "passing", 573 "Notes": "", 574 "Output": "", 575 "ServiceID": "", 576 "ServiceName": "" 577 } 578 ], 579 "DNS": { 580 "TTL": "10s" 581 }, 582 "Datacenter": "dc3", 583 "Failovers": 2 584 }] 585 } 586 ``` 587 588 - `Nodes` contains the list of healthy nodes providing the given service, as 589 specified by the constraints of the prepared query. 590 591 - `Service` has the service name that the query was selecting. This is useful 592 for context in case an empty list of nodes is returned. 593 594 - `DNS` has information used when serving the results over DNS. This is just a 595 copy of the structure given when the prepared query was created. 596 597 - `Datacenter` has the datacenter that ultimately provided the list of nodes and 598 `Failovers` has the number of remote datacenters that were queried while 599 executing the query. This provides some insight into where the data came from. 600 This will be zero during non-failover operations where there were healthy 601 nodes found in the local datacenter. 602 603 ## Explain Prepared Query 604 605 This endpoint generates a fully-rendered query for a given name, post 606 interpolation. 607 608 | Method | Path | Produces | 609 | ------ | ---------------------------- | -------------------------- | 610 | `GET` | `/query/:uuid/explain` | `application/json` | 611 612 The table below shows this endpoint's support for 613 [blocking queries](/api/index.html#blocking-queries), 614 [consistency modes](/api/index.html#consistency-modes), 615 [agent caching](/api/index.html#agent-caching), and 616 [required ACLs](/api/index.html#acls). 617 618 | Blocking Queries | Consistency Modes | Agent Caching | ACL Required | 619 | ---------------- | ----------------- | ------------- | ------------ | 620 | `NO` | `none` | `none` | `query:read` | 621 622 ### Parameters 623 624 - `uuid` `(string: <required>)` - Specifies the UUID of the query to explain. 625 This is required and is specified as part of the URL path. This can also be 626 the name of an existing prepared query, or a name that matches a prefix name 627 for a prepared query template. 628 629 - `dc` `(string: "")` - Specifies the datacenter to query. This will default to 630 the datacenter of the agent being queried. This is specified as part of the 631 URL as a query parameter. 632 633 ### Sample Request 634 635 ```text 636 $ curl \ 637 http://127.0.0.1:8500/v1/query/8f246b77-f3e1-ff88-5b48-8ec93abf3e05/explain 638 ``` 639 640 ### Sample Response 641 642 ```json 643 { 644 "Query": { 645 "ID": "8f246b77-f3e1-ff88-5b48-8ec93abf3e05", 646 "Name": "my-query", 647 "Session": "adf4238a-882b-9ddc-4a9d-5b6758e4159e", 648 "Token": "<hidden>", 649 "Name": "geo-db", 650 "Template": { 651 "Type": "name_prefix_match", 652 "Regexp": "^geo-db-(.*?)-([^\\-]+?)$" 653 }, 654 "Service": { 655 "Service": "mysql-customer", 656 "Failover": { 657 "NearestN": 3, 658 "Datacenters": ["dc1", "dc2"] 659 }, 660 "OnlyPassing": true, 661 "Tags": ["primary"], 662 "Meta": { "mysql_version": "5.7.20" }, 663 "NodeMeta": {"instance_type": "m3.large"} 664 } 665 } 666 } 667 ```