Module: Docker::API::Query

Defined in:
lib/docker/api/query.rb,
sig/docker/api/core.rbs

Overview

Turns Ruby values into the query strings the Engine API expects.

Docker's conventions are specific enough to be worth centralising, and they are not uniform:

  • Booleans travel as the literal strings "true" and "false".
  • Structured parameters such as filters are declared in the API specification as strings holding a JSON document, so a Hash becomes one JSON-encoded value.
  • A handful of parameters -- the platform and type parameters of the image and system endpoints -- are declared as arrays with collectionFormat: multi, so an Array becomes a repeated key rather than one JSON value.

Getting this wrong does not raise: the daemon ignores a parameter it cannot parse and quietly does something else, which is the failure mode that makes it worth encoding in one place.

Class Method Summary collapse

Class Method Details

.encode(params) ⇒ String

Encode a parameter hash as a URL query fragment.

Nil values are dropped rather than sent empty, because an empty value is not the same as an absent one to the daemon: ?all= is a parse error where omitting all is a default.

Examples:

A boolean and a JSON-encoded filter

Query.encode(all: true, filters: { "status" => ["running"] })
#=> "?all=true&filters=%7B%22status%22%3A%5B%22running%22%5D%7D"

An array parameter, repeated rather than JSON-encoded

Query.encode(platform: ["linux/amd64", "linux/arm64"])
#=> "?platform=linux%2Famd64&platform=linux%2Farm64"

Parameters:

  • params (Hash)

    parameters in Ruby types

Returns:

  • (String)

    a fragment beginning with "?", or "" when nothing survived, so callers can concatenate unconditionally



45
46
47
48
49
50
51
52
# File 'lib/docker/api/query.rb', line 45

def encode(params)
  pairs = (params || {}).reject { |_, value| value.nil? }
    .flat_map { |key, value| pairs_for(key.to_s, value) }

  return "" if pairs.empty?

  "?#{URI.encode_www_form(pairs)}"
end

.pairs_for(key, value) ⇒ Array<Array(String, String)>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns one or more key/value pairs.

Parameters:

  • key (String)

    the wire parameter name

  • value (Object)

    the Ruby value

Returns:

  • (Array<Array(String, String)>)

    one or more key/value pairs



58
59
60
61
62
# File 'lib/docker/api/query.rb', line 58

def pairs_for(key, value)
  return value.map { |element| [key, serialize(element)] } if value.is_a?(Array)

  [[key, serialize(value)]]
end

.serialize(value) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the daemon's expected wire form for a single value.

Parameters:

  • value (Object)

Returns:

  • (String)

    the daemon's expected wire form for a single value



67
68
69
70
71
72
73
# File 'lib/docker/api/query.rb', line 67

def serialize(value)
  case value
  when true, false then value.to_s
  when Hash then JSON.generate(value)
  else value.to_s
  end
end