api_frame 0.1.0

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
+ SHA256:
3
+ metadata.gz: a8b59e5031b5fee64016e8be08239134686ba0532ea71cdbf8adbd263037b337
4
+ data.tar.gz: 210dbc213dfa4e0db91a7dd29c1364233a46a4ab00fd854a75c205d7b83003bb
5
+ SHA512:
6
+ metadata.gz: c599a3bc24d8042a985414f555c072887f58904ed4e67cfa3576c2897a9a2bd9fa602642c8de555afdcb8b65964e660420b88dde25699baa110e8a4d4ad5ec77
7
+ data.tar.gz: 380fdb32def48ba199a51cfd5af5ac85eca39cb05d77f75d65714654a7871d18473f4c6e2f2f384e37c11902301e04450225c0c1d07f20ce3a0659d629121b85
data/README.adoc ADDED
@@ -0,0 +1,13 @@
1
+ == ApiFrame
2
+
3
+ ApiFrame is a gem that aims to provide an easy-to-use way of implementing high-level and low-level interactions with APIs working over HTTP.
4
+
5
+ === Installation
6
+
7
+ Add the gem `api_frame` as a runtime dependency to your library’s `gemspec`.
8
+
9
+ === Development
10
+
11
+ After checking out the repository, run `bin/setup` to install dependencies.
12
+ For an interactive Pry session, run `bin/console`.
13
+ Run `rake spec` to run the tests.
@@ -0,0 +1,73 @@
1
+ require 'cgi'
2
+ require 'json'
3
+ require 'net/https'
4
+
5
+ require_relative 'no_success_error'
6
+ require_relative 'utils'
7
+
8
+ module ApiFrame
9
+ module EndpointMethods
10
+ def base_uri
11
+ raise NotImplementedError
12
+ end
13
+
14
+ def default_headers
15
+ {}
16
+ end
17
+
18
+ def default_content_type
19
+ 'application/json'
20
+ end
21
+
22
+ def default_response_parser
23
+ proc do |response|
24
+ JSON.parse(response.body)
25
+ end
26
+ end
27
+
28
+ def perform_request(method, api_path, query: nil, body: nil, headers: nil)
29
+ uri = self.base_uri + api_path
30
+ uri.query = URI.encode_www_form(query) if query
31
+
32
+ Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
33
+ ApiFrame::Utils.request_type_from_method_argument(method).new(uri).tap do |request|
34
+ default_headers.merge(headers || {}).each do |name, value|
35
+ request[name] = value
36
+ end
37
+
38
+ if body
39
+ request['Content-Type'] = default_content_type
40
+ request.body = body
41
+ end
42
+ end.then do |request|
43
+ http.request(request)
44
+ end
45
+ end
46
+ end
47
+
48
+ def self.included(klass)
49
+ klass.extend(ClassMethods)
50
+ end
51
+
52
+ module ClassMethods
53
+ def define_endpoint(name, method:, endpoint:, body: nil)
54
+ define_method(name) do |*args, **kwargs|
55
+ uri = endpoint.respond_to?(:call) ? ApiFrame::Utils.call_proc_without_unknown_keywords(endpoint, *args, **kwargs) : endpoint
56
+ request_body = body .respond_to?(:call) ? ApiFrame::Utils.call_proc_without_unknown_keywords(body, *args, **kwargs) : body
57
+
58
+ perform_request(method, uri, body: request_body, query: kwargs.key?(:query) ? kwargs.fetch(:query) : nil, headers: kwargs.key?(:headers) ? kwargs.fetch(:headers) : nil).then do |response|
59
+ if !kwargs.key?(:plain_response) || !kwargs.fetch(:plain_response)
60
+ if response.is_a?(Net::HTTPSuccess)
61
+ default_response_parser.call(response)
62
+ else
63
+ raise ApiFrame::NoSuccessError, response
64
+ end
65
+ else
66
+ response
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,11 @@
1
+ module ApiFrame
2
+ class NoSuccessError < StandardError
3
+ attr_reader :response
4
+
5
+ def initialize(response)
6
+ super
7
+
8
+ @response = response
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,39 @@
1
+ module ApiFrame
2
+ module Utils
3
+ def self.url_escape(string)
4
+ if !string.nil?
5
+ CGI.escape(string.to_s)
6
+ else
7
+ raise TypeError, 'cannot escape nil'
8
+ end
9
+ end
10
+
11
+ def self.call_proc_without_unknown_keywords(proc, *args, **kwargs, &block)
12
+ params = proc.parameters.group_by(&:first).transform_values! do |m|
13
+ m.map do |s|
14
+ s[1]
15
+ end
16
+ end
17
+
18
+ proc_keys =
19
+ if params.key?(:keyrest)
20
+ kwargs
21
+ else
22
+ kwargs.slice(*params.values_at(:key, :keyreq).compact.flatten)
23
+ end
24
+
25
+ proc.call(*args, **proc_keys, &block)
26
+ end
27
+
28
+ def self.request_type_from_method_argument(method)
29
+ if method.instance_of?(Class) && method.ancestors.include?(Net::HTTPRequest)
30
+ method
31
+ else
32
+ {
33
+ get: Net::HTTP::Get,
34
+ post: Net::HTTP::Post,
35
+ }.fetch(method)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ module ApiFrame
2
+ VERSION = '0.1.0'.freeze
3
+ end
data/lib/api_frame.rb ADDED
@@ -0,0 +1,6 @@
1
+ require_relative 'api_frame/endpoint_methods'
2
+ require_relative 'api_frame/version'
3
+
4
+ module ApiFrame
5
+
6
+ end
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: api_frame
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - expeehaa
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-01-24 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ - expeehaa@outlook.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - README.adoc
21
+ - lib/api_frame.rb
22
+ - lib/api_frame/endpoint_methods.rb
23
+ - lib/api_frame/no_success_error.rb
24
+ - lib/api_frame/utils.rb
25
+ - lib/api_frame/version.rb
26
+ homepage: https://github.com/expeehaa/api_frame
27
+ licenses: []
28
+ metadata:
29
+ allowed_push_host: https://rubygems.org
30
+ rubygems_mfa_required: 'true'
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 2.6.0
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubygems_version: 3.4.1
47
+ signing_key:
48
+ specification_version: 4
49
+ summary: Small framework to define API clients in Ruby
50
+ test_files: []