prest 0.1.0 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b8a009d1db76e802ed1e416845134d08d466f21b26c90aea89929a8efbf875ea
4
- data.tar.gz: b5a860ff089a4b2652fce692e0d9b441333384b6545cca661cf8f143bef67ff8
3
+ metadata.gz: aef2d0096f535fe7a735571b6d3a556aed2ec746e50378b13e2b4218a788dc29
4
+ data.tar.gz: 7ae1c9c4fcc036adcc7484453caeda0fd31e78c5318666a2b20a9ad516de2cbe
5
5
  SHA512:
6
- metadata.gz: d1522ea4ef50f8c66e5c21510f87e23a4a5fa1191f2cc5b585c12de698dcd6f1889b427119773fdd8e5af4d55cd412890b1b94e1c3194f093232ec2c8238242b
7
- data.tar.gz: a0922e5d6b4577481cee58bcc0ea37a26c5ad5710499709d49b1af2371b9966dcb1e8135dc06f4fb43a764d2c94703a9f5aefb4a5024d7c7c28c2dd708e6141e
6
+ metadata.gz: 5ed398def4e6713c62bcab45447ed7f466c517b6786e9bf3ea3f419cab97d8e48c5ca336e6e2b0995e4f4a6ace68476b3aa31d753d6fef061f630e6062b07a73
7
+ data.tar.gz: 7f748b2cf758c6d41bb8d907d631f31167970dd54a3b9b9751c73d98f56c960525ae10990e17ad391c5b3d24d0fb80435f18232d7c8e5cf668e6bdad80142826
data/.rubocop.yml CHANGED
@@ -1,10 +1,11 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.7
2
+ TargetRubyVersion: 2.7.0
3
3
  NewCops: disable
4
4
 
5
5
  Metrics/BlockLength:
6
6
  Exclude:
7
7
  - "spec/**/*"
8
+
8
9
  Style/StringLiterals:
9
10
  Enabled: true
10
11
  EnforcedStyle: single_quotes
data/CHANGELOG.md CHANGED
@@ -3,3 +3,15 @@
3
3
  ## [0.1.0] - 2022-07-20
4
4
 
5
5
  - Initial release
6
+
7
+ ## [0.1.1] - 2022-07-22
8
+
9
+ - Wraps endpoints response in a `Prest::Response` object for easier access to the response data
10
+
11
+ ## [0.1.2] - 2022-08-05
12
+
13
+ - Change how urls are built. Underscore in the fragment building stays as an underscore. Dashes are made with `__`
14
+
15
+ ## [0.1.3] - 2022-08-05
16
+
17
+ - Add `Prest::Service` object for easier rails integration with service-object pattern
data/Gemfile CHANGED
@@ -7,4 +7,5 @@ gemspec
7
7
 
8
8
  gem 'rake', '~> 13.0'
9
9
  gem 'rspec', '~> 3.0'
10
- gem 'rubocop', '~> 1.21'
10
+ gem 'rubocop', '~> 1.21', require: false
11
+ gem 'simplecov', '~> 0.21.2', require: false, group: :test
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- prest (0.1.0)
4
+ prest (0.1.5)
5
5
  httparty (~> 0.20.0)
6
6
 
7
7
  GEM
@@ -9,6 +9,7 @@ GEM
9
9
  specs:
10
10
  ast (2.4.2)
11
11
  diff-lcs (1.5.0)
12
+ docile (1.4.0)
12
13
  httparty (0.20.0)
13
14
  mime-types (~> 3.0)
14
15
  multi_xml (>= 0.5.2)
@@ -50,6 +51,12 @@ GEM
50
51
  rubocop-ast (1.19.1)
51
52
  parser (>= 3.1.1.0)
52
53
  ruby-progressbar (1.11.0)
54
+ simplecov (0.21.2)
55
+ docile (~> 1.1)
56
+ simplecov-html (~> 0.11)
57
+ simplecov_json_formatter (~> 0.1)
58
+ simplecov-html (0.12.3)
59
+ simplecov_json_formatter (0.1.4)
53
60
  unicode-display_width (2.2.0)
54
61
 
55
62
  PLATFORMS
@@ -61,6 +68,7 @@ DEPENDENCIES
61
68
  rake (~> 13.0)
62
69
  rspec (~> 3.0)
63
70
  rubocop (~> 1.21)
71
+ simplecov (~> 0.21.2)
64
72
 
65
73
  BUNDLED WITH
66
74
  2.3.7
data/README.md CHANGED
@@ -1,6 +1,11 @@
1
1
  # Prest
2
2
 
