Skip to content
Update Custom Plugins authored by HoneyryderChuck's avatar HoneyryderChuck
By now, you know that most of the features from this library are added as plugins. By now, you know that most of the features from this library are added as plugins.
Plugins are nothing but a pattern following a known convention. In order for you to write a plugin, you need to create a module and register it (we suggest you to put it under "lib/httpx/plugins" in your project): Plugins are activated for a single session, once you call `.plugin`, and calls can be concatenated in order for load multiple plugins:
```ruby ```ruby
# lib/httpx/plugins/custom.rb # 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:
1. Creating the plugin module
This part is straightforward
```ruby
# 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:
```ruby
# 1. Create your plugin module under lib/httpx/plugins
#
# for this example:lib/httpx/plugins/custom.rb
#
module HTTPX::Plugins module HTTPX::Plugins
module Custom module Custom
...
end end
register :custom, Custom register :custom, Custom
end end
# now you can:
custom_session = HTTPX.plugin(:custom)
```
That's it, your "minimal viable product".
2. Decorate existing components
Methods can be added to some of the internal components, by defining certain modules within your plugin:
* `InstanceMethods`: methods will be added to the session
* `RequestMethods`: methods will be added to the session Requests
* `ResponseMethods`: methods will be added to the session Responses
* `HeadersMethods`: methods will be added to the Headers of the above
* `RequestBodyMethods`: methods will be added to the session Request Body
* `ResponseBodyMethods`: methods will be added to the session Response Body
* `ConnectionMethods`: methods will be added to the session Connections
* `OptionsMethods`: (since `0.16`) methods will be added to the session Options
```ruby
module HTTPX::Plugins
module Custom
module InstanceMethods
def foo
"foo"
end
end
end
# ...
end
HTTPX.plugin(:custom).foo #=> "foo"
```
3. Add extra options
Options can be passed through all layers, and reused inside of your plugins. You have to define them first:
```ruby
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:
```ruby
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`:
```ruby
# 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
``` ```
Once you have it, when loaded, your plugin will: 4. Load/Configure
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:
```ruby
module HTTPX::Plugins
module Custom
class << self
def load_dependencies(*)
require "internal_auth"
end
* load dependencies def configure(klass)
* decorate certain internal resources klass.plugin(:authentication)
* configure 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..."
```
All of these steps are optional.
You're kindly invited to look at the implementations of the plugins to understand how this is done. You're kindly invited to look at the [existing plugins](https://gitlab.com/honeyryderchuck/httpx/-/tree/master/lib/httpx/plugins) to understand the possibilities of what could be done.
Next: [Adapters](home#adapters) Next: [Adapters](home#adapters)
\ No newline at end of file