/prest

Programmatic REST communication interface

Primary LanguageRubyMIT LicenseMIT

Prest

Gem Version Ruby Maintainability Test Coverage

Programmatically communicate with any REST API.

Installation

Add this line to your application's Gemfile:

gem 'prest'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install prest

Usage

Prest::Client.new('https://example.com/api').users.get # instead of .get you can use .put .patch .post .delete
# This translates to making a GET https://example.com/api/users

Prest::Client.new('https://example.com/api').users(2).get
# This translates to making a GET https://example.com/api/users/2

Prest::Client.new('https://example.com/api').users(name: 'Juan', created_at: '2022-07-20').get
# This translates to making a GET https://example.com/api/users?name=Juan&created_at=2022-07-20

# You can also chain methods/fragments as many times as you want
Prest::Client.new('https://example.com/api').users(2).pulls(1).comments.get
# This translates to making a GET https://example.com/api/users/2/pulls/1/comments

# To make requests to url which have a dash in it, use a double __
Prest::Client.new('https://example.com/api').job__posts(1).get
# This translates to making a GET https://example.com/api/job-posts/1

# To pass headers to the request, pass them to the client constructor
Prest::Client.new('https://example.com/api', { headers: { 'Authorization' => 'Bearer Token xxxyyyzzz' } })
             .users
             .get

# To pass a body to the request, pass them to post/put/patch method as follows:
Prest::Client.new('https://example.com/api', { headers: { 'Authorization' => 'Bearer Token xxxyyyzzz' } })
             .users
             .post(body: { username: 'juan-apa' })

Automatically adding the json headers

Because some API's need a Content-Type: application/json and/or Accept: application/json headers, there's a built in option that can be passed to the client to add those for you:

Prest::Client.new('https://example.com/api', { json: true })
             .users
             .get
# Makes a GET https://example.com/api/users with headers Content-Type: application/json and Accept: application/json

Note: The option will merge any other header you pass to the initializer.

Raising exceptions on failed HTTP requests

An HTTP request is considered as failed when the status code is not between 100 and 299. To automatically raise a Prest::RequestError when the HTTP request is not successful, use the bang methods (get!, post!, put!, patch! and delete!).

  # If for example the authorization headers are invalid, it will return an 401 status code.
  # This call will raise a ::Prest::RequestError with the response as a json in the message.

  begin
    Prest::Client.new('https://example.com/api', { headers: { 'Authorization' => 'Bearer Token xxxyyyzzz' } })
              .users
              .get!
  rescue Prest::RequestError => e
    puts e.message # "{ error: \"Invalid auth credentials\" }"
    puts e.status # 403
    puts e.body # "{ error: \"Invalid auth credentials\" }"
    puts e.headers # { 'ContentType' => 'application/json' }
  end

Accessing the response

response = Prest::Client.new('https://example.com/api').users.get

response[:users] # is equivalent to response.body[:users]
# You can access the body directly from the response object

response.successful? # is equivalent to response.status is between 200-299

response.status # returns the status code of the response
response.headers # returns the headers of the response
response.body # returns the body of the response

Rails service-like approach

# app/services/github.rb
class Github < Prest::Service
  private

  def base_uri
    'https://api.github.com'
  end

  def options
    {
      headers: {
        'access_token' => 'xxxyyyzzz'
      }
    }
  end
end

# Then, you can use it like this anywhere in your app:

Github.users('juan-apa').pulls.get

You can also define an initializer to pass values in runtime to your service:

# app/services/github.rb
class Github < Prest::Service
  def initialize(organization)
    @organization = organization
  end

  private

  def base_uri
    'https://api.github.com'
  end

  def options
    {
      headers: {
        'access_token' => 'xxxyyyzzz',
        'org' => @organization
      }
    }
  end
end

# Then, you can use it like this anywhere in your app:

Github.new('gogrow-dev').users.get

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/gogrow-dev/prest. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the Prest project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

Credits

Prest is maintained by GoGrow with the help of our contributors.