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
moduleMyPlugin
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
#
moduleHTTPX::Plugins
moduleHTTPX::Plugins
moduleCustom
moduleCustom
...
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
moduleHTTPX::Plugins
moduleCustom
moduleInstanceMethods
deffoo
"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:
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
moduleHTTPX::Plugins
moduleCustom
moduleOptions
# creates :bar option
defoption_bar(value)
# must be an integer
Integer(value)
end
end
moduleInstanceMethods
deffoo
@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
moduleHTTPX::Plugins
moduleCustom
defself.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:
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.