1 | ![confidence Logo](https://raw.github.com/spumko/con/master/images/confidence.png)
|
2 |
|
3 | **Confidence** is a configuration document format, an API, and a foundation for A/B testing. The configuration format is designed to
|
4 | work with any existing JSON-based configuration, serving values based on object path (`'/a/b/c'` translates to ``a.b.c``). In addition,
|
5 | **confidence** defines special $-prefixed keys used to filter values for a given criteria.
|
6 |
|
7 | [![Build Status](https://secure.travis-ci.org/hapijs/confidence.png)](http://travis-ci.org/hapijs/confidence)
|
8 |
|
9 | Lead Maintainer: [Patrick Kettner](https://github.com/patrickkettner)
|
10 |
|
11 | - [Example](#example)
|
12 | - [Document Format](#document-format)
|
13 | - [Basic Structure](#basic-structure)
|
14 | - [Filters](#filters)
|
15 | - [Ranges](#ranges)
|
16 | - [Metadata](#metadata)
|
17 | - [API](#api)
|
18 |
|
19 | # Example
|
20 |
|
21 | ```json
|
22 | {
|
23 | "key1": "abc",
|
24 | "key2": {
|
25 | "$filter": "env",
|
26 | "production": {
|
27 | "deeper": {
|
28 | "$value": "value"
|
29 | }
|
30 | },
|
31 | "$default": {
|
32 | "$filter": "platform",
|
33 | "android": 0,
|
34 | "ios": 1,
|
35 | "$default": 2
|
36 | }
|
37 | },
|
38 | "key3": {
|
39 | "sub1": 123,
|
40 | "sub2": {
|
41 | "$filter": "xfactor",
|
42 | "yes": 6
|
43 | }
|
44 | },
|
45 | "ab": {
|
46 | "$filter": "random.a",
|
47 | "$range": [
|
48 | { "limit": 10, "value": 4 },
|
49 | { "limit": 20, "value": 5 }
|
50 | ],
|
51 | "$default": 6
|
52 | },
|
53 | "$meta": {
|
54 | "description": "example file"
|
55 | }
|
56 | }
|
57 | ```
|
58 |
|
59 | Without any criteria applied, the above configuration document will result in the following:
|
60 |
|
61 | ```json
|
62 | {
|
63 | "key1": "abc",
|
64 | "key2": 2,
|
65 | "key3": {
|
66 | "sub1": 123
|
67 | },
|
68 | "ab": 6
|
69 | }
|
70 | ```
|
71 |
|
72 | With the following criteria applied:
|
73 |
|
74 | ```json
|
75 | {
|
76 | "env": "production",
|
77 | "platform": "ios",
|
78 | "xfactor": "yes",
|
79 | "random": {
|
80 | "a": 15
|
81 | }
|
82 | }
|
83 | ```
|
84 |
|
85 | The result is:
|
86 |
|
87 | ```json
|
88 | {
|
89 | "key1": "abc",
|
90 | "key2": {
|
91 | "deeper": "value"
|
92 | },
|
93 | "key3": {
|
94 | "sub1": 123,
|
95 | "sub2": 6
|
96 | },
|
97 | "ab": 5
|
98 | }
|
99 | ```
|
100 |
|
101 | # Document Format
|
102 |
|
103 | **Confidence** builds on top of a Javascript object as its document.
|
104 |
|
105 | ### Basic structure
|
106 |
|
107 | The configuration document starts with a simple object. key names can only contain alphanumeric characters and '_' with the '$' prefix reserved
|
108 | for special directives. Values can contain any non-object value (e.g. strings, numbers, booleans) as well as arrays.
|
109 |
|
110 | ```json
|
111 | {
|
112 | "key1": "abc",
|
113 | "key2": 2
|
114 | }
|
115 | ```
|
116 |
|
117 | Keys can have children:
|
118 |
|
119 | ```json
|
120 | {
|
121 | "key1": "abc",
|
122 | "key2": 2,
|
123 | "key3": {
|
124 | "sub1": 123
|
125 | }
|
126 | }
|
127 | ```
|
128 |
|
129 | ### Filters
|
130 |
|
131 | A key can have multiple values based on a filter. The filter is a key provided in a criteria object as the time of retrieval. Filter names can only
|
132 | contain alphanumeric characters and '_'.
|
133 |
|
134 | ```json
|
135 | {
|
136 | "key1": "abc",
|
137 | "key2": {
|
138 | "$filter": "env",
|
139 | "production": 1
|
140 | }
|
141 | }
|
142 | ```
|
143 |
|
144 | When asking for `'/key2'`, if no criteria set is provided or the criteria set does not include a value for the `'env'` filter, no value is available. Only when a criteria
|
145 | set with a key `'env'` and value `'production'` is provided, the value returned is `1`.
|
146 |
|
147 | Filters can point to a nested value using '.' seperated tokens for accessing child values within the criteria object.
|
148 |
|
149 | ```json
|
150 | {
|
151 | "key1": "abc",
|
152 | "key2": {
|
153 | "$filter": "system.env",
|
154 | "production": 1
|
155 | }
|
156 | }
|
157 | ```
|
158 |
|
159 | Filters can have a default value which will be used if the provided criteria set does not include a value for the filter or if the value does not match.
|
160 |
|
161 | ```json
|
162 | {
|
163 | "key1": "abc",
|
164 | "key2": {
|
165 | "$filter": "system.env",
|
166 | "production": 1,
|
167 | "$default": 2
|
168 | }
|
169 | }
|
170 | ```
|
171 |
|
172 | ### Ranges
|
173 |
|
174 | Ranges provide a way to filter a value based on numerical buckets. The criteria value must be an integer and be matched against the lowest bucket limit it can fit.
|
175 |
|
176 | ```json
|
177 | {
|
178 | "key1": "abc",
|
179 | "key2": {
|
180 | "$filter": "system.env",
|
181 | "production": 1,
|
182 | "$default": 2
|
183 | },
|
184 | "key3": {
|
185 | "$filter": "random.a",
|
186 | "$range": [
|
187 | { "limit": 10, "value": 4 },
|
188 | { "limit": 20, "value": 5 }
|
189 | ],
|
190 | "$default": 6
|
191 | }
|
192 | }
|
193 | ```
|
194 |
|
195 | If the criteria includes a value for `random.a`, that value is matched against the sorted range entries. The criterion value will match the entry with lowest limit it
|
196 | is still less than or equal the limit of. For example, a criterion value of `5` will return a key value for `'/key3'` of `4`. A criterion value of `15` will return a
|
197 | key value for `'/key3'` of `5`, and a criterion value of `50` will return a key value for `'/key3'` of `6`.
|
198 |
|
199 | ### Metadata
|
200 |
|
201 | The configuration file can be annotated with metadata that is ignored (and removed) by the parser. Metadata is useful for human readable information as well as to
|
202 | enable other tools such as configuration editors and validators, going beyong the basic parsing specified here.
|
203 |
|
204 | ```json
|
205 | {
|
206 | "key1": "abc",
|
207 | "key2": {
|
208 | "$filter": "system.env",
|
209 | "production": 1,
|
210 | "$default": 2
|
211 | },
|
212 | "key3": {
|
213 | "$filter": "random.a",
|
214 | "$range": [
|
215 | { "limit": 10, "value": 4 },
|
216 | { "limit": 20, "value": 5 }
|
217 | ],
|
218 | "$default": 6
|
219 | },
|
220 | "$meta": {
|
221 | "anything": "really"
|
222 | }
|
223 | }
|
224 | ```
|
225 |
|
226 | To annotate non object values, any value can be wrapped in an object and provided using the `$value` directive.
|
227 |
|
228 | ```json
|
229 | {
|
230 | "key1": {
|
231 | "$value": "abc",
|
232 | "$meta": "whatever"
|
233 | },
|
234 | "key2": {
|
235 | "$filter": "system.env",
|
236 | "production": 1,
|
237 | "$default": 2
|
238 | },
|
239 | "key3": {
|
240 | "$filter": "random.a",
|
241 | "$range": [
|
242 | { "limit": 10, "value": 4 },
|
243 | { "limit": 20, "value": 5 }
|
244 | ],
|
245 | "$default": 6
|
246 | },
|
247 | "$meta": {
|
248 | "anything": "really"
|
249 | }
|
250 | }
|
251 | ```
|
252 |
|
253 | # API
|
254 |
|
255 | ## Confidence.Store
|
256 |
|
257 | The configuration parser used to load the configuration document and apply criteria to get values based on keys.
|
258 |
|
259 | ### new Store([document])
|
260 |
|
261 | Creates an empty configuration storage container where:
|
262 |
|
263 | - `document` - an optional object containing a **confidence** configuration object generated from a parsed JSON document.
|
264 | If the document is invalid, will throw an error. Defaults to `{}`.
|
265 |
|
266 | ```javascript
|
267 | var Confidence = require('confidence');
|
268 |
|
269 | var store = new Confidence.Store();
|
270 | ```
|
271 |
|
272 | ### store.load(document)
|
273 |
|
274 | Validates the provided configuration, clears any existing configuration, then loads the configuration where:
|
275 |
|
276 | - `document` - an object containing a **confidence** configuration object generated from a parsed JSON document.
|
277 | If the document is invlaid, will throw an error.
|
278 |
|
279 | ```javascript
|
280 | var document = {
|
281 | a: 1,
|
282 | b: 2,
|
283 | c: {
|
284 | $filter: 'size',
|
285 | big: 100,
|
286 | small: 1,
|
287 | $default: 50
|
288 | }
|
289 | };
|
290 |
|
291 | store.load(document);
|
292 | ```
|
293 |
|
294 | ### store.get(key, [criteria])
|
295 |
|
296 | Retrieves a value from the configuration document after applying the provided criteria where:
|
297 |
|
298 | - `key` - the requested key path. All keys must begin with '/'. '/' returns the the entire document.
|
299 | - `criteria` - optional object used as criteria for applying filters in the configuration document. Defaults to `{}`.
|
300 |
|
301 | Returns the value found after applying the criteria. If the key is invalid or not found, returns undefined.
|
302 |
|
303 | ```javascript
|
304 | var value = store.get('/c', { size: 'big' });
|
305 | ```
|
306 |
|
307 | ### store.meta(key, [criteria])
|
308 |
|
309 | Retrieves the metadata (if any) from the configuration document after applying the provided criteria where:
|
310 |
|
311 | - `key` - the requested key path. All keys must begin with '/'. '/' returns the the entire document.
|
312 | - `criteria` - optional object used as criteria for applying filters in the configuration document. Defaults to `{}`.
|
313 |
|
314 | Returns the metadata found after applying the criteria. If the key is invalid or not found, or if no metadata is available, returns undefined.
|
315 |
|
316 | ```javascript
|
317 | var value = store.meta('/c', { size: 'big' });
|
318 | ```
|