my_api_client 0.14.0.pre → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +179 -38
  3. data/.dependabot/config.yml +19 -1
  4. data/.envrc.skeleton +1 -0
  5. data/.rubocop.yml +9 -1
  6. data/.rubocop_challenge.yml +5 -0
  7. data/.rubocop_todo.yml +29 -1
  8. data/CHANGELOG.md +177 -1
  9. data/Gemfile.lock +47 -45
  10. data/README.jp.md +156 -21
  11. data/bin/console +4 -0
  12. data/example/api_clients/application_api_client.rb +13 -0
  13. data/example/api_clients/my_error_api_client.rb +34 -0
  14. data/example/api_clients/my_errors.rb +27 -0
  15. data/example/api_clients/my_pagination_api_client.rb +18 -0
  16. data/example/api_clients/my_rest_api_client.rb +48 -0
  17. data/example/api_clients/my_status_api_client.rb +22 -0
  18. data/lib/generators/rails/templates/application_api_client.rb.erb +0 -11
  19. data/lib/generators/rspec/templates/api_client_spec.rb.erb +22 -15
  20. data/lib/my_api_client.rb +7 -0
  21. data/lib/my_api_client/base.rb +4 -2
  22. data/lib/my_api_client/default_error_handlers.rb +64 -0
  23. data/lib/my_api_client/error_handling.rb +6 -6
  24. data/lib/my_api_client/error_handling/generator.rb +23 -7
  25. data/lib/my_api_client/errors.rb +1 -53
  26. data/lib/my_api_client/errors/api_limit_error.rb +6 -0
  27. data/lib/my_api_client/errors/client_error.rb +93 -0
  28. data/lib/my_api_client/errors/network_error.rb +43 -0
  29. data/lib/my_api_client/errors/server_error.rb +42 -0
  30. data/lib/my_api_client/request.rb +29 -34
  31. data/lib/my_api_client/request/basic.rb +32 -0
  32. data/lib/my_api_client/request/executor.rb +1 -1
  33. data/lib/my_api_client/request/pagination.rb +39 -0
  34. data/lib/my_api_client/rspec/matchers/request_to.rb +3 -4
  35. data/lib/my_api_client/version.rb +1 -1
  36. data/my_api/.envrc.skeleton +3 -0
  37. data/my_api/.gitignore +14 -0
  38. data/my_api/.jetskeep +1 -0
  39. data/my_api/.rspec +3 -0
  40. data/my_api/.ruby-version +1 -0
  41. data/my_api/Gemfile +23 -0
  42. data/my_api/Gemfile.lock +243 -0
  43. data/my_api/Procfile +7 -0
  44. data/my_api/README.md +54 -0
  45. data/my_api/Rakefile +4 -0
  46. data/my_api/app/controllers/application_controller.rb +5 -0
  47. data/my_api/app/controllers/error_controller.rb +21 -0
  48. data/my_api/app/controllers/pagination_controller.rb +58 -0
  49. data/my_api/app/controllers/rest_controller.rb +60 -0
  50. data/my_api/app/controllers/status_controller.rb +11 -0
  51. data/my_api/app/helpers/application_helper.rb +5 -0
  52. data/my_api/app/jobs/application_job.rb +7 -0
  53. data/my_api/app/models/application_item.rb +5 -0
  54. data/my_api/config.ru +7 -0
  55. data/my_api/config/application.rb +73 -0
  56. data/my_api/config/dynamodb.yml +22 -0
  57. data/my_api/config/environments/development.rb +9 -0
  58. data/my_api/config/environments/production.rb +11 -0
  59. data/my_api/config/environments/test.rb +9 -0
  60. data/my_api/config/routes.rb +17 -0
  61. data/my_api/db/.gitkeep +0 -0
  62. data/my_api/public/404.html +67 -0
  63. data/my_api/public/422.html +67 -0
  64. data/my_api/public/500.html +66 -0
  65. data/my_api/public/favicon.ico +0 -0
  66. data/my_api/public/index.html +91 -0
  67. data/my_api/spec/controllers/error_controller_spec.rb +43 -0
  68. data/my_api/spec/controllers/pagination_controller_spec.rb +73 -0
  69. data/my_api/spec/controllers/rest_controller_spec.rb +99 -0
  70. data/my_api/spec/controllers/status_controller_spec.rb +47 -0
  71. data/my_api/spec/fixtures/payloads/posts-index.json +51 -0
  72. data/my_api/spec/fixtures/payloads/posts-show.json +53 -0
  73. data/my_api/spec/spec_helper.rb +31 -0
  74. data/rails_app/rails_5.2/.rspec +3 -0
  75. data/rails_app/rails_5.2/Gemfile +18 -0
  76. data/rails_app/rails_5.2/Gemfile.lock +171 -0
  77. data/rails_app/rails_5.2/README.md +24 -0
  78. data/rails_app/rails_5.2/Rakefile +8 -0
  79. data/rails_app/rails_5.2/app/controllers/application_controller.rb +4 -0
  80. data/rails_app/rails_5.2/app/jobs/application_job.rb +4 -0
  81. data/rails_app/rails_5.2/bin/bundle +5 -0
  82. data/rails_app/rails_5.2/bin/rails +6 -0
  83. data/rails_app/rails_5.2/bin/rake +6 -0
  84. data/rails_app/rails_5.2/bin/setup +27 -0
  85. data/rails_app/rails_5.2/bin/update +27 -0
  86. data/rails_app/rails_5.2/config.ru +7 -0
  87. data/rails_app/rails_5.2/config/application.rb +37 -0
  88. data/rails_app/rails_5.2/config/boot.rb +6 -0
  89. data/rails_app/rails_5.2/config/credentials.yml.enc +1 -0
  90. data/rails_app/rails_5.2/config/environment.rb +7 -0
  91. data/rails_app/rails_5.2/config/environments/development.rb +41 -0
  92. data/rails_app/rails_5.2/config/environments/production.rb +70 -0
  93. data/rails_app/rails_5.2/config/environments/test.rb +38 -0
  94. data/rails_app/rails_5.2/config/initializers/application_controller_renderer.rb +9 -0
  95. data/rails_app/rails_5.2/config/initializers/backtrace_silencers.rb +8 -0
  96. data/rails_app/rails_5.2/config/initializers/cors.rb +17 -0
  97. data/rails_app/rails_5.2/config/initializers/filter_parameter_logging.rb +6 -0
  98. data/rails_app/rails_5.2/config/initializers/inflections.rb +17 -0
  99. data/rails_app/rails_5.2/config/initializers/mime_types.rb +5 -0
  100. data/rails_app/rails_5.2/config/initializers/wrap_parameters.rb +11 -0
  101. data/rails_app/rails_5.2/config/locales/en.yml +33 -0
  102. data/rails_app/rails_5.2/config/routes.rb +5 -0
  103. data/rails_app/rails_5.2/config/spring.rb +8 -0
  104. data/rails_app/rails_5.2/public/robots.txt +1 -0
  105. data/rails_app/rails_5.2/spec/rails_helper.rb +14 -0
  106. data/rails_app/rails_5.2/spec/spec_helper.rb +13 -0
  107. data/rails_app/rails_6.0/.rspec +3 -0
  108. data/rails_app/rails_6.0/Gemfile +17 -0
  109. data/rails_app/rails_6.0/Gemfile.lock +186 -0
  110. data/rails_app/rails_6.0/README.md +24 -0
  111. data/rails_app/rails_6.0/Rakefile +8 -0
  112. data/rails_app/rails_6.0/app/controllers/application_controller.rb +4 -0
  113. data/rails_app/rails_6.0/app/jobs/application_job.rb +9 -0
  114. data/rails_app/rails_6.0/bin/rails +6 -0
  115. data/rails_app/rails_6.0/bin/rake +6 -0
  116. data/rails_app/rails_6.0/bin/setup +27 -0
  117. data/rails_app/rails_6.0/config.ru +7 -0
  118. data/rails_app/rails_6.0/config/application.rb +39 -0
  119. data/rails_app/rails_6.0/config/boot.rb +6 -0
  120. data/rails_app/rails_6.0/config/credentials.yml.enc +1 -0
  121. data/rails_app/rails_6.0/config/environment.rb +7 -0
  122. data/rails_app/rails_6.0/config/environments/development.rb +39 -0
  123. data/rails_app/rails_6.0/config/environments/production.rb +90 -0
  124. data/rails_app/rails_6.0/config/environments/test.rb +41 -0
  125. data/rails_app/rails_6.0/config/initializers/application_controller_renderer.rb +9 -0
  126. data/rails_app/rails_6.0/config/initializers/backtrace_silencers.rb +8 -0
  127. data/rails_app/rails_6.0/config/initializers/cors.rb +17 -0
  128. data/rails_app/rails_6.0/config/initializers/filter_parameter_logging.rb +6 -0
  129. data/rails_app/rails_6.0/config/initializers/inflections.rb +17 -0
  130. data/rails_app/rails_6.0/config/initializers/mime_types.rb +5 -0
  131. data/rails_app/rails_6.0/config/initializers/wrap_parameters.rb +11 -0
  132. data/rails_app/rails_6.0/config/locales/en.yml +33 -0
  133. data/rails_app/rails_6.0/config/routes.rb +5 -0
  134. data/rails_app/rails_6.0/config/spring.rb +8 -0
  135. data/rails_app/rails_6.0/public/robots.txt +1 -0
  136. data/rails_app/rails_6.0/spec/rails_helper.rb +14 -0
  137. data/rails_app/rails_6.0/spec/spec_helper.rb +13 -0
  138. metadata +120 -5
  139. data/renovate.json +0 -21
