Skip to main content

Contexts

Izanami allows to define finely when a feature should or should not be active, but sometimes this is not enough.

For instance, you may want to have different activation conditions for dev and prod environment.

There is two way to make it work, however they both have their drawback:

  • You could use a user list activation condition and pass your environment as a user. This is a bit hacky, but would work as long as you don't need to add another activation condition to this feature.
  • You could use a script activation condition, and pass your environment as payload for your feature activation request. This works, however it's better to avoid using script feature when possible, since this kind of activation strategy is impossible to cache client side.

Since this kind of use case is very common, Izanami provides contexts.

Contexts are a way for callers to indicate their execution context. They are organized as a tree: one context can define subcontexts, which can themselves have subcontexts and so on.

Contexts are ideal to let the caller indicate information such as browser, env, device, ...

You can redefine activation conditions for your feature in a given context.

Caller can specify a context or subcontext when checking for feature activation status.

When called with a context, Izanami will search for context-specific activation conditions and use them if they exist. If they don't, Izanami will go up this context tree and use the first encountered activation condition, or the base one if no activation condition was encountered.

To make it clearer, let's take a look at an example

eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1cXFtT4zhcdTAwMTN9n18xxfe6aKXWfd+4XHUwMDBld1x1MDAwMuE2fLWVMolcdJ44TkhMIGzNf99WYGPjxFx1MDAxMIaEeGZwUVx1MDAxMGQ5kqU+Ot1Hbf/z6fPnhbjf9lx1MDAxN/76vODfVb0wqHW824U/XFx5z+90g1aEp2Dwf7d106lcdTAwMGVqXsVxu/vXn38mV5Bqq/lwlVx1MDAxZvpNP4q7WO//+P/nz/9cZn6n21x0w6Dd9Vx1MDAwN9VcdTAwMDcnkoaMzFx1MDAxNu61okGbTCpqpJVWXHUwMDBma1x1MDAwNN1VbCz2a3j60lx1MDAwYrt+csZcdTAwMTUtNFZvj+1+P1xcOu1vX97eSHFf7Z4lrV5cdTAwMDZhWI774aBP3Vx1MDAxNt5Hcq5cdTAwMWJ3Wlxy/zSoxVeu7Ux53lWd1k39KvK73SfXtNpeNYj7rozSYalcdTAwMTfVXHUwMDA335GU3LlcdTAwMWHAXHUwMDE04ZopJVx1MDAxNVx1MDAwMOVSXHJPP3yBVURyMEpwhXWFzPRspVx1MDAxNbY6rmf/Y1azKiR9u/CqjTp2MKoldS5cdTAwMDdHUuf28X6NIUpbSaVcdTAwMTbGUCNgWOPKXHUwMDBm6lfxYKKI4JJxLo1cdTAwMDbsrU064lx1MDAwZiZEcFx1MDAwZSBw0oYnXFzr7c3awDD+Tmah4zX9TXdFdFx1MDAxM4bpoYxqj0P5n1x1MDAwMSUmXHUwMDA0jyXfk9tz9deyppc2vycmXHUwMDE4+3fx8L5TJvOtsttpnFdMrVx1MDAxY/Dt7lx1MDAwNts+91x1MDAwZXtcdTAwMGLDet9cdTAwMWY/Jd2/ade8XHUwMDA3XHUwMDBiZJqhgVx1MDAxYSmF0mJ4Plxmokb23sJWtZFcdTAwMTjtp9SNjEDlST9TOLG5MLFcXHOKhiMnhsn4ey44TFx1MDAwNCVWS1x1MDAwNFx1MDAwMEJEcVx1MDAwNU9hwsBcdTAwMTIqhFx1MDAxNFx1MDAxNlx1MDAwZjBUvFx1MDAwNSZxx4u6ba+DljVcblx1MDAxNW6JVu5cdTAwMTBcZjh2hqlRrFx1MDAwMM2CgzHsXHUwMDEzUKHE29Hx5MRcYlxmpmmpSa9aUVxcXHUwMDBl7lx1MDAwN/amnpSue80g7D+Z14FcdOMwLnvpJd+VLoVB3Vx1MDAxOfNCXHUwMDE1e+t3nth5XHUwMDFjILNcZis0g1otTF1dxaa8IPI7m5Ms9K1OUFx1MDAwZlwiLzxcdTAwMWHbXHUwMDEzvG9/47+pYlx1MDAwNORcdTAwMGZcdTAwMDGSMZ5cdTAwMDfJwVxuqa1JhvolRF5cdTAwMWQvtu/i9abnbV6023BcXFx0Vytynoi0L1x1MDAwMpIzg4hTXHUwMDEyeUmCXHUwMDEyyb0+4JExpC1hXHUwMDA1kooyOFx1MDAxYTPDo5JcdTAwMDSXP1xcXHUwMDAwqWRaapPczTNwXHUwMDA0Sl271Jj5wJFKybnQQmiTNsuZwvHS9+Kbjs9yIFx1MDAxOfqX8TOAjFvtPDQ+6XFcdTAwMTZ6o61OXHUwMDA3fkZlXHUwMDBih4RcYopKY9Tk6PNcdTAwMGZ2L9QtMsva/Xnb15XN6212V3D0oVuoXHJIIcFcbsogMaNH+FGC3rNzXHUwMDFhXHUwMDExXHUwMDE2iud7jXBpfSF+XHUwMDFjflJcdTAwMTPqONegNaN/Sm0y7M/gTynNQZl5seFcdTAwMDB+oFx1MDAwMf3Yd4OfXHUwMDFmeVx1MDAxN6Ffe1/0jTQ6Je6TOluaoFx1MDAwZoymQF9cdTAwMDE/Xr5buTipLJ+IW1x1MDAxNTSWllwien78peDwXHUwMDAzSiRobVx1MDAwMW1cdTAwMWWszbKfc1YpIPehlUmW7df0yE9cdTAwMDPhzlx1MDAxN8UhZ+jkpejsOV/UMitcdTAwMTVnMIVI7ScjP5hcdTAwMGL5wdTxx/PDQWQ+SbVJmcJL+DtomLW1m3245uudm35vTZlyyVx1MDAxNlx1MDAxY3/WXHUwMDEyUFxcY+yrcFx1MDAxMU+JSFx1MDAwZvjDIM1ilCaEXHUwMDAwaYTJ9CvBn085OrJvcD6BMIc/7IhcdTAwMDFcdTAwMGXjdJNR/Fx1MDAxOZxcdTAwMWTk79+J/GpBd1x1MDAwZew32urr4Nfxq/GDXHUwMDAxjsEgaJotXHUwMDFkYpBRkFx1MDAxOJG8Qrnc94+4X67UNyvbjfXS5pFe+9L7VmxJxlpGKLqXimJcdTAwMDQohUnC4f6DXHUwMDE3jvGhQT9AXHUwMDE5oy2lb4pcdTAwMDBzhUvLiZTKWEVcdTAwMTGD2o5cdP6EIFx1MDAwMtdcYoMmb1xyZ+nF4DFcdTAwMTZcdTAwMDTFhEjZ8lx1MDAxNGVL/ljyjGw5d2WRpfyTXHUwMDExQ0ZcdTAwMTeHSTB0YkO+Z2f01NvZi+q1k+Nvh2GpXHUwMDAyUb3YZEIpruLII5wxXHUwMDFjcqoyXG48XHUwMDE4tHNhLLpzOFRcdTAwMTjnzMybU4qYV0tcdTAwMTlMXHUwMDFhXHUwMDA1lFx0OVx1MDAwNVx1MDAwM/5xb05psPxcdTAwMTWW+jY6WcHT+PGdpYzRVqdJJylFO4NCoFSgeyFs4vS9hEJcdTAwMTMuVm/LXHUwMDA2LuLu/enZXHUwMDFl3fi2078pNp0wLjnR1GJoZZxHlUWhokRhlGMtLonSynyfbs50wjAmXHUwMDE0XHUwMDA2lJjJPthPQSg0d09cdTAwMTeA41x1MDAwNOtXKON7XHUwMDA33sm+aVxcwlXUaV32blx1MDAwZcr7q1x1MDAxYsXmXHUwMDEzrlx1MDAwNFx1MDAxOcCVKbRkLrKOkeZEcYxKXHUwMDAwrEbXSL3Fkp9XXHUwMDA3ODE/oFx1MDAwZVx1MDAwMDhhfFx1MDAxYVx1MDAwZdFPxifvrFx1MDAwZYy2Olx1MDAxZHVcdTAwMDBovjogNLdcdTAwMDJnd3KHbq9cdTAwMWPC4opp3NmLY716Xe2vndf8Ylx1MDAwM5C6ZdyAwYWaIXFmUypw5SZcYj/DpdTKPidcdTAwMGbMa29cboMq5LjEIfhd5LlfZG+K2Xx5XHUwMDFjXHUwMDFkXHUwMDFiq4VVk1x1MDAwMzD6euHR7dt+/WBt9ZxXe3zxZGur2Fx1MDAwMMS7JMg6nFx1MDAxOVxcyZHinsdfPlx1MDAwMc5FnmNcdTAwMTZpm1xuOldcdTAwMDL80OfeXHUwMDFhUFx0lsuChlmXq8Ynl+fM+sbu6tXd2V35NLyutJrL7fjkoNjxlFx1MDAxNkAs1WhJXHUwMDE0XHUwMDAzJmMyW1SCcsKcXHUwMDAziiBcdTAwMTTCyjclTOXGU4xxQlx1MDAwNzFcdTAwMWSlYGkqR+1cdTAwMTVcdTAwMDGVlG7VTFx1MDAwN1xyv1lAXHUwMDA1z2z3cFx0Llx1MDAwN41Ozie7tNc0XHUwMDE3teb1LttcXIF6ne1Vr09cbs0nWlxuQjFaQmu1XHUwMDAyRzzjz1x0plxitYYqxLXWs1xmqCwjYyx4lEIsLj7M0Lnu8FxioVx1MDAxMOPvxiDlm4vqXFxUubFcck+TR1JL40jqLWgnXHUwMDE4y8mFua3L6yV5dvb1/LjTOt09uDxcbq/3ropNJIxKS1x1MDAxNNVcYlx1MDAxZVxmXHUwMDFjXHUwMDE18Iye4fZiXHUwMDE1rkBGWFx1MDAxMFTZbM+mxCRcdTAwMDBcdTAwMDSdXCKuLWVWcuzKj1BcdNPaKCl/YypR+aFcdEOXwc3j5FSyfLFcdND39qBxcHzYL1x1MDAxZHY25Neo0FTCqKZcdTAwMDR9a4MxgVx1MDAxYnWWyVx1MDAxY1x1MDAxMFxmXGKaXHUwMDA3V8g5mks+uzxya4h0sVx0hvpIXHUwMDE3XGKciWJcdTAwMTOF9lxyPE33v7w4lyzw76zPjW14Slxugcjdc+XMXG6t0urPSyhcXLzYXHUwMDE2am1lR693j1x1MDAxNoOVXHUwMDAzu86WXHUwMDBlXHUwMDBijUJcXIOJZkxaIajLXHUwMDBmXHUwMDE4ceg4QSM3RqJrJ8ybXGJl+vpcdTAwMWO2aVx1MDAxOIf5OndcdTAwMWby3Fuy53I9Oi6cSkRTIcRL4Fx1MDAwYlx1MDAwZSRAc3fxPOw37781XHLf88++XHUwMDE2XHUwMDFhfJZrYlx1MDAxNVx1MDAxN47ghGAy+ZJx4KP56vh8UsetYUhAXHUwMDE0fqPsuV8pdVx1MDAxY3SulsGdXHUwMDEw5XKxJo+mjndOdntL7f6JXGJPxGE3XjruVFxuXHI+hjEjsYKjn62U0ExnZTlGiZDaKo38KN5cdTAwMTZLTT9z3LmrXHUwMDE4QdHf76mpXyRxXHUwMDFjWG74J4XLpeYwefSn/eOwv7V5s9jwarZpT3W/slx1MDAxN1x1MDAxN1x1MDAxYn0u90JcdTAwMGKLvEfd9lx1MDAxNFx1MDAxZFx1MDAxMcUtocpIiuxnrFX50d98uI8xoE6v/yC/YpOfqz1cdTAwMGV+Kj8xSjC0Rlx1MDAxY9qJ0des1lwidbSzeVx1MDAwNV+qZ83grlx1MDAwNFGtUXD0KUuMNoorrZximH1qw1x1MDAwMDFYSjlcdTAwMDLU2Fx1MDAxOT7DXHUwMDBmYIlcdTAwMDbuesJAuP6Mos9w4lQg7mhYXHUwMDE5kXKTh2C0XHUwMDFjrNRze+HFcySJv1JcdTAwMTn3r8BoN/Y68XJcdTAwMTDVgqievcSPajlnQq9cdTAwMWKvtJrNIMZulFpBXHUwMDE0Z2tcZr53qdNp3V753shY4Dfnnmu7r3v6ho/k0+fExlx1MDAwNv9cZj///cfY2ov5U++OkUlPvu9T+u9rgS9zk3tcdTAwMTnjiHtcdK/YwFvqXHUwMDFk9K9cdTAwMGZL7TuxcSjLe6u3la2oVGzkU67IYJdcdTAwMTl/NFx1MDAxNVwi8/ZcdTAwMGV0h1x0XGKDRqu14Ea+6SU3zyOfS1x1MDAwMoYpaylcdTAwMDD2Y4zb+1wi8DlGz5aaaWiwXHUwMDFmuH833OdNvDtmXHUwMDA1e26yhcm+PXZcdTAwMDHjLjX5Y5pHSzunpYq1cN6+7ZQ6x/vt/ZJXdNhLXCJd4lx1MDAxNVdCcpNRmjjTXHUwMDA0XHUwMDAzYCMx2lVUmNnlYVpGcNVcdTAwMDEjQFx0JcGMoXtticLwh2qMg6hLXFxcdTAwMWKhe7xMMsTXTFx1MDAxZVx1MDAxNPuA/Uxgnzvx7lx1MDAxOJnyaaE+P1tHgXGPl7xC4jqsrV9vNdrdVtncxTu9w4B2N1x1MDAwYp5+nXXzM/lcdTAwMDI40Fx1MDAwNM9cdTAwMWFqzeDB0Zmh3r1cdTAwMTNMXHUwMDE5MG7H1JmAXHUwMDE4XHUwMDEzY2tFjOHcYF/cXHUwMDBiuvhIyoBG05CWzSZj4Fx1MDAwM/UzQX3+xLtjZMpfXHT7PG2Np1x1MDAxMidG39HHJWVp4fQl3J/cb+pe6er6eqMue1ulnrgobbFi415ITaR7/1x1MDAwYpXaXGKbSoJ/TPvGxdi9LcxYjn/57Oj+x96KXHUwMDAywlx1MDAwMmPpZ50/xO2fStxGXG7PXHUwMDAzIOfuXHUwMDA1kpxOzrueODitnOwsn7U6+ytbi4tcci9sXHUwMDE1/LlD9LBcdI6By/ukjFrIyGugKeFSuFRsRCdPZfBcdTAwMTRE3KaSXHUwMDE5XHUwMDBi89xbXHUwMDAy7ZK+3lxyfoWWtj890uuC126XY1x1MDAxY6ehXHUwMDA3s9BcdTAwMGL82+X83M1Pj9B1IPFcdTAwMDeOz/dP3/9cdTAwMDVcdTAwMDD1hu4ifQ==Basefeature1enabledfeature2disabledContext1Context2feature1disabledSubcontext1Subcontext2feature1enabledfeature2enabledfeature2enabled

The above schema represents a "context tree". The base node of the tree represents activation conditions that are defined by features. Each node may or may not redefine activation conditions for these features. To keep it simple, we only used "basic" startegy (feature is either enable or disable).

Now let's see what happens when requesting feature activation:

  • feature1 without specifying context: enabled (easy, base activation condition was used here)
  • feature1 for context1: disabled (we use context1 redefinition for feature1)
  • feature1 for subcontext2: disabled (there is no activation condition redefinition for subcontext2, therefore we use the closest one when going up: context1 redefinition)
  • feature2 for subcontext1: disabled (context2 has no overload for subcontext1 nor context1, therefore base activation condition is used)