derek_hall-sdk 0.3.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 +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/Gemfile +15 -0
- data/README.md +59 -0
- data/Rakefile +8 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/design.md +21 -0
- data/lib/lotr/sdk/client.rb +56 -0
- data/lib/lotr/sdk/dataset.rb +31 -0
- data/lib/lotr/sdk/version.rb +7 -0
- data/lib/lotr/sdk.rb +13 -0
- data/lotr-sdk.gemspec +36 -0
- metadata +73 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: cf8a7f24372150b936ddc3d3d5cbe9bf4ea0fe28f7f8ec837ad8ef0ca310d92f
|
4
|
+
data.tar.gz: ee0ae3a9306cd76a1d8767e4ab1d64479bae94c10ac91c1f81ee0830d80f5a62
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 063ad2aeeb3112aeec5b3ee1718c1d275c9289fa833e4be48d95634058675d29a8116bbd14a48900ff6d90078fef297a19fea446eadd723aaa0529b6061e6e43
|
7
|
+
data.tar.gz: b7defaf60e45157e1fc9d0e889de44d1492b8f6564ec2f2bc914a97edc29567e4940501931ca60068ccffaa3e0229f3aba9bea00be94208e8a9ef4db35b43caf
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
# Specify your gem's dependencies in lotr-sdk.gemspec
|
6
|
+
gemspec
|
7
|
+
|
8
|
+
gem "rake", "~> 13.0"
|
9
|
+
gem "rspec", "~> 3.0"
|
10
|
+
gem 'http'
|
11
|
+
|
12
|
+
group :test do
|
13
|
+
gem 'webmock'
|
14
|
+
gem 'vcr'
|
15
|
+
end
|
data/README.md
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
|
2
|
+
# LOTR SDK
|
3
|
+
|
4
|
+
Ruby client for the LOTR api located at https://the-one-api.dev/
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
gem install derek_hall-SDK
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
In your ruby file
|
11
|
+
|
12
|
+
gem 'derek_hall-SDK'
|
13
|
+
require 'lotr/sdk'
|
14
|
+
|
15
|
+
client = Lotr::Sdk::Client.new(ENV['KEY'])
|
16
|
+
|
17
|
+
# grab a random quote
|
18
|
+
random_quote = client.quote_list.data.sample
|
19
|
+
puts "Who said #{random_quote['dialog']}?"
|
20
|
+
|
21
|
+
# get the name and race of the character who was quoted
|
22
|
+
character = client.character(id: random_quote['character']).data.first
|
23
|
+
puts "Answer: #{character['name']} - #{character['race']}"
|
24
|
+
|
25
|
+
# gather all pages of quote data
|
26
|
+
|
27
|
+
full_quote_data = []
|
28
|
+
next_page_number = 1
|
29
|
+
while next_page_number
|
30
|
+
quote_list = client.quote_list(page:next_page_number)
|
31
|
+
full_quote_data += quote_list.data
|
32
|
+
next_page_number = quote_list.next_page_number
|
33
|
+
end
|
34
|
+
|
35
|
+
puts "Total number of quotes: #{full_quote_data.size}"
|
36
|
+
|
37
|
+
## Supported commands
|
38
|
+
|
39
|
+
* movie_list
|
40
|
+
* movie
|
41
|
+
* character_list
|
42
|
+
* character
|
43
|
+
* book_list
|
44
|
+
* book
|
45
|
+
* quote_list
|
46
|
+
* quote
|
47
|
+
|
48
|
+
## Local development
|
49
|
+
git clone https://github.com/dhall/derek_hall-SDK.git
|
50
|
+
cd derek_hall-SDK
|
51
|
+
bundle
|
52
|
+
|
53
|
+
Run tests
|
54
|
+
|
55
|
+
rake test
|
56
|
+
|
57
|
+
Build gem
|
58
|
+
|
59
|
+
rake build
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "lotr/sdk"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/design.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# LOTR SDK Design Approach
|
2
|
+
|
3
|
+
## Constraints
|
4
|
+
I needed to time-box this initial version to under 5 hours of effort. Design constraints are a good thing to practice, as in real world problems there are always constraints to consider (time, resources, other requirements, etc).
|
5
|
+
|
6
|
+
## Priorities
|
7
|
+
Since I knew I would be limited on time, I wanted to get the 'plumbing' in place and prioritize what I worked on. I think it's important to have a testing approach that doesn't rely on the availability of any third party APIs. A few reasons for that are
|
8
|
+
* Availability: the status of an API or connectivity to a network should not stop your tests from completing
|
9
|
+
* Good stewardship: my development tests will may run very frequently and it's not nice to flood an API with a lot of wasted requests from your test suite
|
10
|
+
* Resource management: this API is rate limited, so our tests could cause our real usage to get timed out, but especially in cases where you are paying for a specified amount of requests
|
11
|
+
|
12
|
+
After the general dev and build overhead was in place, I started building out the usage of SDK. I didn't want a user to need to know a lot about the API or about REST APIs in general. I designed a client that gets instantiated with the secret key. The requests take a natural language approach such as `movie_list` to get a list of movies.
|
13
|
+
|
14
|
+
I wanted the data returned to be more than raw json data, so it knows something about itself. I called this a `dataset` and the user can easily determine if they have data or an error by methods of those names. When data is present, the dataset also has `meta` information that can be used to gather additional pages of data. As long as `next_page_number` is a truthy value, there is more data available.
|
15
|
+
|
16
|
+
## Future Direction
|
17
|
+
Even with this simple API, building a robust SDK takes a lot of work. I've only started that process with this first version. Some clear next steps would be
|
18
|
+
|
19
|
+
* Sorting, ordering, filtering: the API has robust support for these operations so it would be a nice addition to allow doing this on the API side. This would keep from needing to pull all data into the client just to search for a particular entry, for example.
|
20
|
+
* Test coverage: The framework and approach is in place, so adding more comprehensive tests would be a good use of time.
|
21
|
+
* Full datasets: Adding a method that loops through the operations and gets all data would be useful. It's straightforward to do this on the client side but it would be a nice convenience.
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'http'
|
2
|
+
module Lotr
|
3
|
+
module Sdk
|
4
|
+
class Client
|
5
|
+
|
6
|
+
def initialize(key)
|
7
|
+
@key = key
|
8
|
+
@base_url = 'https://the-one-api.dev/v2'
|
9
|
+
end
|
10
|
+
|
11
|
+
def query_api(endpoint,page=nil)
|
12
|
+
page_param = "page=#{page}" if page
|
13
|
+
HTTP.auth("Bearer #{@key}").get("#{@base_url}/#{endpoint}?#{page_param}")
|
14
|
+
end
|
15
|
+
|
16
|
+
# Movies
|
17
|
+
def movie_list(page:1)
|
18
|
+
Dataset.new( query_api('movie',page) )
|
19
|
+
end
|
20
|
+
|
21
|
+
def movie(id:)
|
22
|
+
Dataset.new( query_api("movie/#{id}") )
|
23
|
+
end
|
24
|
+
|
25
|
+
# Books
|
26
|
+
def book_list(page:1)
|
27
|
+
Dataset.new( query_api('book',page) )
|
28
|
+
end
|
29
|
+
|
30
|
+
def book(id:)
|
31
|
+
Dataset.new( query_api("book/#{id}") )
|
32
|
+
end
|
33
|
+
|
34
|
+
# Quotes
|
35
|
+
def quote_list(page:1)
|
36
|
+
Dataset.new( query_api('quote',page) )
|
37
|
+
end
|
38
|
+
|
39
|
+
def quote(id:)
|
40
|
+
Dataset.new( query_api("quote/#{id}") )
|
41
|
+
end
|
42
|
+
|
43
|
+
# Characters
|
44
|
+
def character_list(page:1)
|
45
|
+
Dataset.new( query_api('character',page) )
|
46
|
+
end
|
47
|
+
|
48
|
+
def character(id:)
|
49
|
+
Dataset.new( query_api("character/#{id}") )
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
module Lotr
|
3
|
+
module Sdk
|
4
|
+
class Dataset
|
5
|
+
attr_accessor :data, :meta, :error
|
6
|
+
def initialize(response)
|
7
|
+
if response.code < 300
|
8
|
+
list = response.parse
|
9
|
+
@data = list['docs']
|
10
|
+
@meta = {
|
11
|
+
total_count: list['total'],
|
12
|
+
current_page: list['page'],
|
13
|
+
total_pages: list['pages']
|
14
|
+
}
|
15
|
+
else
|
16
|
+
@error = {
|
17
|
+
error_code: response.code,
|
18
|
+
error_message: response.to_s
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def next_page_number
|
24
|
+
return nil if @error
|
25
|
+
@meta[:current_page] < @meta[:total_pages] ? @meta[:current_page] + 1 : nil
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
data/lib/lotr/sdk.rb
ADDED
data/lotr-sdk.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/lotr/sdk/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "derek_hall-sdk"
|
7
|
+
spec.version = Lotr::Sdk::VERSION
|
8
|
+
spec.authors = ["Derek Hall"]
|
9
|
+
spec.email = ["derekhall77@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = "SDK for LOTR api"
|
12
|
+
spec.description = "SDK for LOTR api"
|
13
|
+
spec.homepage = "https://rubygems.org/gems/derek_hall-sdk"
|
14
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
15
|
+
|
16
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
17
|
+
|
18
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
19
|
+
spec.metadata["source_code_uri"] = "https://github.com/dhall"
|
20
|
+
spec.metadata["changelog_uri"] = "https://github.com/dhall"
|
21
|
+
|
22
|
+
# Specify which files should be added to the gem when it is released.
|
23
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
24
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
25
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
26
|
+
end
|
27
|
+
spec.bindir = "exe"
|
28
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
29
|
+
spec.require_paths = ["lib"]
|
30
|
+
|
31
|
+
# Uncomment to register a new dependency of your gem
|
32
|
+
spec.add_dependency "http", "~> 5.0"
|
33
|
+
|
34
|
+
# For more information and examples about making a new gem, checkout our
|
35
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: derek_hall-sdk
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Derek Hall
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-08-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: http
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5.0'
|
27
|
+
description: SDK for LOTR api
|
28
|
+
email:
|
29
|
+
- derekhall77@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- ".gitignore"
|
35
|
+
- ".rspec"
|
36
|
+
- Gemfile
|
37
|
+
- README.md
|
38
|
+
- Rakefile
|
39
|
+
- bin/console
|
40
|
+
- bin/setup
|
41
|
+
- design.md
|
42
|
+
- lib/lotr/sdk.rb
|
43
|
+
- lib/lotr/sdk/client.rb
|
44
|
+
- lib/lotr/sdk/dataset.rb
|
45
|
+
- lib/lotr/sdk/version.rb
|
46
|
+
- lotr-sdk.gemspec
|
47
|
+
homepage: https://rubygems.org/gems/derek_hall-sdk
|
48
|
+
licenses: []
|
49
|
+
metadata:
|
50
|
+
allowed_push_host: https://rubygems.org
|
51
|
+
homepage_uri: https://rubygems.org/gems/derek_hall-sdk
|
52
|
+
source_code_uri: https://github.com/dhall
|
53
|
+
changelog_uri: https://github.com/dhall
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options: []
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 2.3.0
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
requirements: []
|
69
|
+
rubygems_version: 3.2.3
|
70
|
+
signing_key:
|
71
|
+
specification_version: 4
|
72
|
+
summary: SDK for LOTR api
|
73
|
+
test_files: []
|