@@ -1,7 +1,35 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2020-02-21 23:30:47 +0000 using RuboCop version 0.80.0.
3
+ # on 2020-09-15 23:30:28 UTC using RuboCop version 0.91.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 5
10
+ Lint/MissingSuper:
11
+ Exclude:
12
+ - 'lib/my_api_client/error_handling/generator.rb'
13
+ - 'lib/my_api_client/error_handling/retry_option_processor.rb'
14
+ - 'lib/my_api_client/integrations/bugsnag.rb'
15
+ - 'lib/my_api_client/request/executor.rb'
16
+ - 'lib/my_api_client/sleeper.rb'
17
+
18
+ # Offense count: 60
19
+ # Configuration parameters: AllowSubject.
20
+ RSpec/MultipleMemoizedHelpers:
21
+ Max: 15
22
+
23
+ # Offense count: 1
24
+ # Cop supports --auto-correct.
25
+ Style/HashTransformValues:
26
+ Exclude:
27
+ - 'lib/my_api_client/integrations/bugsnag.rb'
28
+
29
+ # Offense count: 3
30
+ # Cop supports --auto-correct.
31
+ Style/StringConcatenation:
32
+ Exclude:
33
+ - 'lib/my_api_client/request.rb'
34
+ - 'lib/my_api_client/rspec/matchers/request_to.rb'
35
+ - 'my_api/app/controllers/pagination_controller.rb'
@@ -1,6 +1,180 @@
1
1
  # Change log
2
2
 