3
- Programmaticcally communicate with any REST API.
3
+ [![Gem Version](https://badge.fury.io/rb/prest.svg)](https://badge.fury.io/rb/prest)
4
+ [![Ruby](https://github.com/gogrow-dev/prest/actions/workflows/main.yml/badge.svg?branch=main)](https://github.com/gogrow-dev/prest/actions/workflows/main.yml)
5
+ [![Maintainability](https://api.codeclimate.com/v1/badges/f81b2e00be4d8eaa5e81/maintainability)](https://codeclimate.com/github/gogrow-dev/prest/maintainability)
6
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/f81b2e00be4d8eaa5e81/test_coverage)](https://codeclimate.com/github/gogrow-dev/prest/test_coverage)
7
+
8
+ Programmatically communicate with any REST API.
4
9
 
5
10
  ## Installation
6
11
 
@@ -34,6 +39,10 @@ Prest::Client.new('https://example.com/api').users(name: 'Juan', created_at: '20
34
39
  Prest::Client.new('https://example.com/api').users(2).pulls(1).comments.get
35
40
  # This translates to making a GET https://example.com/api/users/2/pulls/1/comments
36
41
 
42
+ # To make requests to url which have a dash in it, use a double __
43
+ Prest::Client.new('https://example.com/api').job__posts(1).get
44
+ # This translates to making a GET https://example.com/api/job-posts/1
45
+
37
46
  # To pass headers to the request, pass them to the client constructor
38
47
  Prest::Client.new('https://example.com/api', { headers: { 'Authorization' => 'Bearer Token xxxyyyzzz' } })
39
48
  .users
@@ -45,29 +54,92 @@ Prest::Client.new('https://example.com/api', { headers: { 'Authorization' => 'Be
45
54
  .post(body: { username: 'juan-apa' })
46
55
  ```
47
56
 
57
+ ### Raising exceptions on failed HTTP requests
58
+
59
+ An HTTP request is considered as failed when the status code is not between `100` and `299`.
60
+ To automatically raise a `Prest::Error` when the HTTP request is not successful, use the bang methods (`get!`, `post!`, `put!`, `patch!` and `delete!` ).
61
+
62
+ ```ruby
63
+ # If for example the authorization headers are invalid, it will return an 401 status code.
64
+ # This call will raise a ::Prest::Error with the response as a json in the message.
65
+
66
+ begin
67
+ Prest::Client.new('https://example.com/api', { headers: { 'Authorization' => 'Bearer Token xxxyyyzzz' } })
68
+ .users
69
+ .get!
70
+ rescue Prest::Error => e
71
+ puts e.message # "{ error: \"Invalid auth credentials\" }"
72
+ end
73
+ ```
74
+
75
+ ### Accessing the response
76
+
77
+ ```ruby
78
+ response = Prest::Client.new('https://example.com/api').users.get
79
+
80
+ response[:users] # is equivalent to response.body[:users]
81
+ # You can access the body directly from the response object
82
+
83
+ response.successful? # is equivalent to response.status is between 200-299
84
+
85
+ response.status # returns the status code of the response
86
+ response.headers # returns the headers of the response
87
+ response.body # returns the body of the response
88
+ ```
89
+
48
90
  ### Rails service-like approach
49
91
 
50
92
  ```ruby
51
93
  # app/services/github.rb
52
- class Github
53
- BASE_URL = 'https://api.github.com'
94
+ class Github < Prest::Service
95
+ private
54
96
 
55
- def new
56
- Prest::Client.new(BASE_URL, { headers: headers })
97
+ def base_uri
98
+ 'https://api.github.com'
99
+ end
100
+
101
+ def options
102
+ {
103
+ headers: {
104
+ 'access_token' => 'xxxyyyzzz'
105
+ }
106
+ }
107
+ end
108
+ end
109
+
110
+ # Then, you can use it like this anywhere in your app:
111
+
112
+ Github.users('juan-apa').pulls.get
113
+ ```
114
+
115
+ You can also define an initializer to pass values in runtime to your service:
116
+
117
+ ```ruby
118
+ # app/services/github.rb
119
+ class Github < Prest::Service
120
+ def initialize(organization)
121
+ @organization = organization
57
122
  end
58
123
 
59
124
  private
60
125
 
61
- def headers
126
+ def base_uri
127
+ 'https://api.github.com'
128
+ end
129
+
130
+ def options
62
131
  {
63
- 'access_token' => 'xxxyyyzzz'
132
+ headers: {
133
+ 'access_token' => 'xxxyyyzzz',
134
+ 'org' => @organization
135
+ }
64
136
  }
65
137
  end
66
138
  end
67
139
 
68
140
  # Then, you can use it like this anywhere in your app:
69
141
 
70
- Github.new.users('juan-apa').pulls.get
142
+ Github.new('gogrow-dev').users.get
71
143
  ```
72
144
 
73
145
  ## Development
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Prest
4
+ # Main wrapper class for Prest Response.
5
+ class Response
6
+ extend ::Forwardable
7
+
8
+ def_delegator :@body, :[]
9
+
10
+ attr_reader :status, :body, :headers
11
+
12
+ def initialize(status, body, headers)
13
+ @status = status
14
+ @body = body
15
+ @headers = headers
16
+ end
17
+
18
+ def successful?
19
+ @status.between?(100, 399)
20
+ end
21
+ end
22
+ end
data/lib/prest/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Prest
4
- VERSION = '0.1.0'
4
+ VERSION = '0.1.5'
5
5
  end
data/lib/prest.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'httparty'
4
4
  require_relative 'prest/version'
5
+ require_relative 'prest/response'
5
6
 
6
7
  module Prest
7
8
  class Error < StandardError; end
@@ -9,7 +10,7 @@ module Prest
9
10
  # Main wrapper class for Prest. To use the gem, call:
10
11
  # Prest::Client.new('https://base_uri.com', { headers: { 'Authorization' => 'Bearer token' }})
11
12
  class Client < BasicObject
12
- SUPPORTED_HTTP_VERBS = %i[get post put patch delete].freeze
13
+ SUPPORTED_HTTP_VERBS = %i[get post put patch delete get! post! put! patch! delete!].freeze
13
14
 
14
15
  def initialize(base_uri, options = {})
15
16
  @base_uri = base_uri
@@ -20,28 +21,42 @@ module Prest
20
21
 
21
22
  def method_missing(method, *args, **kwargs)
22
23
  if SUPPORTED_HTTP_VERBS.include?(method)
23
- execute_query(method, **kwargs)
24
+ if method.to_s.end_with?('!')
25
+ execute_query!(method[0..-2], **kwargs)
26
+ else
27
+ execute_query(method, **kwargs)
28
+ end
24
29
  else
25
30
  chain_fragment(method.to_s, *args, **kwargs)
26
31
  self
27
32
  end
28
33
  end
29
34
 
30
- def respond_to_missing?(_)
35
+ def respond_to_missing?(_, _)
31
36
  true
32
37
  end
33
38
 
34
39
  private
35
40
 
36
41
  def execute_query(http_method, body: {})
37
- ::HTTParty.send(http_method, build_url, headers: headers, body: body)
42
+ res = ::HTTParty.send(http_method, build_url, headers: headers, body: body)
43
+ ::Prest::Response.new(res.code, res.parsed_response, res.headers)
44
+ rescue ::HTTParty::ResponseError => e
45
+ ::Kernel.raise ::Prest::Error, e.message
46
+ end
47
+
48
+ def execute_query!(*args, **kwargs)
49
+ res = execute_query(*args, **kwargs)
50
+ ::Kernel.raise ::Prest::Error, res.body.to_json unless res.successful?
51
+
52
+ res
38
53
  end
39
54
 
40
55
  def chain_fragment(fragment_name, *args, **kwargs)
41
56
  arguments = args.join('/')
42
- parsed_args = arguments.empty? ? '' : "#{arguments}/"
57
+ parsed_args = arguments.empty? ? '' : "/#{arguments}"
43
58
  @query_params.merge!(kwargs)
44
- @fragments << "#{fragment_name.tr("_", "-")}/#{parsed_args}"
59
+ @fragments << "#{fragment_name.gsub("__", "-")}#{parsed_args}"
45
60
  end
46
61
 
47
62
  def headers
@@ -60,4 +75,37 @@ module Prest
60
75
  "#{@base_uri}/#{path}#{stringified_params}"
61
76
  end
62
77
  end
78
+
79
+ # Base Service Object from which to extend to integrate with api's using the Prest gem.
80
+ class Service < BasicObject
81
+ def method_missing(method, *args, **kwargs)
82
+ client.__send__(method, *args, **kwargs)
83
+ end
84
+
85
+ def self.method_missing(method, *args, **kwargs)
86
+ new.__send__(:client).__send__(method, *args, **kwargs)
87
+ end
88
+
89
+ def self.respond_to_missing?(_, _)
90
+ true
91
+ end
92
+
93
+ def respond_to_missing?(_, _)
94
+ true
95
+ end
96
+
97
+ protected
98
+
99
+ def client
100
+ @client ||= ::Prest::Client.new(base_uri, options)
101
+ end
102
+
103
+ def base_uri
104
+ ::Kernel.raise(Error, 'Implement in subclass')
105
+ end
106
+
107
+ def options
108
+ {}
109
+ end
110
+ end
63
111
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juan Aparicio
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-07-20 00:00:00.000000000 Z
11
+ date: 2022-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -41,6 +41,7 @@ files:
41
41
  - README.md
42
42
  - Rakefile
43
43
  - lib/prest.rb
44
+ - lib/prest/response.rb
44
45
  - lib/prest/version.rb
45
46
  - prest.gemspec
46
47
  homepage: https://gogrow.dev