prest 0.1.0 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
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