Filtering and Querying

Transform response data using JMESPath expressions or bash/Linux commands.

Filter vs Query

Filter: Narrow down results (subset of data)

Query: Transform structure (reshape data)

Both work together in sequence: filter first, then query.

Supported Formats

Two options available:

  1. JMESPath: AWS CLI-style expressions for JSON
  2. Bash/Linux commands: Any shell command using $(command) syntax

Both work in CLI flags, request files, and profile defaults.

JMESPath Syntax

AWS CLI-style expressions for JSON transformation.

CLI Usage

Filter:

restcli --filter "items[?status==\`active\`]" request.http

Query:

restcli --query "[].name" request.http

Or short form:

restcli -q "[].name" request.http

Combined:

restcli --filter "users[?age>\`18\`]" --query "[].email" request.http

Request Files

HTTP format:

### Get Active Users
# @filter users[?active==`true`]
# @query [].{name: name, email: email}
GET https://api.example.com/users

YAML format:

name: Get Active Users
method: GET
url: "https://api.example.com/users"
filter: "users[?active==`true`]"
query: "[].{name: name, email: email}"

JSON format:

{
  "name": "Get Active Users",
  "method": "GET",
  "url": "https://api.example.com/users",
  "filter": "users[?active==`true`]",
  "query": "[].{name: name, email: email}"
}

Profile Defaults

In .profiles.json:

{
  "name": "API",
  "defaultFilter": "results[?status==`active`]",
  "defaultQuery": "[].{id: id, name: name}"
}

Applied to all requests unless overridden.

JMESPath Examples

Basic Selection

Select field:

data.users

Array element:

users[0]

Multiple fields:

{name: name, email: email}

Filtering

Active items:

items[?active==`true`]

Age greater than 18:

users[?age>`18`]

Status equals value:

results[?status==`completed`]

Projection

Extract field from array:

users[].name

Transform array:

users[].{id: id, name: name, email: contact.email}

Functions

Length:

length(items)

Sort:

sort_by(users, &age)

Max value:

max_by(products, &price)

Bash/Linux Command Syntax

Use $(command) to pipe response through any bash/Linux command.

Response is piped to stdin of the command.

CLI Usage

With jq:

restcli --query '$(jq ".items[].name")' request.http

With grep:

restcli --query '$(grep -o "id.*")' request.http

With filter and query:

restcli --filter '$(jq ".items")' --query '$(jq ".[].name")' request.http

Request Files

HTTP format:

### Get Names
# @query $(jq '.users[].name')
GET https://api.example.com/users

YAML format:

name: Get Names
method: GET
url: "https://api.example.com/users"
query: "$(jq '.users[].name')"

JSON format:

{
  "name": "Get Names",
  "method": "GET",
  "url": "https://api.example.com/users",
  "query": "$(jq '.users[].name')"
}

Examples

Extract with jq:

$(jq '.items[].name')

Grep pattern:

$(grep -o '"id":[0-9]*')

Count lines:

$(wc -l)

Format with awk:

$(awk '{print $1, $3}')

Sort results:

$(sort)

Unique values:

$(sort | uniq)

Chain commands:

$(jq '.items[]' | grep active | wc -l)

Complex pipeline:

$(jq -r '.users[].email' | sort | uniq | wc -l)

Priority

Filters and queries apply in this order:

  1. CLI flags (highest)
  2. Request file
  3. Profile defaults (lowest)

Higher priority overrides lower.

Examples

Filter Active Users

Response:

{
  "users": [
    {"id": 1, "name": "Alice", "active": true},
    {"id": 2, "name": "Bob", "active": false},
    {"id": 3, "name": "Charlie", "active": true}
  ]
}

Filter:

users[?active==`true`]

Result:

[
  {"id": 1, "name": "Alice", "active": true},
  {"id": 3, "name": "Charlie", "active": true}
]

Transform Structure

Response:

{
  "data": {
    "users": [
      {"id": 1, "name": "Alice", "contact": {"email": "[email protected]"}},
      {"id": 2, "name": "Bob", "contact": {"email": "[email protected]"}}
    ]
  }
}

Query:

data.users[].{id: id, name: name, email: contact.email}

Result:

[
  {"id": 1, "name": "Alice", "email": "[email protected]"},
  {"id": 2, "name": "Bob", "email": "[email protected]"}
]

Filter and Query Combined

Response:

{
  "products": [
    {"id": 1, "name": "Widget", "price": 10, "inStock": true},
    {"id": 2, "name": "Gadget", "price": 20, "inStock": false},
    {"id": 3, "name": "Tool", "price": 15, "inStock": true}
  ]
}

Filter:

products[?inStock==`true`]

Query:

[].{name: name, price: price}

Result:

[
  {"name": "Widget", "price": 10},
  {"name": "Tool", "price": 15}
]

Using jq for Complex Logic

Response:

{
  "items": [
    {"category": "A", "values": [1, 2, 3]},
    {"category": "B", "values": [4, 5, 6]}
  ]
}

Query with bash:

$(jq '[.items[] | select(.category == "A") | .values[]] | add')

Result:

6

Profile Default Applied

Profile:

{
  "name": "API",
  "defaultFilter": "results[?status==`success`]",
  "defaultQuery": "[].{id: id, message: message}"
}

Request:

### Check Results
GET https://api.example.com/results

Filter and query applied automatically from profile.

Override in request:

### Check All Results
# @filter ""
# @query ""
GET https://api.example.com/results

Empty values disable profile defaults for this request.

Resources

JMESPath reference: https://jmespath.org