configly-ruby 0.0.2 → 0.0.7
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 +4 -4
- data/README.md +160 -14
- data/configly-ruby.gemspec +2 -2
- data/lib/configly/client.rb +35 -18
- data/lib/configly/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a42b4285e7b42e00601a87e46cfb8680f07762ad577ae26ab840aeecefa57d1a
|
4
|
+
data.tar.gz: 96d5942a380b62128d30fac438dff07bfa47746ea85668926c6ab735eeec770c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4f4fd9e7fb133c3ba13376929c06bd64a09c8e707347ddb325887ebb4d4161de3952af67b47edba1d0239401c1758a2c379980e29a2dec73dab0615a265210e
|
7
|
+
data.tar.gz: e0be4959d0af7c1bd59aa2d1030190cfaa4d798c9d2982f8badc0180f8b924cddee7d0fc892dfcefad0302968bfcce444b213fff253e525dee34383eed41b2e0
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
# Configly
|
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
|
-

|
5
|
+

|
6
6
|
|
7
7
|
Table of Contents
|
8
8
|
=================
|
@@ -38,13 +38,74 @@ 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.
|
41
|
+
- High availability, high-throughput, low-latency backend.
|
42
42
|
- Smart caching on the client libraries to minimize server requests.
|
43
43
|
- Client libraries available in an expanding amount of languages.
|
44
44
|
|
45
|
+
### Concepts/ Data Model
|
46
|
+
- A Configly account contains a set of Configs.
|
47
|
+
- A Config is a key-value pair along with associated metadata (like TTL).
|
48
|
+
- The keys are strings.
|
49
|
+
- The values are one of the following types:
|
50
|
+
|
51
|
+
#### Types
|
52
|
+
|
53
|
+
| Type | notes | Example(s)|
|
54
|
+
|---------|----------|----------|
|
55
|
+
| string | | "I <3 Configly!" |
|
56
|
+
| number | Can be integers or decimal; _be aware some clients require you to specify which when fetching_ | 31337, 1.618 |
|
57
|
+
| boolean | only true or false | true, false |
|
58
|
+
| jsonBlob | A [JSON5](https://json5.org/) (more relaxed JSON) array or object. | ``` ["one", 5, true]```, ```{"text": "Buy now!", color: "#0F0"}``` |
|
59
|
+
|
60
|
+
##### More `jsonBlob` examples
|
61
|
+
You can make arbitrarily complex JSON structures -- _as long_ as the top level is
|
62
|
+
an object or array. This is incredibly powerful as you can send a host of data
|
63
|
+
with a single _config_:
|
64
|
+
|
65
|
+
|
66
|
+
A more complex array for a store inventory. Note that because we're using JSON5, quotes
|
67
|
+
are optional for single words.
|
68
|
+
```js
|
69
|
+
[
|
70
|
+
"Simple T-shirt",
|
71
|
+
"Basic hoodie",
|
72
|
+
{
|
73
|
+
item: "Complex T-shirt",
|
74
|
+
sizes: ['S', 'M', 'L'],
|
75
|
+
price_us_cents: [1099, 1499, 1599],
|
76
|
+
}
|
77
|
+
]
|
78
|
+
```
|
79
|
+
|
80
|
+
And a more complex object showing how you can internationalize and set style:
|
81
|
+
```js
|
82
|
+
{
|
83
|
+
"welcome_message": {
|
84
|
+
copy: {
|
85
|
+
'en': 'Welcome!',
|
86
|
+
'es': "¡Bienvenidos!",
|
87
|
+
}, style: {
|
88
|
+
color: '#0F0',
|
89
|
+
fontWeight: '700',
|
90
|
+
}
|
91
|
+
},
|
92
|
+
"buy_button" : {
|
93
|
+
copy: {
|
94
|
+
'en': 'Buy',
|
95
|
+
'es': "Comprar",
|
96
|
+
}, style: {
|
97
|
+
backgroundColor: "#F00",
|
98
|
+
border: "border-radius 10px",
|
99
|
+
}
|
100
|
+
}
|
101
|
+
}
|
102
|
+
```
|
103
|
+
|
45
104
|
## Getting Started
|
46
105
|
|
47
|
-
|
106
|
+
In four easy steps!
|
107
|
+
|
108
|
+
### 1. Get your API Key
|
48
109
|
|
49
110
|
You'll need a [Configly](https://www.config.ly) account. Registration is lightning quick—you can register via
|
50
111
|
visiting [https://www.config.ly/signup](https://www.config.ly/signup).
|
@@ -52,30 +113,115 @@ visiting [https://www.config.ly/signup](https://www.config.ly/signup).
|
|
52
113
|
After signing up, you can grab your API Key from [https://www.config.ly/register](https://www.config.ly/register).
|
53
114
|
You'll need your API Key to setup the API below.
|
54
115
|
|
55
|
-
###
|
116
|
+
### 2. Create your first Config
|
117
|
+
From [https://www.config.ly/config](https://www.config.ly/config), create a new Config via the "Add" button:
|
118
|
+

|
119
|
+
|
120
|
+
Consider creating a simple `JSON Object or Array` Config called `greetings` and give it the value of:
|
121
|
+
`['hello', 'hola', '你好', 'नमस्ते']`:
|
122
|
+
|
123
|
+
[https://www.config.ly/config](https://www.config.ly/config) should look like this:
|
124
|
+
|
125
|
+

|
56
126
|
|
127
|
+
Be sure to save via clicking 'Send to Clients'. Now, we'll write client code to fetch this key.
|
128
|
+
|
129
|
+
### 3. Install the client library
|
130
|
+
|
131
|
+
If you're using bundler, add the following line to your project's `Gemfile`:
|
132
|
+
```sh
|
133
|
+
gem 'configly-ruby', '~> 0.0.5'
|
134
|
+
```
|
135
|
+
|
136
|
+
Or, if you're using the Gem directly from your application, you can run:
|
57
137
|
```sh
|
58
138
|
gem install configly-ruby
|
59
139
|
```
|
60
140
|
|
61
141
|
You will need to set the `CONFIGLY_API_KEY` environment variable.
|
62
142
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
143
|
+
### 4. Fetch the Config
|
144
|
+
In a Rails controller, add the following code
|
145
|
+
```ruby
|
146
|
+
def get
|
147
|
+
begin
|
148
|
+
key = Configly::Client.get(params[:key])
|
149
|
+
render plain: key
|
150
|
+
rescue Configly::KeyError
|
151
|
+
render :status => 404
|
152
|
+
end
|
153
|
+
end
|
67
154
|
```
|
68
155
|
|
156
|
+
Map the route, and then request it in your browser with the `key` params (e.g. `http://localhost:3000/configly?key=test1234`).
|
157
|
+
|
158
|
+
Try changing some values on [https://www.config.ly/config](https://www.config.ly/config) to confirm that
|
159
|
+
the client is getting the updates.
|
160
|
+
|
161
|
+
Congratulations you have Configly working end-to-end! Now, feel free to use Configly with all your projects!
|
162
|
+
|
163
|
+
## Configuring this library to use websockets
|
164
|
+
Coming soon...
|
165
|
+
|
69
166
|
## Usage
|
167
|
+
> The golden rule of Configly library use is: **do NOT** assign the result of a `get()`
|
168
|
+
to a long-lived variable; in order to check for new values from the server, you must call `get()`.
|
169
|
+
|
170
|
+
The package needs to be configured with your account's API key, which is available in the
|
171
|
+
[Configly Configulator](https://config.ly/config)
|
172
|
+
|
173
|
+
```
|
174
|
+
// This value is stored on the Config.ly servers.
|
175
|
+
store_catalog:
|
176
|
+
{
|
177
|
+
has_sale: true,
|
178
|
+
discount: 0.8,
|
179
|
+
items: ['T Shirt', 'Hoodie', 'Ferrari'],
|
180
|
+
price: [ 100, 250, 200000],
|
181
|
+
}
|
182
|
+
```
|
70
183
|
|
71
|
-
|
184
|
+
On the Ruby client:
|
72
185
|
|
73
186
|
```ruby
|
74
|
-
|
187
|
+
begin
|
188
|
+
catalog = Configly::Client.get(KEY)
|
189
|
+
items = catalog['items']
|
190
|
+
prices = catalog['prices']
|
191
|
+
|
192
|
+
items.each_with_index do |item, index|
|
193
|
+
Rails.logger.debug("#{item}: #{prices[index]} USD")
|
194
|
+
end
|
195
|
+
rescue Configly::KeyError
|
196
|
+
Rails.logger.error("Something went wrong")
|
197
|
+
end
|
75
198
|
```
|
76
199
|
|
77
|
-
If the key doesn't exist
|
200
|
+
Note: If the key doesn't exist, this will raise a `Configly::KeyError`
|
201
|
+
|
202
|
+
Here is an example with feature flags.
|
203
|
+
// These values are stored on the Config.ly server
|
204
|
+
```
|
205
|
+
feature1_enabled: true
|
206
|
+
feature2_enabled: false
|
207
|
+
```
|
208
|
+
|
209
|
+
On the ruby client:
|
210
|
+
|
211
|
+
```ruby
|
212
|
+
begin
|
213
|
+
if Configly::Client.get('feature1_enabled')
|
214
|
+
# Logic for feature 1
|
215
|
+
end
|
216
|
+
|
217
|
+
if Configly::Client.get('feature2_enabled')
|
218
|
+
# Logic for feature 2
|
219
|
+
end
|
220
|
+
rescue Configly::KeyError
|
221
|
+
Rails.logger.error("Something went wrong")
|
222
|
+
end
|
223
|
+
```
|
78
224
|
|
79
225
|
## License
|
80
226
|
|
81
|
-
This repository is published under the [MIT](LICENSE.md) license.
|
227
|
+
This repository is published under the [MIT](LICENSE.md) license.
|
data/configly-ruby.gemspec
CHANGED
@@ -3,8 +3,8 @@ 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.
|
7
|
-
s.date = '2020-11-
|
6
|
+
s.version = '0.0.7'
|
7
|
+
s.date = '2020-11-16'
|
8
8
|
s.summary = "Configly"
|
9
9
|
s.description = "Configly SDK gem"
|
10
10
|
s.authors = ["Dana Levine"]
|
data/lib/configly/client.rb
CHANGED
@@ -8,7 +8,7 @@ CONFIGLY_VALUE_URL = '/api/v1/value'
|
|
8
8
|
module Configly
|
9
9
|
class Client
|
10
10
|
@keys = {}
|
11
|
-
@
|
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
|
-
|
34
|
+
fetch(get_keys_to_preload, false)
|
35
35
|
end
|
36
36
|
|
37
37
|
def self.start_web_socket_client
|
@@ -62,21 +62,38 @@ module Configly
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
def self.fetch(keys)
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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
|
77
95
|
end
|
78
96
|
end
|
79
|
-
return loaded_keys
|
80
97
|
end
|
81
98
|
|
82
99
|
def self.get(key)
|
@@ -87,9 +104,9 @@ module Configly
|
|
87
104
|
raise KeyError.new(key)
|
88
105
|
end
|
89
106
|
else
|
90
|
-
|
91
|
-
if
|
92
|
-
return[key]
|
107
|
+
fetch([key], true)
|
108
|
+
if @keys.has_key? key
|
109
|
+
return @keys[key]
|
93
110
|
else
|
94
111
|
raise KeyError.new(key)
|
95
112
|
end
|
data/lib/configly/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: configly-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dana Levine
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-11-
|
11
|
+
date: 2020-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faye-websocket
|