How to render tag filter into query target for service list query

Hi there!

I have a question how to render my intention of using a filter in a query. I want to do Service - Agent - HTTP API | Consul by HashiCorp query with tag filtering: pass condition => one of the tags is in the specific list.

The description doesn’t say how technically to express this in the HTTP image of request. I’m not from web background, and with the given description I assume that machinery with filters (which are part of query parameters) is kind of a standard thing, but I have no web background so its not evident to me.
I want to integrate with Consul from C++ application (using https://github.com/boostorg/beast if that makes any difference) so I can understand the machinery on the level of raw HTTP messages (I can write the code that will produce a necessary HTTP message once I know how it should look like).
For Service field I’ve managed to “render” the filter properly:

GET /v1/agent/services?filter=Service=="THESERVICE" HTTP/1.1
header-fields

For Tags All that I try seems not to work:
Try: GET /v1/agent/services?filter=Tags In [“fake-service”] HTTP/1.1
Result: 400 Bad Request

Try: GET /v1/agent/services?filter=Tags%20In%20[“fake-service”] HTTP/1.1
Result: Failed to create boolean expression evaluator: 1:6 (5): no match found, expected: “!=”, “==”, “contains”, “in”, “is”, “matches”, “not” or [ \t\r\n]

Try: GET /v1/agent/services?filter=Tags%20in%20[“fake-service”] HTTP/1.1
Result: Failed to create boolean expression evaluator: 1:9 (8): rule “match”: Invalid selector

Can you, please, give me a link to description or maybe a curl example using Tags filter?

Hi @ngrodzitski,

I think you’re close to having this work. The filter just needs to be URL encoded prior to sending the request to Consul.

Here’s an example Python script which queries /v1/agent/services with a url-encoded filter that only returns a service matching the name web.

#!/usr/bin/env python3
#
# filter-example.py

import json
import os
from urllib.request import Request, urlopen
from urllib.parse import urlencode, urljoin

def main():

    consul_addr = os.getenv("CONSUL_HTTP_ADDR", "http://localhost:8500")

    url = urljoin(consul_addr, "/v1/agent/services")
    query_filter = urlencode({"filter": "Service==\"web\""})

    request = Request(url="{}?{}".format(url, query_filter), method="GET")
    response = urlopen(request)

    if response.status == 200:
        response = json.load(response)
        print(json.dumps(response, indent=2))

if __name__ == "__main__":
    main()

$ ./filter-example.py
{
  "web1": {
    "ID": "web1",
    "Service": "web",
    "Tags": [
      "rails"
    ],
    "Meta": {},
    "Port": 80,
    "Address": "",
    "SocketPath": "",
    "Weights": {
      "Passing": 1,
      "Warning": 1
    },
    "EnableTagOverride": false,
    "Datacenter": "dc1"
  }
}

Thanks for your script.
A bit late response, but anyway, that what I was looking for:
query_filter = urlencode({"filter": "\"xxx\" in Tags or \"yyy\" in Tags"}), the essential part is "xxx" in Tags or "yyy" in Tags.