Project

prest

0.01
The project is in a healthy, maintained state
Programmatically communicate with external REST API the easy way.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Runtime

>= 0.20.0, < 0.23.0
 Project Readme

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' }.to_json)

Using raw/custom/special query parameters

In ruby, duplicate keyword arguments on method calls are not accepted, so you can not do the following:

Prest::Client.new('https://example.com/api').example(key: 1, key: 2).get
# `key: 1` is overriden by `key: 2`;
# produces: GET https://example.com/api/one/two?key=2

Because of this and other cases where formatting is very strict/unusual, you can pass a string which will not be formatted to the query parameters. To do this, use the following:

# GET https://example.com/api/example?key=1&key2&other=value
Prest::Client.new('https://example.com/api')
             .example(__query_params: 'key=1&key=2', other: 'value')
             .get

The string passed to the keyword argument __query_params will not be formatted, and passed as is.

Warning __query_params is the only keyword argument that can be repeated across method calls:

Prest::Client.new('https://example.com/api')
             .one(key: '1')
             .two(key: '2')
             .get
# Produces: GET https://example.com/api/one/two?key=2

However using __query_params:

Prest::Client.new('https://example.com/api')
             .one(__query_params: 'key=1')
             .two(__query_params: 'key=2')
             .get
#Produces: GET https://example.com/api/one/two?key=1&key=2

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.