configly-ruby 0.0.5 → 0.0.6

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: 524b5942925d1b420aca59131590986ca941ac9206e543ad00448fd1e303d0c0
4
- data.tar.gz: 679cc9958ff99e8eea95fc13c713074ef880d43aaf684679d8d80f4a7a00043b
3
+ metadata.gz: 5d1525cdf4c14061d87df93eb5d7784ed7ec17a97ca73952c1b05955c22c1d89
4
+ data.tar.gz: e5e66c9d611800617304884ec26a408cd4e900f7ce559e38998e1126650098b2
5
5
  SHA512:
6
- metadata.gz: 97445a7db758cbc30d2f49aaf14736855276d2195cd808e199d6b2f1a395edfc2a4503e9ef6381c6fef2a8d18e94bda89a69b2bfa38a1a8aa06c5192a1746a38
7
- data.tar.gz: 3604454a283d703dc3b0a563e4c497cfaa85208b92c5124183259165bb121c441d2c7e6b468eb22e5ab7bc58c6c5b8e209957148cadc9bf1cc7bb986d36731c7
6
+ metadata.gz: 9ccd504f03c7a4f08242b887d873d7e47588cc3fbcb7258c0dc299828b3f982724520451c0f14cd8725d0df1436a787ab9bf076b7da33c8a32ec1d9bab620931
7
+ data.tar.gz: 90e29d3e9c06d3292f9f1470275567a9bec65d3e6f157b79d223a9d811e53983848db69fb80d8c3d553ef029eeaa337acdcd8e36596592492e7ed3e2d990ccac
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
- # Configly React Library
1
+ # Configly Ruby Library
2
2
  > The Ruby library for [Configly](https://www.config.ly): the modern config/static data key/value store.
3
3
 
4
- ![npm](https://img.shields.io/npm/v/configly-react)
5
- ![GitHub](https://img.shields.io/github/license/configly/react)
4
+ ![npm](https://img.shields.io/gem/v/configly-ruby)
5
+ ![GitHub](https://img.shields.io/github/license/configly/ruby)
6
6
 
7
7
  Table of Contents
8
8
  =================
@@ -38,13 +38,73 @@ read more about the benefits at [Configly](config.ly).
38
38
 
39
39
  - API to fetch Strings, JSON Blobs (arrays and objects), Booleans, and Numbers from the Configly backend
40
40
  - [Web interface](https://www.config.ly/config) for modifying these values without having to deploy code (we call our beloved web interface _the Configulator_).
41
- - High availability, high-throughput, low-latency backend.
42
- - Smart caching on the client libraries to minimize server requests.
41
+ - High availability, high-throughput, low-latency backend.
43
42
  - Client libraries available in an expanding amount of languages.
44
43
 
44
+ ### Concepts/ Data Model
45
+ - A Configly account contains a set of Configs.
46
+ - A Config is a key-value pair along with associated metadata (like TTL).
47
+ - The keys are strings.
48
+ - The values are one of the following types:
49
+
50
+ #### Types
51
+
52
+ | Type | notes | Example(s)|
53
+ |---------|----------|----------|
54
+ | string | | "I <3 Configly!" |
55
+ | number | Can be integers or decimal; _be aware some clients require you to specify which when fetching_ | 31337, 1.618 |
56
+ | boolean | only true or false | true, false |
57
+ | jsonBlob | A [JSON5](https://json5.org/) (more relaxed JSON) array or object. | ``` ["one", 5, true]```, ```{"text": "Buy now!", color: "#0F0"}``` |
58
+
59
+ ##### More `jsonBlob` examples
60
+ You can make arbitrarily complex JSON structures -- _as long_ as the top level is
61
+ an object or array. This is incredibly powerful as you can send a host of data
62
+ with a single _config_:
63
+
64
+
65
+ A more complex array for a store inventory. Note that because we're using JSON5, quotes
66
+ are optional for single words.
67
+ ```js
68
+ [
69
+ "Simple T-shirt",
70
+ "Basic hoodie",
71
+ {
72
+ item: "Complex T-shirt",
73
+ sizes: ['S', 'M', 'L'],
74
+ price_us_cents: [1099, 1499, 1599],
75
+ }
76
+ ]
77
+ ```
78
+
79
+ And a more complex object showing how you can internationalize and set style:
80
+ ```js
81
+ {
82
+ "welcome_message": {
83
+ copy: {
84
+ 'en': 'Welcome!',
85
+ 'es': "¡Bienvenidos!",
86
+ }, style: {
87
+ color: '#0F0',
88
+ fontWeight: '700',
89
+ }
90
+ },
91
+ "buy_button" : {
92
+ copy: {
93
+ 'en': 'Buy',
94
+ 'es': "Comprar",
95
+ }, style: {
96
+ backgroundColor: "#F00",
97
+ border: "border-radius 10px",
98
+ }
99
+ }
100
+ }
101
+ ```
102
+
45
103
  ## Getting Started
46
104
 
47
- ### Get your API Key
105
+ In four easy steps!
106
+
107
+ ### 1. Get your API Key
48
108
 
49
109
  You'll need a [Configly](https://www.config.ly) account. Registration is lightning quick&mdash;you can register via
50
110
  visiting [https://www.config.ly/signup](https://www.config.ly/signup).
@@ -52,27 +112,115 @@ visiting [https://www.config.ly/signup](https://www.config.ly/signup).
52
112
  After signing up, you can grab your API Key from [https://www.config.ly/register](https://www.config.ly/register).
53
113
  You'll need your API Key to setup the API below.
54
114
 
55
- ### Library Installation
115
+ ### 2. Create your first Config
116
+ From [https://www.config.ly/config](https://www.config.ly/config), create a new Config via the "Add" button:
117
+ ![image](https://user-images.githubusercontent.com/184923/98487495-3b42ca80-21f1-11eb-9bfc-bfd429733362.png)
118
+
119
+ Consider creating a simple `JSON Object or Array` Config called `greetings` and give it the value of:
120
+ `['hello', 'hola', '你好', 'नमस्ते']`:
121
+
122
+ [https://www.config.ly/config](https://www.config.ly/config) should look like this:
123
+
124
+ ![image](https://user-images.githubusercontent.com/184923/98494454-09d6f880-220b-11eb-9ef7-36709ddc129f.png)
56
125
 
126
+ Be sure to save via clicking 'Send to Clients'. Now, we'll write client code to fetch this key.
127
+
128
+ ### 3. Install the client library
129
+
130
+ If you're using bundler, add the following line to your project's `Gemfile`:
131
+ ```sh
132
+ gem 'configly-ruby', '~> 0.0.5'
133
+ ```
134
+
135
+ Or, if you're using the Gem directly from your application, you can run:
57
136
  ```sh
58
137
  gem install configly-ruby
59
138
  ```
60
139
 
61
140
  You will need to set the `CONFIGLY_API_KEY` environment variable.
62
141
 
63
- ### Using this library with websockets
142
+ ### 4. Fetch the Config
143
+ In a Rails controller, add the following code
144
+ ```ruby
145
+ def get
146
+ begin
147
+ key = Configly::Client.get(params[:key])
148
+ render plain: key
149
+ rescue Configly::KeyError
150
+ render :status => 404
151
+ end
152
+ end
153
+ ```
154
+
155
+ Map the route, and then request it in your browser with the `key` params (e.g. `http://localhost:3000/configly?key=test1234`).
156
+
157
+ Try changing some values on [https://www.config.ly/config](https://www.config.ly/config) to confirm that
158
+ the client is getting the updates.
159
+
160
+ Congratulations you have Configly working end-to-end! Now, feel free to use Configly with all your projects!
161
+
162
+ ## Configuring this library to use websockets
64
163
  Coming soon...
65
164
 
66
165
  ## Usage
166
+ > The golden rule of Configly library use is: **do NOT** assign the result of a `get()`
167
+ to a long-lived variable; in order to check for new values from the server, you must call `get()`.
168
+
169
+ The package needs to be configured with your account's API key, which is available in the
170
+ [Configly Configulator](https://config.ly/config)
171
+
172
+ ```
173
+ // This value is stored on the Config.ly servers.
174
+ store_catalog:
175
+ {
176
+ has_sale: true,
177
+ discount: 0.8,
178
+ items: ['T Shirt', 'Hoodie', 'Ferrari'],
179
+ price: [ 100, 250, 200000],
180
+ }
181
+ ```
67
182
 
68
- To fetch a key, use the following command:
183
+ On the Ruby client:
69
184
 
70
185
  ```ruby
71
- Configly::Client.get(KEY)
186
+ begin
187
+ catalog = Configly::Client.get(KEY)
188
+ items = catalog['items']
189
+ prices = catalog['prices']
190
+
191
+ items.each_with_index do |item, index|
192
+ Rails.logger.debug("#{item}: #{prices[index]} USD")
193
+ end
194
+ rescue Configly::KeyError
195
+ Rails.logger.error("Something went wrong")
196
+ end
72
197
  ```
73
198
 
74
- If the key doesn't exist (or if you are using the websockets client and it hasn't been prefetched), this will rais a `Configly::KeyError`
199
+ Note: If the key doesn't exist, this will raise a `Configly::KeyError`
200
+
201
+ Here is an example with feature flags.
202
+ // These values are stored on the Config.ly server
203
+ ```
204
+ feature1_enabled: true
205
+ feature2_enabled: false
206
+ ```
207
+
208
+ On the ruby client:
209
+
210
+ ```ruby
211
+ begin
212
+ if Configly::Client.get('feature1_enabled')
213
+ # Logic for feature 1
214
+ end
215
+
216
+ if Configly::Client.get('feature2_enabled')
217
+ # Logic for feature 2
218
+ end
219
+ rescue Configly::KeyError
220
+ Rails.logger.error("Something went wrong")
221
+ end
222
+ ```
75
223
 
76
224
  ## License
77
225
 
78
- This repository is published under the [MIT](LICENSE.md) license.
226
+ This repository is published under the [MIT](LICENSE.md) license.
@@ -3,7 +3,7 @@ require_relative 'lib/configly/version'
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = 'configly-ruby'
6
- s.version = '0.0.5'
6
+ s.version = '0.0.6'
7
7
  s.date = '2020-11-16'
8
8
  s.summary = "Configly"
9
9
  s.description = "Configly SDK gem"
@@ -8,7 +8,7 @@ CONFIGLY_VALUE_URL = '/api/v1/value'
8
8
  module Configly
9
9
  class Client
10
10
  @keys = {}
11
- @caches = {}
11
+ @ttl_expirations = {}
12
12
  @use_ws = false
13
13
  def self.init
14
14
  @use_ws = true
@@ -31,7 +31,7 @@ module Configly
31
31
  end
32
32
 
33
33
  def self.load_initial_data
34
- @keys = fetch(get_keys_to_preload)
34
+ fetch(get_keys_to_preload, false)
35
35
  end
36
36
 
37
37
  def self.start_web_socket_client
@@ -62,19 +62,38 @@ module Configly
62
62
  end
63
63
  end
64
64
 
65
- def self.fetch(keys)
66
- uri = URI("https://#{CONFIGLY_SERVER}#{CONFIGLY_VALUE_URL}?#{generate_qs(keys)}")
67
- loaded_keys = {}
68
- Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
69
- request = Net::HTTP::Get.new uri
70
- request.basic_auth get_api_key, ''
71
- response = http.request request
72
- data = JSON.parse(response.body)['data']
73
- data.keys.each do |key|
74
- loaded_keys[key] = data[key]['value']
65
+ def self.fetch(keys, use_ttls)
66
+ current_time = Time.now.to_i
67
+
68
+ # If we aren't using the TTLs, fetch all keys
69
+ if !use_ttls
70
+ keys_to_fetch = keys
71
+ else
72
+ # Otherwise, fetch the keys that are unfetched or expired
73
+ keys_to_fetch = []
74
+ keys.each do |key|
75
+ if !@ttl_expirations.has_key?(key) || @ttl_expirations[key] < current_time
76
+ keys_to_fetch << key
77
+ end
78
+ end
79
+ end
80
+
81
+ # Only actually execute the request if there are keys to fetch
82
+ if keys_to_fetch.length > 0
83
+ uri = URI("https://#{CONFIGLY_SERVER}#{CONFIGLY_VALUE_URL}?#{generate_qs(keys_to_fetch)}")
84
+
85
+ Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
86
+ request = Net::HTTP::Get.new uri
87
+ request.basic_auth get_api_key, ''
88
+ response = http.request request
89
+ data = JSON.parse(response.body)['data']
90
+ data.keys.each do |key|
91
+ # Set the key and the expiration
92
+ @keys[key] = data[key]['value']
93
+ @ttl_expirations[key] = current_time + data[key]['ttl']
94
+ end
75
95
  end
76
96
  end
77
- return loaded_keys
78
97
  end
79
98
 
80
99
  def self.get(key)
@@ -85,9 +104,9 @@ module Configly
85
104
  raise KeyError.new(key)
86
105
  end
87
106
  else
88
- loaded_keys = fetch([key])
89
- if loaded_keys.has_key? key
90
- return loaded_keys[key]
107
+ fetch([key], true)
108
+ if @keys.has_key? key
109
+ return @keys[key]
91
110
  else
92
111
  raise KeyError.new(key)
93
112
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: configly-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dana Levine