-
Notifications
You must be signed in to change notification settings - Fork 3
Create an adapter class
An API adapter class contains methods for connecting to and searching a third party API. Whowas provides the public interface for all adapter classes, but there are required and optional private methods you should define.
First, generate a template:
rails generate whowas:adapter MyAdapter
This will create a file app/whowas/adapters/my_adapter.rb
that looks like this (but with comments):
module Whowas
class MyAdapter
include Whowas::Adapter
def search_api(input)
""
end
def validate(input)
true ||
(raise Whowas::Errors::InvalidInput, "Invalid input for #{self.class.name}")
end
def format(input)
input
end
end
end
The entire interface consists of one method, search
, which is defined in Whowas::Adapter
def search(input)
validate(input)
input = format(input)
search_api(input)
end
As you can see, all it does is call the private methods defined on each adapter in order. validate
and format
are optional, but search_api
must be defined in each adapter class.
Validations defined here check the input for all search methods using this adaoter; therefore, use for conditions that are universal to this API's queries. (You can run validations at the search method level as well.)
Example: MyAdapter requires a valid timestamp for any query it runs.
def validate(input)
DateTime.parse(input[:timestamp]) && true ||
(raise Whowas::Errors::InvalidInput, "Invalid input for MyAdapter")
end
validate
should return true or raise Whowas::Errors::InvalidInput.
If undefined, validate
always returns true.
format
allows you to transform the input to match the API's requirements. Again, this method is adapter-wide; you can define transformations specific to a particular search method at that level. Feel free to define helper methods, such as format_timestamp
below.
Example: The input hash needs to be formatted to match the API specifications.
def format(input)
{
query: "search #{input[:query]}",
timestamp: format_timestamp(input[:timestamp])
}
end
def format_timestamp(timestamp)
DateTime.parse(timestamp).strftime("Y-%m-%dT%H:%M:%S")
end
format
should return data in the format the API requires. Specifically, the output from format
will be the input to search_api
(more below).
If undefined, format
returns its argument unchanged.
Here is the core of the API search. The contents of this method will depend on the API itself, of course, but an example search_api method might look like this:
def search_api(input)
connection = api.connect!
results = connection.search(input)
if results
results.to_s
else
""
end
rescue Api::ServiceDown => e
raise Whowas::Errors::ServiceUnavailable, e
end
Again, feel free to define helper methods as necessary. It is useful sometimes to create a class-level variable for the connection itself, so it can be shared between multiple calls.
search_api
must return a string, either with the results or empty. If your API returns its results in another format, you must transform it to a string.
search_api
may raise Whowas::Errors::ServiceUnavailable if the third-party service is unreachable.