someapi 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f026e9cad3240ec1c275409e82272d601ca13230
4
+ data.tar.gz: e73c051d5f2eba1c9f10e90cc948365be6d9c05b
5
+ SHA512:
6
+ metadata.gz: c64f30f3523c35d6604c939553a321faab0fc8b05f45c00ddd7fea0d8201a01c263a48186bc54dfec9f9d561c177e9ec22513bb47f030b2b96b7c5ee99b9854b
7
+ data.tar.gz: f97a01af2f90419dbe770d16e0e14c2ed75309e4717cc0d1751007e93d68111fbb35cb81b3c7494dd26f0fc14f928a206940b7113b6070a32c79a0c377fdf7c2
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in someapi.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Daniel Smith
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # SomeAPI
2
+
3
+ Built around HTTParty, SomeAPI provides a generic wrapper for your favourite RESTful WebAPI. Simply extend Some::API and apply your usual HTTParty options like base_uri, then call your new API and party harder!
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'someapi'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install someapi
18
+
19
+ ## Party harder
20
+
21
+ It's easier than 123!
22
+
23
+ 1. Create your wrapper:
24
+
25
+ class Github < Some::API
26
+ base_uri 'https://api.github.com'
27
+ headers 'User-Agent' => 'p45-dashboard'
28
+ default_params 'client_id' => ENV['GITHUB_CLIENT_ID'],
29
+ 'client_secret' => ENV['GITHUB_CLIENT_SECRET']
30
+ format :json
31
+ end
32
+
33
+ 2. Start using it! Simply string method calls and subscripts together like it's a real API wrapper. Add a bang (`!`) at the end to initiate the HTTP request, returning an HTTParty response, so all your favourite HTTParty features are still intact. Party on!
34
+
35
+ github = Guthub.new
36
+ ...
37
+ github.get.users[@username].repos!
38
+ github.post.repos[@username][@repo].pulls! body: { title: "Foo", body: "Pull my Foo", ... }
39
+ github.delete.repos.[@username][@repo].!
40
+
41
+ ## Make a mockery of your tests
42
+
43
+ Don't stub your toe on external services!
44
+
45
+ 1. Add `gem 'webmock'` to your Gemfile under the test group
46
+
47
+ 2. Add the following somewhere in your testing framework's configuration (like `spec_helper.rb`)
48
+
49
+ Some::API.include WebMock::API
50
+
51
+ 3. Adding `stub` before the HTTP method in a SomeAPI request will instead return a Webmock stub after the bang.
52
+
53
+ github = Github.new
54
+ ...
55
+ github.stub.get.users[@username].repos!.
56
+ to_return status: 200, body: @somehash.to_json
57
+
58
+ Stubs look exactly the same as their corresponding requests except for the presence of `stub`, so you can literally copy-pasta from your controllers to your specs and vice-versa without fiddling.
59
+
60
+ ## Tips and Gotchas
61
+
62
+ If your request ends in a `[someth]` remember to put a dot before the bang, as in the examples. Ruby doesn't define the (very odd and mostly useless actually) operator for `[]!`.
63
+
64
+ Posting hashes can be done more succinctly by using the `<<` operator, as follows (using the post example from above):
65
+
66
+ github.post.repos[@username][@repo].pulls << { title: "Foo", body: "Pull my Foo", ... }
67
+
68
+ Also note that every time you do this (put the bang at the beginning of a request):
69
+
70
+ !github.get.users[@some_user]
71
+
72
+ a baby seal/platypus/kitten will die a horrific death. Also, it looks really bad and will confuse the crap out of you and your peers.
73
+
74
+ ## Thank you for helping us help you help us all
75
+
76
+ 1. Fork it ( https://github.com/[my-github-username]/someapi/fork )
77
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
78
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
79
+ 4. Push to the branch (`git push origin my-new-feature`)
80
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,3 @@
1
+ module Some
2
+ VERSION = "0.0.1"
3
+ end
data/lib/someapi.rb ADDED
@@ -0,0 +1,135 @@
1
+ require "someapi/version"
2
+
3
+ require 'httparty'
4
+
5
+ module Some
6
+
7
+ class API
8
+ include HTTParty
9
+
10
+ API_REGEX = /^[a-zA-Z0-9_]+[!]?$/
11
+
12
+ def initialize options={}, meth=nil, path=nil, stubbed=false
13
+ @meth = meth
14
+ @path = path
15
+ @options = options
16
+
17
+ # stubbed is a flag set when you're stubbing the API call
18
+ # used in testing
19
+ # just call 'stub' in the call chain before the http_method method
20
+ @stubbed = stubbed
21
+ end
22
+
23
+ # http_method methods
24
+ # used in the call chain to set the http method
25
+ %W(get post put patch delete copy move head options).each do |meth|
26
+ define_method(meth) do
27
+ unless @meth
28
+ self.class.new Hash.new, meth.to_s, nil, @stubbed
29
+ else
30
+ self[meth]
31
+ end
32
+ end
33
+ end
34
+
35
+ # use in the call chain to flag this request as a stub
36
+ # used in testing for setting up API-call stubs
37
+ def stub
38
+ unless @meth
39
+ self.class.new Hash.new, @meth, @path, true
40
+ else
41
+ self['stub']
42
+ end
43
+ end
44
+
45
+ # sort of an alias for 'posting' (or whatever) an object
46
+ # just syntactic sugar for {body: obj} really
47
+ # I would have used '=' but that would return the object you posted! >.<
48
+ def << obj
49
+ self.! body: obj
50
+ end
51
+
52
+ # seriously this could be alias_method :>>, :!
53
+ def >> options
54
+ self.! options
55
+ end
56
+
57
+ # 'calls' the API request
58
+ # (or makes the stub, if stubbed)
59
+ def ! options = {}
60
+ unless @stubbed
61
+ self.class.send(@meth, @path || '/', deep_merge(options,@options))
62
+ else
63
+ uri = "#{self.class.base_uri}#{@path}"
64
+
65
+ deep_merge(options,@options)
66
+ process_headers(options)
67
+ process_query(options)
68
+ options = self.class.default_options.
69
+ merge(@options.merge(options))
70
+
71
+ stub_request(@meth.to_sym, uri.to_s).with(options)
72
+ end
73
+ end
74
+
75
+ # chains 'thing' onto URL path
76
+ def [] thing
77
+ self.class.new @options, @meth, "#{@path || ''}/#{thing}", @stubbed
78
+ end
79
+
80
+ # this is where the fun begins...
81
+ def method_missing meth, *args, &block
82
+ meths = meth.to_s
83
+ if @meth && meths =~ API_REGEX
84
+
85
+ if meths.end_with?('!')
86
+ # `foo! bar' is syntactic sugar for `foo.! bar'
87
+ self[meths[0...-1]].!(args[0] || {})
88
+
89
+ else
90
+ # chain the method name onto URL path
91
+ self[meths]
92
+ end
93
+ else
94
+ super
95
+ end
96
+ end
97
+
98
+ def respond_to_missing? meth
99
+ @meth && meth.to_s =~ API_REGEX
100
+ end
101
+
102
+ private
103
+
104
+ # shamelessly stolen from HTTParty
105
+ def process_headers(options)
106
+ if options[:headers] && self.class.headers.any?
107
+ options[:headers] = self.class.headers.merge(options[:headers])
108
+ end
109
+ end
110
+
111
+ # shamelessly copied from above, but for :query
112
+ def process_query(options)
113
+ if self.class.default_options[:default_params]
114
+ options[:query] = self.class.default_options[:default_params].
115
+ merge(options[:query] || {})
116
+ end
117
+ end
118
+
119
+ # merge a hash within a hash from two hashes (yo-dawg...)
120
+ def merge_stuff(a,b,tag)
121
+ if a[tag] && b[tag]
122
+ a[tag] = b[tag].merge(a[tag])
123
+ end
124
+ end
125
+
126
+ # just merge_stuff like :headers and :query... you know, HTTP stuff
127
+ def deep_merge(a,b)
128
+ merge_stuff(a,b,:headers)
129
+ merge_stuff(a,b,:query)
130
+ b.merge(a)
131
+ end
132
+
133
+ end
134
+
135
+ end
data/someapi.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'someapi/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "someapi"
8
+ spec.version = Some::VERSION
9
+ spec.authors = ["Daniel Smith"]
10
+ spec.email = ["jellymann@gmail.com"]
11
+ spec.summary = %q{A generic RESTful API wrapper.}
12
+ spec.description = %q{Built around HTTParty, SomeAPI provides a generic wrapper for your favourite RESTful WebAPI. Simply extend Some::API and apply your usual HTTParty options like base_uri, then call your new API and party harder!}
13
+ spec.homepage = "https://github.com/jellymann/someapi"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "httparty", "~> 0.13.1"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.6"
24
+ spec.add_development_dependency "rake"
25
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: someapi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Smith
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.13.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.13.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Built around HTTParty, SomeAPI provides a generic wrapper for your favourite
56
+ RESTful WebAPI. Simply extend Some::API and apply your usual HTTParty options like
57
+ base_uri, then call your new API and party harder!
58
+ email:
59
+ - jellymann@gmail.com
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - ".gitignore"
65
+ - Gemfile
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - lib/someapi.rb
70
+ - lib/someapi/version.rb
71
+ - someapi.gemspec
72
+ homepage: https://github.com/jellymann/someapi
73
+ licenses:
74
+ - MIT
75
+ metadata: {}
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubyforge_project:
92
+ rubygems_version: 2.3.0
93
+ signing_key:
94
+ specification_version: 4
95
+ summary: A generic RESTful API wrapper.
96
+ test_files: []