Syntax
We define the map used to translate api data by passing a block to the
Spigot.define
method.
Spigot.define do
service :github do
resource :user do
name :name
login :username
end
end
end
This map defines the data attributes for a User received from Github.
The data received has the keys :name
and :login
.
The values at those keys are mapped to the columns :name
and
:username
respectively.
Methods
Each ActiveRecord method has a similar signature. Each accepts a hash of data, if you want to scope your data to a specific service, pass the data in as a value keyed to the service name {'username' => 'dino'}
vs. { github: {'username' => 'dino'} }
.
You specify the attribute used in your query by assigning the primary_key
option in your Spigot definition.
find_by_api
find_all_by_api
create_by_api
update_by_api
find_or_create_by_api
create_or_update_by_api
# Spigot Definition
Spigot.resource :user do
full_name :name
login :email
token :auth
options do
primary_key :email
end
end
# API Data
data = {"full_name":"Dean","login":"dino@amore.io","token":"bcd456"}
User.find_by_api(data)
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."email" = 'dino@amore.io' ORDER BY "users"."id" ASC LIMIT 1
#=> User id: 1, name: "Dean Martin", email: "dino@amore.io", token: "abc123"
Services
Spigot definitions have a service
keyword. You can pass it a name
and then a block of resource
definitions. Each service denotes a different
source of API data, such as Twitter or Github. You can also call service on the `Spigot` object without the define method.
Spigot.define do
service :twitter do
...
end
end
Spigot.service :yelp do
resource :review do
...
end
end
Resources
Spigot definitions have a resource
keyword. This corresponds to the name of the class that is implementing this map. Spigot uses the resource name to look up which map to use for the class you're currently mixing Spigot into.
In this code block, we are defining a service for the Twitter API. When we pass twitter data to a spigot method used on the User
class, it will use the mapping defined in the :user
resource.
If you define a resource without enclosing it in a service, it will use this map whenever you don't specify which service to use as you pass the data in.
Spigot.define do
service :twitter do
resource :user do
...
end
end
end
Spigot.resource(:tweet) do
...
end
Nested Data
The data received from an API is often nested. We can convey this using a nested block within a resource definition.
In this code block, we are mapping data that has a contact
key that points to a nested hash containing data with keys login
and phone
. We will drill down into the contact
hash and map those corresponding values to the appropriate attributes in our formatted hash.
Spigot.resource :user do
full_name :name
contact do
login :email
phone :telephone
end
end
Evaluated Ruby
On any attribute map, you're able to pass it a block which will be used during the assignment of the value. This let's you modify the value before assignment to the attribute in the formatted hash.
In this code block, we are taking the value that is present in the API data under the username
key and interpolating the value into a static url to build our database's value for the user's URL
Spigot.resource(:user) do
full_name :name
username :url do |value|
"https://twitter.com/#{value}"
end
end
Options
There are a couple options available to help define how Spigot accomplishes various tasks. Right now this is limited to database queries. Each Spigot option set is defined per resource.
primary_key
- The attribute used to execute a select statement when querying this resource's table
Spigot.resource(:user) do
full_name :name
login :email
options do
primary_key :email
end
end