By now, you know that most of the features from this library are added as plugins.
Plugins are activated for a single session, once you call .plugin
, and calls can be concatenated in order for load multiple plugins:
# enabling follow redirects plugin
session = HTTPX.plugin(:follow_redirects)
# enabling new session with cookies plugin
session_with_cookies = session.plugin(:cookies)
Plugins are nothing but a pattern following a known convention for “controlled patching”. In order for you to create a plugin you can follow the following steps:
This part is straightforward
# There you go
module MyPlugin
end
custom_session = HTTPX.plugin(MyPlugin)
1.1 (Optionally) register it
Plugins can be called via a symbol (like the :cookies
example from above). For that to happen, you have to register them. There a few rules for that, described in the gist below:
# 1. Create your plugin module under lib/httpx/plugins
#
# for this example:lib/httpx/plugins/custom.rb
#
module HTTPX::Plugins
module Custom
end
register :custom, Custom
end
# now you can:
custom_session = HTTPX.plugin(:custom)
That’s it, your “minimal viable product”.
Methods can be added to some of the internal components, by defining certain modules within your plugin:
InstanceMethods
: methods will be added to the sessionRequestMethods
: methods will be added to the session RequestsResponseMethods
: methods will be added to the session ResponsesHeadersMethods
: methods will be added to the Headers of the aboveRequestBodyMethods
: methods will be added to the session Request BodyResponseBodyMethods
: methods will be added to the session Response BodyConnectionMethods
: methods will be added to the session ConnectionsOptionsMethods
: (since 0.16
) methods will be added to the session Optionsmodule HTTPX::Plugins
module Custom
module InstanceMethods
def foo
"foo"
end
end
end
# ...
end
HTTPX.plugin(:custom).foo #=> "foo"
Options can be passed through all layers, and reused inside of your plugins. You have to define them first:
session = HTTPX.plugin(:custom, bar: 1) => #=> "unknown option: bar"
In order for you to do that, you have to define the “transformer” method on the OptionsMethods
, which you do by creating a method with the “option_” prefix, followed by the option:
module HTTPX::Plugins
module Custom
module Options
# creates :bar option
def option_bar(value)
# must be an integer
Integer(value)
end
end
module InstanceMethods
def foo
@options.bar
end
end
end
# ...
end
HTTPX.plugin(:custom).foo #=> nil
HTTPX.plugin(:custom, bar: 2).foo #=> 2
HTTPX.plugin(:custom).with(bar: 1).foo #=> 1
HTTPX.plugin(:custom).with(bar: "a").foo #=> invalid value for Integer(): "a" (ArgumentError)
In case you want to provide a sensible default for an option, you can use the “hook” method extra_options
:
# same example from above
module HTTPX::Plugins
module Custom
def self.extra_options(options)
options.merge(bar: 2)
end
# ...
end
HTTPX.plugin(:custom).foo #=> 2
Your custom plugin might depend on external libraries. For example, you might want to integrate with some internal token generation gem, and assign those tokens on each request. The plugin system provides two “hooks” one can use for this goal:
load_dependencies(session_class)
: called at the beginning of the loading process, can be used, p.ex. to require dependencies, or some other form of pre-processing;configure(session_class)
: called at the end of the loading process, can do some post-processing; also used to load other plugins implicitly;For our example, you then use a combination of all above methods to load the gem, load the :authentication
plugin for convenience auth helpers, and off we go:
module HTTPX::Plugins
module Custom
class << self
def load_dependencies(*)
require "internal_auth"
end
def configure(klass)
klass.plugin(:authentication)
end
end
module InstanceMethods
def authenticate
token = InternalAuth.generate
authentication(token)
end
end
end
# ...
end
HTTPX.plugin(:custom).authenticate.get("https://internal-smth/action") #=> "..Authorization: Bearer custom-token..."
You’re kindly invited to look at the existing plugins to understand the possibilities of what could be done.
Next: Adapters