0.0
No commit activity in last 3 years
No release in over 3 years
This rubygem does not have a description or summary.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 8.2
~> 0.10
~> 0.1
~> 12.0
~> 4.5
~> 3.5
~> 0.46

Runtime

>= 2.0
 Project Readme

BetterHeroku

Gem Version

Table of Contents

  • Features
  • Requirements
  • Setup
  • Usage
    • Authentication
      • Personal API tokens
      • OAuth tokens
    • Mocking requests
  • Tests
  • Versioning
  • Code of Conduct
  • Contributions
  • License
  • History
  • Credits

Features

BetterHeroku Is a better Heroku client gem. The official "platform-api" Heroku client gem has several issues:

  • The name itself is presumptuous. No mention of Heroku, assumes there's no other platform for which there's an API.
  • The code is auto-generated from a schema.json provided by Heroku themselves. The gem is not updated nearly as frequently as the schema.json, and lags behind the published APIs.
  • The schema.json itself often lags behind the published API docs, and occasionally disagrees with them.
  • It's not obvious how to consume the documented API.
    • The way to get the current account is heroku.account.info("~"). The only way to know this is to contact Heroku support.
    • For a url with multiple parameters, like info for a dyno for an app, is requested like heroku.dyno.info(app, dyno). The parameters are not documented, because the code is generated.
  • The client provides no access to the lower-level HTTP client, Excon, to enable features such as HTTP persistence, or to override it for testing.
  • The client provides no means to add logging or instrumentation of the raw requests.

BetterHeroku attempts to solve all these problems by being a much simpler and less-opinionated implementation.

Requirements

  1. Ruby 2.4.0

Setup

gem install better_heroku

Add the following to your Gemfile:

gem "better_heroku"

Usage

client = BetterHeroku::Client.new.authenticate(token: my_token)
resp = client.get("apps", app_id)
resp.status #=> 200
resp["id"]  #=> "01234567-89ab-cdef-0123-456789abcdef"

The client pays no attention to the segments of the url passed in, and instead just joins them with /. This way, it always matches 1:1 with the published API docs. In this example, we're using the App Info endpoint, which looks like GET /apps/{app_id_or_name} in the docs. Just pass in the various segments in the same order, and it'll work.

Authentication

BetterHeroku supports all the Heroku methods of authentication.

Personal API tokens

Get your personal API token from the Heroku dashboard, or from the CLI:

heroku auth:token

You'll get a UUID that you can use to make requests:

client = BetterHeroku::Client.new.authenticate(token: "01234567-89ab-cdef-0123-456789abcdef")
resp = client.get("apps", app_id)

In one-off scripts this is fine, but for production usage I strongly recommend you put the token in a config or environment variable.

OAuth tokens

When making requests on behalf of other users, you'll need to use OAuth tokens. See the Heroku OAuth docs for details.

Once set up, you'll have your Heroku OAuth secret. In this example, we've stored it in an environment variable called HEROKU_OAUTH_SECRET. Once your users go through the web flow, you'll get back from Heroku a token and a refresh_token. The token expires after 8 hours, and the refresh_token never expires, and may be used to obtain a new token.

If you're not concerned about storing the token (perhaps you only make a few requests once a day, and the token would have expired the next time you need it anyways), you can just authenticate with your secret and the refresh token:

client = BetterHeroku::Client.new
authenticated_client = client.oauth(secret: ENV["HEROKU_OAUTH_SECRET"], refresh_token: refresh_token)

resp = authenticated_client.get("apps", app_id)

The authenticated_client will not automatically handle refreshing the oauth token, however it does provide a simple facility to do so via #refresh_oauth_token. Additionally, that method takes an optional callback that can be used to persist the access token for future requests.

As BetterHeroku borrow's HTTP.rb's philosophy of a immutable client object, you'll need to replace the client you're using with the refreshed client object. If you're using threads, its on you to handle handle that in a threadsafe manner. In most cases, doing so probably isn't necessary, the following example should work fine.

response = authenticated_client.get("apps", app_id)
if response.status == 401
  refreshed_client = authenticated_client.refresh_oauth_token do |response|
    user.update_attribute(:oauth_token, response["access_token"])
  end
  response = refreshed_client.get("apps", app_id)
end

The response is the response body as documented in the Heroku OAuth token refresh docs.

Mocking requests

You probably don't want to always make actual requests against the Heroku API, so BetterHeroku provides a mechanism to pass in the lower HTTP client. An example of what this might look like:

let(:http) { double(HTTP) }

it "should do awesome things" do
  allow(http).to receive(:get).and_return(BetterHeroku::MockResponse.new({"id" => "01234567-89ab-cdef-0123-456789abcdef"})
  client = BetterHeroku::Client.new(http: http)

  resp = client.get("accounts", "01234567-89ab-cdef-0123-456789abcdef")

  expect(resp["id"]).to eq "01234567-89ab-cdef-0123-456789abcdef"
end

Also, be sure to check out the FakeHTTP gem to mock the HTTP library with a Sinatra-like DSL.

Tests

To test, run:

rake

Versioning

Read Semantic Versioning for details. Briefly, it means:

  • Patch (x.y.Z) - Incremented for small, backwards compatible, bug fixes.
  • Minor (x.Y.z) - Incremented for new, backwards compatible, public API enhancements/fixes.
  • Major (X.y.z) - Incremented for any backwards incompatible public API changes.

Code of Conduct

Please note that this project is released with a CODE OF CONDUCT. By participating in this project you agree to abide by its terms.

Contributions

Read CONTRIBUTING for details.

License

Copyright (c) 2017 Paul Sadauskas. Read LICENSE for details.

History

Read CHANGES for details. Built with Gemsmith.

Credits

Developed by Paul Sadauskas