Ucb::Hcm
Ucb::Hcm is a lightweight ruby wrapper around UC Berkeley's Human Capital Management API.
The current version (3.x) is intended for v3 of the HCM API. If you need to access v2, you should use 1.0 of this gem.
Installation
Add this line to your application's Gemfile:
gem 'ucb-hcm', "~> 3"
And then execute:
$ bundle
Or install it by yourself:
$ gem install ucb-hcm
Configuration
Configure your app with your API credentials from UCB's API Central.
Ucb::Hcm.configure do |hcm|
hcm.app_id = "APP_ID"
hcm.app_key = "APP_KEY"
hcm.endpoint = "https://apis.berkeley.edu/uat/hr/v3"
end
Usage
:rotating_light: Note: Version 3.x of this gem only supports v3 of the API. :rotating_light:
See the API documentation for details on the different endpoints and what they return.
Note that the main part of the returned payload (["response"]
) is always an Array
. It will often have only one element, but there could be more, even if you're not expecting them. To make certain you're getting all the data you asked for, be sure to iterate over the payload.
Fetch Employees
client = Ucb::Hcm::Client.new
response = client.get("/employees", { limit: 20, previous: 0, next: 20 })
>> response.all
=> [
{
"identifiers"=> [
{"type"=>"hr-employee-id", "id"=>"10141478"}
]
},
{
"identifiers"=>[
{"type"=>"hr-employee-id", "id"=>"10272831"},
{"type"=>"legacy-hr-employee-id", "id"=>"12521372"}
]
}
...
]
Fetch specific Employee
client = Ucb::Hcm::Client.new
response = client.get("/employees/10272831", {"id-type" => "hr-employee-id"})
>> response.all
=> [
{
"identifiers" => [
{"type" => "campus-uid", "id" => "20108691"}, {"type" => "campus-solutions-id"}, {"type" => "student-id"}, {"type" => "hr-employee-id", "id" => "10272831"}, {"type" => "legacy-hr-employee-id"}, {"type" => "calnet-id"}
],
"names" => [{
"type "= >{"code" => "PRI", "description" => "Primary"},
"familyName" => "Kumar",
"givenName" => "Siri",
"lastChangedBy" => {"id" => "10000499"},
"fromDate" => "2018-10-01"
}],
...
}
]
Fetch an Employee's jobs
client = Ucb::Hcm::Client.new
response = client.get("/employees/10272831/jobs", {"id-type" => "hr-employee-id"})
>> response.all
=> [
{
"identifiers" => [
{"type" => "campus-uid", "id" => "20108691"}, {"type" => "campus-solutions-id"}, {"type" => "student-id"}, {"type" => "hr-employee-id", "id" => "10272831"}, {"type" => "legacy-hr-employee-id"}, {"type" => "calnet-id"}
],
"jobs" => [
{
"number" => 0,
"sequence" => 0,
"type" => {
"code" => "2",
"description" => "Staff: Career"
},
...
}
...
]
}
]
Parsing The Response
All of the API calls return an instance of Ucb::Hcm::Response
. There are various ways to get to the underlying data, depending on your needs.
Checking The Response Status
You can find out if the call was successful by checking the return code, or just calling success?
:
response = client.get("/employees/10272831/jobs", {"id-type" => "hr-employee-id"})
response.code
=> 200
response.success?
=> true
Any status code other than 200
will cause success?
to return false
Extracting The Response Data: The Low-Level Approach
Calling raw_response
will give the response object of the underlying HTTP library (currently HTTParty::Response
). That object behaves like a hash, so you can access any part of the payload directly:
response = client.get("/employees/10272831/jobs", {"id-type" => "hr-employee-id"})
response.raw_response["source"]
=> "UCB-HR-PATH-DB"
The all
method will return the contents of the response
portion of the payload - this is where the meat of the data is usually found. The response
node is always an Array
of Hash
objects even if one element is expected:
response = client.get("/employees/10272831/jobs", {"id-type" => "hr-employee-id"})
response.all
=> [
{
"identifiers" => [
{"type" => "campus-uid", "id" => "20108691"}, {"type" => "campus-solutions-id"}, {"type" => "student-id"}, {"type" => "hr-employee-id", "id" => "10272831"}, {"type" => "legacy-hr-employee-id"}, {"type" => "calnet-id"}
],
"jobs" => [
{
"number" => 0,
"sequence" => 0,
"type" => {
"code" => "2",
"description" => "Staff: Career"
},
...
}
...
]
}
]
response.all.first["jobs"].first["number"]
=> 0
You can also iterate through each of the response items with the each
method:
response = client.get("/employees/10272831/jobs", {"id-type" => "hr-employee-id"})
response.each do |item|
puts item["jobs"].first["number"]
end
=> 0
Extracting The Response Data Using DataFetcher
The payloads from the HCM API are often very large and deeply nested, so navigating them as raw hashes can be a little cumbersome. To help get around this, it's possible to read the response data using the Ucb::Hcm::DataFetcher
object.
DataFetcher Overview
A DataFetcher
takes a hash when initialized and it can then be safely navigated using dot notation:
data = {foo: "bar", baz: { bam: "bang" }}
fetcher = Ucb::Hcm::DataFetcher.new(data)
fetcher.baz.bam.value
=> "bang"
You need to call value
when you've reached the node you're trying to read.
If you hit a node that contains an array, you can use the usual Array
methods to navigate through them:
data = {foo: "bar", baz: [{ bam: "bang" }]} # baz is an Array this time
fetcher = Ucb::Hcm::DataFetcher.new(data)
fetcher.baz.first.bam.value
=> "bang"
fetcher.baz[0].bam.value
=> "bang"
Apart from the conciseness of the syntax, DataFetcher
has another advantage over digging through hashes, as it will handle nodes that are nil
without raising an exception:
fetcher.baz.this_is_not_a_real_node.bam.value
=> nil
If any part of the traversal yields nil
, the call to value
will return nil
but you can change this by passing a different default to the value
call:
fetcher.baz.this_is_not_a_real_node.bam.value("oops!")
=> "oops!"
Getting DataFetchers From A Response
You can access an API payload with DataFetcher
objects by calling all_fetchers
or each_fetcher
on a Response
instance. These are equivalent to all
and each
(described earlier) but they return DataFetcher
instances rather than hashes:
response = client.get("/employees/10272831/jobs", {"id-type" => "hr-employee-id"})
response.all.first.class
=> Hash
response.all_fetchers.first.class
=> Ucb::Hcm::DataFetcher
response.each do |item|
p item.class
end
=> Hash
response.each_fetcher do |item|
p item.class
end
=> Ucb::Hcm::DataFetcher
Contributing
- Fork it ( https://github.com/[my-github-username]/ucb-hcm/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Ask for
.env
file from previous developer and runsource .env
- Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request