Skip to content

Custom serialization rules

Vlad Faust edited this page Feb 12, 2019 · 1 revision

To make a simple (i.e. scalar, which could be read from a single string) Object serializable, you should implement

  • #to_http_param(builder : HTTP::Params::Builder, key : String) and
  • .from_http_param(value : String) : self

methods on it as well as define the HTTP::Params::Serializable::Scalar annotation. Good candidates for scalars are Int32, Bool, String or URI — the ones which are likely to be expressed in the only way within a single string.

The URI extension is shipped by default, here is its source code:

@[HTTP::Params::Serializable::Scalar]
class URI
  # Put `self` as an HTTP param into the *builder* at *key*.
  def to_http_param(builder : HTTP::Params::Builder, key : String)
    builder.add(key, to_http_param)
  end

  # Return `self` as an HTTP param string.
  def to_http_param
    to_s
  end

  # Parse `URI` from an HTTP param.
  def self.from_http_param(value : String)
    return URI.parse(value)
  end
end

Complex objects require more effort. Basically, they must implement these methods:

def to_http_param(builder : HTTP::Params::Builder, key : String? = nil)
  # Notice the *key* is nilable
end

# Or if you're using a converter on a param.
# If you never do, this method is not required.
# But if you plan to publish the code, then implement it:
def to_http_param(builder : HTTP::Params::Builder, key : String? = nil, converter : C = nil) forall C
  # ditto
end

def self.from_http_param(query : String, path : Tuple) : self
  # Notice the *path* argument
end

# Or if you're using a converter on a param.
# If you never do, this method is not required.
# But if you plan to publish the code, then implement it:
def self.from_http_param(query : String, path : Tuple, converter : C = nil) : self forall C
  # ditto
end
Clone this wiki locally