3
- ## v0.14.0.pre (Feb 23, 2020)
3
+ ## v0.17.0 (Sep 20, 2020)
4
+
5
+ ### Feature
6
+
7
+ * [#303](https://github.com/ryz310/my_api_client/pull/303) Change the duration format to milliseconds ([@ryz310](https://github.com/ryz310))
8
+ * [#308](https://github.com/ryz310/my_api_client/pull/308) Add testing for api client generators ([@ryz310](https://github.com/ryz310))
9
+
10
+ ### Rubocop Challenge
11
+
12
+ * [#311](https://github.com/ryz310/my_api_client/pull/311) Style/GlobalStdStream-20200906233350 ([@ryz310](https://github.com/ryz310))
13
+ * [#312](https://github.com/ryz310/my_api_client/pull/312) Style/StringConcatenation-20200907233020 ([@ryz310](https://github.com/ryz310))
14
+ * [#313](https://github.com/ryz310/my_api_client/pull/313) Style/HashTransformValues-20200908233016 ([@ryz310](https://github.com/ryz310))
15
+ * [#316](https://github.com/ryz310/my_api_client/pull/316) Layout/EmptyLinesAroundAttributeAccessor-20200909233021 ([@ryz310](https://github.com/ryz310))
16
+ * [#320](https://github.com/ryz310/my_api_client/pull/320) Re-generate .rubocop_todo.yml with RuboCop v0.91.0 ([@ryz310](https://github.com/ryz310))
17
+
18
+ ### Dependabot
19
+
20
+ * [#299](https://github.com/ryz310/my_api_client/pull/299) ryz310/dependabot/bundler/bugsnag-6.17.0 ([@ryz310](https://github.com/ryz310))
21
+ * [#310](https://github.com/ryz310/my_api_client/pull/310) ryz310/dependabot/bundler/rubocop-performance-1.8.0 ([@ryz310](https://github.com/ryz310))
22
+ * [#314](https://github.com/ryz310/my_api_client/pull/314) ryz310/dependabot/bundler/activesupport-5.2.4.4 ([@ryz310](https://github.com/ryz310))
23
+ * [#315](https://github.com/ryz310/my_api_client/pull/315) ryz310/dependabot/bundler/my_api/actionview-6.0.3.3 ([@ryz310](https://github.com/ryz310))
24
+ * [#318](https://github.com/ryz310/my_api_client/pull/318) ryz310/dependabot/bundler/webmock-3.9.1 ([@ryz310](https://github.com/ryz310))
25
+ * [#319](https://github.com/ryz310/my_api_client/pull/319) ryz310/dependabot/bundler/rubocop-0.91.0 ([@ryz310](https://github.com/ryz310))
26
+ * [#321](https://github.com/ryz310/my_api_client/pull/321) ryz310/dependabot/bundler/my_api/puma-5.0.0 ([@ryz310](https://github.com/ryz310))
27
+
28
+ ## v0.16.1 (Aug 27, 2020)
29
+
30
+ ### Feature
31
+
32
+ * [#296](https://github.com/ryz310/my_api_client/pull/296) Support HTTP PUT method ([@ryz310](https://github.com/ryz310))
33
+
34
+ ### Rubocop Challenge
35
+
36
+ * [#256](https://github.com/ryz310/my_api_client/pull/256) Performance/StartWith-20200523233027 ([@ryz310](https://github.com/ryz310))
37
+ * [#268](https://github.com/ryz310/my_api_client/pull/268) Lint/RedundantCopDisableDirective-20200622233019 ([@ryz310](https://github.com/ryz310))
38
+ * [#289](https://github.com/ryz310/my_api_client/pull/289) Re-generate .rubocop_todo.yml with RuboCop v0.89.1 ([@ryz310](https://github.com/ryz310))
39
+ * [#293](https://github.com/ryz310/my_api_client/pull/293) RSpec/LeadingSubject-20200817233022 ([@ryz310](https://github.com/ryz310))
40
+
41
+ ### Dependabot
42
+
43
+ * [#232](https://github.com/ryz310/my_api_client/pull/232) ryz310/dependabot/bundler/faraday-1.0.1 ([@ryz310](https://github.com/ryz310))
44
+ * [#241](https://github.com/ryz310/my_api_client/pull/241) ryz310/dependabot/bundler/my_api/byebug-11.1.3 ([@ryz310](https://github.com/ryz310))
45
+ * [#243](https://github.com/ryz310/my_api_client/pull/243) ryz310/dependabot/bundler/yard-0.9.25 ([@ryz310](https://github.com/ryz310))
46
+ * [#248](https://github.com/ryz310/my_api_client/pull/248) ryz310/dependabot/bundler/activesupport-5.2.4.3 ([@ryz310](https://github.com/ryz310))
47
+ * [#251](https://github.com/ryz310/my_api_client/pull/251) ryz310/dependabot/bundler/my_api/puma-4.3.5 ([@ryz310](https://github.com/ryz310))
48
+ * [#257](https://github.com/ryz310/my_api_client/pull/257) ryz310/dependabot/bundler/my_api/dynomite-1.2.6 ([@ryz310](https://github.com/ryz310))
49
+ * [#264](https://github.com/ryz310/my_api_client/pull/264) ryz310/dependabot/bundler/my_api/rack-2.2.3 ([@ryz310](https://github.com/ryz310))
50
+ * [#265](https://github.com/ryz310/my_api_client/pull/265) ryz310/dependabot/bundler/my_api/actionpack-6.0.3.2 ([@ryz310](https://github.com/ryz310))
51
+ * [#266](https://github.com/ryz310/my_api_client/pull/266) ryz310/dependabot/bundler/my_api/capybara-3.33.0 ([@ryz310](https://github.com/ryz310))
52
+ * [#281](https://github.com/ryz310/my_api_client/pull/281) ryz310/dependabot/bundler/rubocop-performance-1.7.1 ([@ryz310](https://github.com/ryz310))
53
+ * [#287](https://github.com/ryz310/my_api_client/pull/287) ryz310/dependabot/bundler/my_api/kramdown-2.3.0 ([@ryz310](https://github.com/ryz310))
54
+ * [#290](https://github.com/ryz310/my_api_client/pull/290) ryz310/dependabot/bundler/bugsnag-6.16.0 ([@ryz310](https://github.com/ryz310))
55
+ * [#294](https://github.com/ryz310/my_api_client/pull/294) ryz310/dependabot/bundler/my_api/jets-2.3.17 ([@ryz310](https://github.com/ryz310))
56
+ * [#295](https://github.com/ryz310/my_api_client/pull/295) ryz310/dependabot/bundler/rubocop-rspec-1.43.2 ([@ryz310](https://github.com/ryz310))
57
+
58
+ ### Misc
59
+
60
+ * [#271](https://github.com/ryz310/my_api_client/pull/271) Minor fixes ([@ryz310](https://github.com/ryz310))
61
+
62
+ ## v0.16.0 (Mar 29, 2020)
63
+
64
+ ### Breaking Change
65
+
66
+ #### [#225](https://github.com/ryz310/my_api_client/pull/225) Raise an exception whenever an error is detected ([@ryz310](https://github.com/ryz310))
67
+
68
+ Until now, using `with` or `block` in `error_handling` did not automatically raise an exception, but will now always raise an exception when an error is detected.
69
+ You can specify raising error class with `raise` option.
70
+
71
+ **Before**
72
+
73
+ ```rb
74
+ error_handling json: { '$.errors.code': 10..19 }, with: :my_error_handling
75
+
76
+ def my_error_handling
77
+ # Executes this method when an error is detected.
78
+ # No exception is raised. You can raise an error if necessary.
79
+ end
80
+ ```
81
+ ```rb
82
+ error_handling status_code: 500..599 do |_params, logger|
83
+ # Executes this block when an error is detected.
84
+ # No exception is raised. You can raise an error if necessary.
85
+ end
86
+ ```
87
+
88
+ **After**
89
+
90
+ ```rb
91
+ error_handling json: { '$.errors.code': 10..19 }, with: :my_error_handling
92
+
93
+ def my_error_handling
94
+ # Executes this method when an error is detected.
95
+ # And then raise `MyApiClient::Error`.
96
+ end
97
+ ```
98
+ ```rb
99
+ error_handling status_code: 500..599 do |params, logger|
100
+ # Executes this block when an error is detected.
101
+ # And then raise `MyApiClient::Error`.
102
+ end
103
+ ```
104
+
105
+ #### [#226](https://github.com/ryz310/my_api_client/pull/226) Default error handlers ([@ryz310](https://github.com/ryz310))
106
+
107
+ Until now, you needed define all `error_handling` or `retry_on` yourself. But will now some `error_handling` and `retry_on` are prepared as default.
108
+
109
+ You can check default `error_handling` or `retry_on` here.
110
+
111
+ See: https://github.com/ryz310/my_api_client/blob/master/lib/my_api_client/default_error_handlers.rb
112
+
113
+ ### Dependabot
114
+
115
+ * [#227](https://github.com/ryz310/my_api_client/pull/227) ryz310/dependabot/bundler/pry-byebug-3.9.0 ([@ryz310](https://github.com/ryz310))
116
+ * [#228](https://github.com/ryz310/my_api_client/pull/228) ryz310/dependabot/bundler/my_api/jets-2.3.15 ([@ryz310](https://github.com/ryz310))
117
+
118
+ ### Misc
119
+
120
+ * [#229](https://github.com/ryz310/my_api_client/pull/229) Edit dependabot configuration ([@ryz310](https://github.com/ryz310))
121
+
122
+ ## v0.15.0 (Mar 21, 2020)
123
+
124
+ ### Feature
125
+
126
+ * [#220](https://github.com/ryz310/my_api_client/pull/220) Pageable HTTP request ([@ryz310](https://github.com/ryz310))
127
+ * Add `#pageable_get` method (alias: `#pget`)
128
+ * For example:
129
+ * API client definition
130
+ ```ruby
131
+ class MyPaginationApiClient < ApplicationApiClient
132
+ endpoint 'https://example.com/v1'
133
+
134
+ # GET pagination?page=1
135
+ def pagination
136
+ pageable_get 'pagination', paging: '$.links.next', headers: headers, query: { page: 1 }
137
+ end
138
+
139
+ private
140
+
141
+ def headers
142
+ { 'Content-Type': 'application/json;charset=UTF-8' }
143
+ end
144
+ end
145
+ ```
146
+ * The pagination API response
147
+ ```json
148
+ {
149
+ "links": {
150
+ "next": "https://example.com/pagination?page=3",
151
+ "previous": "https://example.com/pagination?page=1",
152
+ },
153
+ "page": 2
154
+ }
155
+ ```
156
+ * Usage
157
+ ```ruby
158
+ api_clinet = MyPaginationApiClient.new
159
+ api_clinet.pagination.each do |response|
160
+ # Do something.
161
+ end
162
+
163
+ p = api_clinet.pagination
164
+ p.next # => 1st page result
165
+ p.next # => 2nd page result
166
+ p.next # => 3rd page result
167
+ ```
168
+ * [#223](https://github.com/ryz310/my_api_client/pull/223) Use Enumerator::Lazy instead of Enumerator ([@ryz310](https://github.com/ryz310))
169
+
170
+ ## v0.14.0 (Mar 14, 2020)
171
+
172
+ ### Feature
173
+
174
+ * [#211](https://github.com/ryz310/my_api_client/pull/211) Integration testing using the jets framework ([@ryz310](https://github.com/ryz310))
175
+ * [#213](https://github.com/ryz310/my_api_client/pull/213) Add status API to integration testing ([@ryz310](https://github.com/ryz310))
176
+ * [#214](https://github.com/ryz310/my_api_client/pull/214) Add error API to integration testing ([@ryz310](https://github.com/ryz310))
177
+ * [#215](https://github.com/ryz310/my_api_client/pull/215) Update the REST API to enhance integration testing ([@ryz310](https://github.com/ryz310))
4
178
 
5
179
  ### Refactoring
6
180
 
@@ -60,6 +234,7 @@
60
234
  ### Rubocop Challenge
61
235
 
62
236
  * [#205](https://github.com/ryz310/my_api_client/pull/205) Re-generate .rubocop_todo.yml with RuboCop v0.80.0 ([@ryz310](https://github.com/ryz310))
237
+ * [#210](https://github.com/ryz310/my_api_client/pull/210) Re-generate .rubocop_todo.yml with RuboCop v0.80.1 ([@ryz310](https://github.com/ryz310))
63
238
 
64
239
  ### Dependabot
65
240
 
@@ -68,6 +243,7 @@
68
243
  * [#194](https://github.com/ryz310/my_api_client/pull/194) Bump bugsnag from 6.12.2 to 6.13.0 ([@ryz310](https://github.com/ryz310))
69
244
  * [#197](https://github.com/ryz310/my_api_client/pull/197) Bump webmock from 3.8.0 to 3.8.1 ([@ryz310](https://github.com/ryz310))
70
245
  * [#199](https://github.com/ryz310/my_api_client/pull/199) Bump webmock from 3.8.1 to 3.8.2 ([@ryz310](https://github.com/ryz310))
246
+ * [#216](https://github.com/ryz310/my_api_client/pull/216) Bump webmock from 3.8.2 to 3.8.3 ([@ryz310](https://github.com/ryz310))
71
247
 
72
248
  ### Renovate
73
249
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- my_api_client (0.14.0.pre)
4
+ my_api_client (0.17.0)
5
5
  activesupport (>= 4.2.0)
6
6
  faraday (>= 0.17.1)
7
7
  jsonpath
@@ -10,79 +10,81 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- activesupport (5.2.4.1)
13
+ activesupport (5.2.4.4)
14
14
  concurrent-ruby (~> 1.0, >= 1.0.2)
15
15
  i18n (>= 0.7, < 2)
16
16
  minitest (~> 5.1)
17
17
  tzinfo (~> 1.1)
18
18
  addressable (2.7.0)
19
19
  public_suffix (>= 2.0.2, < 5.0)
20
- ast (2.4.0)
21
- bugsnag (6.13.0)
20
+ ast (2.4.1)
21
+ bugsnag (6.17.0)
22
22
  concurrent-ruby (~> 1.0)
23
- byebug (11.1.1)
24
- coderay (1.1.2)
25
- concurrent-ruby (1.1.6)
26
- crack (0.4.3)
27
- safe_yaml (~> 1.0.0)
28
- diff-lcs (1.3)
23
+ byebug (11.1.3)
24
+ coderay (1.1.3)
25
+ concurrent-ruby (1.1.7)
26
+ crack (0.4.4)
27
+ diff-lcs (1.4.4)
29
28
  docile (1.3.2)
30
- faraday (1.0.0)
29
+ faraday (1.0.1)
31
30
  multipart-post (>= 1.2, < 3)
32
- hashdiff (1.0.0)
33
- i18n (1.8.2)
31
+ hashdiff (1.0.1)
32
+ i18n (1.8.5)
34
33
  concurrent-ruby (~> 1.0)
35
- jaro_winkler (1.5.4)
36
- json (2.3.0)
34
+ json (2.3.1)
37
35
  jsonpath (1.0.5)
38
36
  multi_json
39
37
  to_regexp (~> 0.2.1)
40
- method_source (0.9.2)
41
- minitest (5.14.0)
42
- multi_json (1.14.1)
38
+ method_source (1.0.0)
39
+ minitest (5.14.2)
40
+ multi_json (1.15.0)
43
41
  multipart-post (2.1.1)
44
- parallel (1.19.1)
45
- parser (2.7.0.2)
46
- ast (~> 2.4.0)
47
- pry (0.12.2)
48
- coderay (~> 1.1.0)
49
- method_source (~> 0.9.0)
50
- pry-byebug (3.8.0)
42
+ parallel (1.19.2)
43
+ parser (2.7.1.4)
44
+ ast (~> 2.4.1)
45
+ pry (0.13.1)
46
+ coderay (~> 1.1)
47
+ method_source (~> 1.0)
48
+ pry-byebug (3.9.0)
51
49
  byebug (~> 11.0)
52
- pry (~> 0.10)
53
- public_suffix (4.0.3)
50
+ pry (~> 0.13.0)
51
+ public_suffix (4.0.6)
54
52
  rainbow (3.0.0)
55
53
  rake (13.0.1)
54
+ regexp_parser (1.8.0)
56
55
  rexml (3.2.4)
57
56
  rspec (3.9.0)
58
57
  rspec-core (~> 3.9.0)
59
58
  rspec-expectations (~> 3.9.0)
60
59
  rspec-mocks (~> 3.9.0)
61
- rspec-core (3.9.1)
62
- rspec-support (~> 3.9.1)
63
- rspec-expectations (3.9.0)
60
+ rspec-core (3.9.2)
61
+ rspec-support (~> 3.9.3)
62
+ rspec-expectations (3.9.2)
64
63
  diff-lcs (>= 1.2.0, < 2.0)
65
64
  rspec-support (~> 3.9.0)
66
65
  rspec-mocks (3.9.1)
67
66
  diff-lcs (>= 1.2.0, < 2.0)
68
67
  rspec-support (~> 3.9.0)
69
- rspec-support (3.9.2)
68
+ rspec-support (3.9.3)
70
69
  rspec_junit_formatter (0.4.1)
71
70
  rspec-core (>= 2, < 4, != 2.12.0)
72
- rubocop (0.80.0)
73
- jaro_winkler (~> 1.5.1)
71
+ rubocop (0.91.0)
74
72
  parallel (~> 1.10)
75
- parser (>= 2.7.0.1)
73
+ parser (>= 2.7.1.1)
76
74
  rainbow (>= 2.2.2, < 4.0)
75
+ regexp_parser (>= 1.7)
77
76
  rexml
77
+ rubocop-ast (>= 0.4.0, < 1.0)
78
78
  ruby-progressbar (~> 1.7)
79
- unicode-display_width (>= 1.4.0, < 1.7)
80
- rubocop-performance (1.5.2)
81
- rubocop (>= 0.71.0)
82
- rubocop-rspec (1.38.1)
83
- rubocop (>= 0.68.1)
79
+ unicode-display_width (>= 1.4.0, < 2.0)
80
+ rubocop-ast (0.4.2)
81
+ parser (>= 2.7.1.4)
82
+ rubocop-performance (1.8.1)
83
+ rubocop (>= 0.87.0)
84
+ rubocop-ast (>= 0.4.0)
85
+ rubocop-rspec (1.43.2)
86
+ rubocop (~> 0.87)
84
87
  ruby-progressbar (1.10.1)
85
- safe_yaml (1.0.5)
86
88
  sawyer (0.8.2)
87
89
  addressable (>= 2.3.5)
88
90
  faraday (> 0.8, < 2.0)
@@ -93,14 +95,14 @@ GEM
93
95
  simplecov-html (0.10.2)
94
96
  thread_safe (0.3.6)
95
97
  to_regexp (0.2.1)
96
- tzinfo (1.2.6)
98
+ tzinfo (1.2.7)
97
99
  thread_safe (~> 0.1)
98
- unicode-display_width (1.6.1)
99
- webmock (3.8.2)
100
+ unicode-display_width (1.7.0)
101
+ webmock (3.9.1)
100
102
  addressable (>= 2.3.6)
101
103
  crack (>= 0.3.2)
102
104
  hashdiff (>= 0.4.0, < 2.0.0)
103
- yard (0.9.24)
105
+ yard (0.9.25)
104
106
 
105
107
  PLATFORMS
106
108
  ruby
@@ -122,4 +124,4 @@ DEPENDENCIES
122
124
  yard
123
125
 
124
126
  BUNDLED WITH
125
- 2.1.2
127
+ 2.1.4
@@ -6,7 +6,9 @@ MyApiClient は API リクエストクラスを作成するための汎用的な
6
6
 
7
7
  ただし、 Sawyer はダミーデータの作成が難しかったり、他の gem で競合することがよくあるので、将来的には依存しないように変更していくかもしれません。
8
8
 
9
- また、 Ruby on Rails で利用することを想定してますが、それ以外の環境でも動作するように作っているつもりです。不具合などあれば Issue ページからご報告下さい。
9
+ また、 Ruby on Rails で利用することを想定してますが、それ以外の環境でも動作するように作っています。不具合などあれば Issue ページからご報告下さい。
10
+
11
+ [toc]
10
12
 
11
13
  ## Supported Versions
12
14
 
@@ -83,32 +85,95 @@ api_clinet.get_users #=> #<Sawyer::Response>
83
85
 
84
86
  続いて、 `#get_users` や `#post_user` を定義します。メソッド名には API のタイトルを付けると良いと思います。メソッド内部で `#get` や `#post` を呼び出していますが、これがリクエスト時の HTTP Method になります。他にも `#patch` `#put` `#delete` が利用可能です。
85
87
 
88
+ ### Pagination
89
+
90
+ API の中にはレスポンスに結果の続きを取得するための URL を含んでいるものがあります。
91
+
92
+ MyApiClient では、このような API を enumerable に扱うための `#pageable_get` というメソッドを用意しています。以下に例を示します。
93
+
94
+ ```ruby
95
+ class MyPaginationApiClient < ApplicationApiClient
96
+ endpoint 'https://example.com/v1'
97
+
98
+ # GET pagination?page=1
99
+ def pagination
100
+ pageable_get 'pagination', paging: '$.links.next', headers: headers, query: { page: 1 }
101
+ end
102
+
103
+ private
104
+
105
+ def headers
106
+ { 'Content-Type': 'application/json;charset=UTF-8' }
107
+ end
108
+ end
109
+ ```
110
+
111
+ 上記の例の場合、最初に `GET https://example.com/v1/pagination?page=1` に対してリクエストが実行され、続けてレスポンス JSON の `$.link.next` に含まれる URL に対して enumerable にリクエストを実行します。
112
+
113
+ 例えば以下のようなレスポンスであれば、`$.link.next` は `"https://example.com/pagination?page=3"` を示します。
114
+
115
+ ```json
116
+ {
117
+ "links": {
118
+ "next": "https://example.com/pagination?page=3",
119
+ "previous": "https://example.com/pagination?page=1",
120
+ },
121
+ "page": 2
122
+ }
123
+ ```
124
+
125
+ そして `#pageable_get` は [Enumerator::Lazy](https://docs.ruby-lang.org/ja/latest/class/Enumerator=3a=3aLazy.html) を返すので、 `#each` や `#next` を実行することで次の結果を取得できます。
126
+
127
+ ```ruby
128
+ api_clinet = MyPaginationApiClient.new
129
+ api_clinet.pagination.each do |response|
130
+ # Do something.
131
+ end
132
+
133
+ p = api_clinet.pagination
134
+ p.next # => 1st page result
135
+ p.next # => 2nd page result
136
+ p.next # => 3rd page result
137
+ ```
138
+
139
+ なお、`#each` はレスポンスに含まれる `paging` の値が nil になるまで繰り返されるのでご注意ください。例えば `#take` と組み合わせることでページネーションの上限を設定できます。
140
+
141
+ `#pageable_get` の alias として `#pget` も利用可能です。
142
+
143
+ ```ruby
144
+ # GET pagination?page=1
145
+ def pagination
146
+ pget 'pagination', paging: '$.links.next', headers: headers, query: { page: 1 }
147
+ end
148
+ ```
149
+
86
150
  ### Error handling
87
151
 
88
- 上記のコードにエラーハンドリングを追加してみます。
152
+ `my_api_client` ではレスポンスの内容によって例外を発生させるエラーハンドリングを定義できます。ここでは例として前述のコードにエラーハンドリングを定義しています。
89
153
 
90
154
  ```ruby
91
155
  class ExampleApiClient < MyApiClient::Base
92
156
  endpoint 'https://example.com'
93
157
 
94
- error_handling status_code: 400..499, raise: MyApiClient::ClientError
158
+ error_handling status_code: 400..499,
159
+ raise: MyApiClient::ClientError
95
160
 
96
- error_handling status_code: 500..599 do |params, logger|
161
+ error_handling status_code: 500..599, raise: MyApiClient::ServerError do |_params, logger|
97
162
  logger.warn 'Server error occurred.'
98
- raise MyApiClient::ServerError, params
99
163
  end
100
164
 
101
- error_handling json: { '$.errors.code': 10..19 }, with: :my_error_handling
165
+ error_handling json: { '$.errors.code': 10..19 },
166
+ raise: MyApiClient::ClientError,
167
+ with: :my_error_handling
102
168
 
103
169
  # Omission...
104
170
 
105
171
  private
106
172
 
107
- # @param params [MyApiClient::Params::Params] HTTP req and res params
173
+ # @param params [MyApiClient::Params::Params] HTTP reqest and response params
108
174
  # @param logger [MyApiClient::Request::Logger] Logger for a request processing
109
175
  def my_error_handling(params, logger)
110
176
  logger.warn "Response Body: #{params.response.body.inspect}"
111
- raise MyApiClient::ClientError, params
112
177
  end
113
178
  end
114
179
  ```
@@ -121,29 +186,26 @@ error_handling status_code: 400..499, raise: MyApiClient::ClientError
121
186
 
122
187
  これは `ExampleApiClient` からのリクエスト全てにおいて、レスポンスのステータスコードが `400..499` であった場合に `MyApiClient::ClientError` が例外として発生するようになります。 `ExampleApiClient` を継承したクラスにもエラーハンドリングは適用されます。ステータスコードのエラーハンドリングは親クラスで定義すると良いと思います。
123
188
 
124
- なお、 `status_code` には `Integer` `Range` `Regexp` が指定可能です。`raise` には `MyApiClient::Error` を継承したクラスが指定可能です。`my_api_client` で標準で定義しているエラークラスについては以下のソースコードをご確認下さい。
189
+ なお、 `status_code` には `Integer` `Range` `Regexp` が指定可能です。
190
+
191
+ `raise` には `MyApiClient::Error` を継承したクラスが指定可能です。`my_api_client` で標準で定義しているエラークラスについては以下のソースコードをご確認下さい。 `raise` を省略した場合は `MyApiClient::Error` を発生するようになります。
125
192
 
126
- https://github.com/ryz310/my_api_client/blob/master/lib/my_api_client/errors.rb
193
+ https://github.com/ryz310/my_api_client/blob/master/lib/my_api_client/errors
127
194
 
128
- 次に、 `raise` の代わりに `block` を指定する場合について。
195
+ 次に、 `block` を指定する場合について。
129
196
 
130
197
  ```ruby
131
- error_handling status_code: 500..599 do |params, logger|
198
+ error_handling status_code: 500..599, raise: MyApiClient::ServerError do |_params, logger|
132
199
  logger.warn 'Server error occurred.'
133
- raise MyApiClient::ServerError, params
134
200
  end
135
201
  ```
136
202
 
137
- 上記の例であれば、ステータスコードが `500..599` の場合に `block` の内容が実行れます。引数の `params` にはリクエスト情報とレスポンス情報が含まれています。`logger` はログ出力用インスタンスですが、このインスタンスを使ってログ出力すると、以下のようにリクエスト情報がログ出力に含まれるようになり、デバッグの際に便利です。
203
+ 上記の例であれば、ステータスコードが `500..599` の場合に `MyApiClient::ServerError` を発生させる前に `block` の内容が実行れます。引数の `params` にはリクエスト情報とレスポンス情報が含まれています。`logger` はログ出力用インスタンスですが、このインスタンスを使ってログ出力すると、以下のようにリクエスト情報がログ出力に含まれるようになり、デバッグの際に便利です。
138
204
 
139
205
  ```text
140
206
  API request `GET https://example.com/path/to/resouce`: "Server error occurred."
141
207
  ```
142
208
 
143
- リクエストに失敗した場合は例外処理を実行する、という設計が一般的だと思われるので、基本的にブロックの最後に `raise` を実行する事になると思います。
144
-
145
- 最後に `json` と `with` を利用する場合について。
146
-
147
209
  ```ruby
148
210
  error_handling json: { '$.errors.code': 10..19 }, with: :my_error_handling
149
211
  ```
@@ -159,17 +221,28 @@ error_handling json: { '$.errors.code': 10..19 }, with: :my_error_handling
159
221
  }
160
222
  ```
161
223
 
162
- `with` にはインスタンスメソッド名を指定することで、エラーを検出した際に任意のメソッドを実行させることができます。メソッドに渡される引数は `block` 定義の場合と同じく `params` と `logger` です。
224
+ `with` にはインスタンスメソッド名を指定することで、エラーを検出した際、例外を発生させる前に任意のメソッドを実行させることができます。メソッドに渡される引数は `block` 定義の場合と同じく `params` と `logger` です。なお、 `block` と `with` は同時には利用できません。
163
225
 
164
226
  ```ruby
165
227
  # @param params [MyApiClient::Params::Params] HTTP req and res params
166
228
  # @param logger [MyApiClient::Request::Logger] Logger for a request processing
167
229
  def my_error_handling(params, logger)
168
230
  logger.warn "Response Body: #{params.response.body.inspect}"
169
- raise MyApiClient::ClientError, params
170
231
  end
171
232
  ```
172
233
 
234
+ #### Default error handling
235
+
236
+ `my_api_client` では、標準でステータスコード 400 ~ 500 番台のレスポンスを例外として処理するようにしています。ステータスコードが 400 番台場合は `MyApiClient::ClientError`、 500 番台の場合は `MyApiClient::ServerError` を継承した例外クラスが raise されます。
237
+
238
+ また、 `MyApiClient::NetworkError` に対しても標準で `retry_on` が定義されています。
239
+
240
+ いずれも override 可能ですので、必要に応じて `error_handling` を定義して下さい。
241
+
242
+ 以下のファイルで定義しています。
243
+
244
+ https://github.com/ryz310/my_api_client/blob/master/lib/my_api_client/default_error_handlers.rb
245
+
173
246
  #### Symbol を利用する
174
247
 
175
248
  ```ruby
@@ -238,7 +311,9 @@ end
238
311
 
239
312
  API リクエストを何度も実行していると回線の不調などによりネットワークエラーが発生する事があります。長時間ネットワークが使えなくなるケースもありますが、瞬間的なエラーであるケースも多々あります。 `MyApiClient` ではネットワーク系の例外はまとめて `MyApiClient::NetworkError` として `raise` されます。この例外の詳細は後述しますが、 `retry_on` を利用する事で、 `ActiveJob` のように任意の例外処理を補足して、一定回数、一定の期間を空けて API リクエストをリトライさせる事ができます。
240
313
 
241
- ただし、 `ActiveJob` とは異なり同期処理でリトライするため、ネットワークの瞬断に備えたリトライ以外ではあまり使う機会はないのではないかと思います。上記の例のように API Limit に備えてリトライするケースもあるかと思いますが、こちらは `ActiveJob` で対応した方が良いと思います。
314
+ なお、 `retry_on MyApiClient::NetworkError` は標準実装されているため、特別に定義せずとも自動的に適用されます。 `wait` `attempts` に任意の値を設定したい場合のみ定義してご利用ください。
315
+
316
+ ただし、 `ActiveJob` とは異なり同期処理でリトライするため、ネットワークの瞬断に備えたリトライ以外ではあまり使う機会はないのではないかと思います。上記の例のように API Rate Limit に備えてリトライするケースもあるかと思いますが、こちらは `ActiveJob` で対応した方が良いかもしれません。
242
317
 
243
318
  ちなみに一応 `discard_on` も実装していますが、作者自身が有効な用途を見出せていないので、詳細は割愛します。良い利用方法があれば教えてください。
244
319
 
@@ -567,6 +642,66 @@ rescue MyApiClient::Error => e
567
642
  end
568
643
  ```
569
644
 
645
+ ## Deployment
646
+
647
+ この gem のリリースには [gem_comet](https://github.com/ryz310/gem_comet) を利用しています。
648
+ `gem_comet` の README.md にも使い方が載っていますが、備忘録のため、こちらにもリリースフローを記載しておきます。
649
+
650
+ ### Preparement
651
+
652
+ 以下のコマンドで `.envrc` を作成し、 `GITHUB_ACCESS_TOKEN` を設定します。
653
+
654
+ ```sh
655
+ $ cp .envrc.skeleton .envrc
656
+ ```
657
+
658
+ 以下のコマンドで `gem_comet` をインストールします。
659
+
660
+ ```sh
661
+ $ gem install gem_comet
662
+ ```
663
+
664
+ ### USAGE
665
+
666
+ 以下のコマンドで、最後のリリースから現在までに merge した PR の一覧を確認できます。
667
+
668
+ ```sh
669
+ $ gem_comet changelog
670
+ ```
671
+
672
+ 以下のコマンドで gem のリリースを実行します。
673
+ `{VERSION}` には新しく付与するバージョン番号を指定します。
674
+
675
+ ```sh
676
+ $ gem_comet release {VERSION}
677
+ ```
678
+
679
+ 実行すると、 https://github.com/ryz310/my_api_client/pulls に以下のような PR が作成されます。
680
+
681
+ * [Update v0\.16\.1](https://github.com/ryz310/my_api_client/pull/297)
682
+ * [Release v0\.16\.1](https://github.com/ryz310/my_api_client/pull/298)
683
+
684
+ まず、 `Update v{VERSION}` という PR から merge に取り掛かります。
685
+
686
+ PR のコメントにも TODO が記載されていますが、まず、バージョン番号が正しく採番されているかを確認します。
687
+
688
+ See: [314a4c0](https://github.com/ryz310/my_api_client/pull/297/commits/314a4c06f66324ce77b640b1ee8db5c84ee038a2)
689
+
690
+ 次に `CHANGELOG.md` を編集して、 CHANGELOG を見やすく整理します。
691
+
692
+ See: [33a2d17](https://github.com/ryz310/my_api_client/pull/297/commits/33a2d1703c773813c837e74ee3181906b2f2e502)
693
+
694
+ これらが整ったら、 `Update v{VERSION}` を merge します。
695
+
696
+ これでリリース準備が整ったので、`Release v{VERSION}` の merge に取り掛かります。
697
+
698
+ この PR にこれからリリースする gem に対する変更が全て載っています。
699
+ 変更内容の最終確認をして、 CI も通ったことを確認したら `Release v{VERSION}` を merge します。
700
+
701
+ あとは Circle CI 側で gem のリリースが自動実行されるので、暫く待ちましょう。
702
+
703
+ お疲れさまでした :tea:
704
+
570
705
  ## Contributing
571
706
 
572
707
  不具合の報告や Pull Request を歓迎しています。OSS という事で自分はなるべく頑張って英語を使うようにしていますが、日本語での報告でも大丈夫です :+1: