All Projects → nxt-insurance → nxt_registry

nxt-insurance / nxt_registry

Licence: MIT license
A simple registry to implement the container pattern

Programming Languages

ruby
36898 projects - #4 most used programming language
shell
77523 projects

Projects that are alternatives of or similar to nxt registry

Go Containerregistry
Go library and CLIs for working with container registries
Stars: ✭ 974 (+5987.5%)
Mutual labels:  registry, container
inspr
Inspr is an agnostic application mesh for simpler, faster, and securer development of distributed applications (dApps).
Stars: ✭ 49 (+206.25%)
Mutual labels:  registry, container
Hub Tool
🧪 Docker Hub experimental CLI tool
Stars: ✭ 147 (+818.75%)
Mutual labels:  registry, container
singularityhub.github.io
Container tools for scientific computing! Docs at https://singularityhub.github.io/singularityhub-docs
Stars: ✭ 68 (+325%)
Mutual labels:  registry, container
Harbor
An open source trusted cloud native registry project that stores, signs, and scans content.
Stars: ✭ 16,320 (+101900%)
Mutual labels:  registry, container
runiac
Run IaC Anywhere With Ease
Stars: ✭ 18 (+12.5%)
Mutual labels:  container
typeioc
Dependency injection container for typescript / javascript
Stars: ✭ 32 (+100%)
Mutual labels:  container
plf queue
A C++ data container replicating std::queue functionality but with better performance.
Stars: ✭ 20 (+25%)
Mutual labels:  container
docker-cyberchef
GCHQ CyberChef in a container
Stars: ✭ 81 (+406.25%)
Mutual labels:  container
BarterOnly
An ecommerce platform to buy or exchange items at your convenience
Stars: ✭ 16 (+0%)
Mutual labels:  ruby-on-rails
wor-authentication
Gem to add authentication to your application using JWT, with expirable, renewable and customizable tokens!
Stars: ✭ 63 (+293.75%)
Mutual labels:  ruby-on-rails
avo
Ruby on Rails application building framework
Stars: ✭ 907 (+5568.75%)
Mutual labels:  ruby-on-rails
docker-metasploit
Metasploit framework with steroids
Stars: ✭ 49 (+206.25%)
Mutual labels:  container
software-systems-architecture
A collection of descriptions of the architecture that various systems use.
Stars: ✭ 24 (+50%)
Mutual labels:  ruby-on-rails
craneoperator
Gives you a simple web interface for browsing around a Docker Registry
Stars: ✭ 116 (+625%)
Mutual labels:  registry
awesome-cloud-native-security
awesome resources about cloud native security 🐿
Stars: ✭ 233 (+1356.25%)
Mutual labels:  container
akk-stack
Containerized EverQuest Emulator Server Environment
Stars: ✭ 36 (+125%)
Mutual labels:  container
codewind-vscode
Extension for developing cloud-native, containerized applications from VS Code
Stars: ✭ 17 (+6.25%)
Mutual labels:  container
activerecord-crate-adapter
Ruby on Rails ActiveRecord adapter for CrateDB
Stars: ✭ 27 (+68.75%)
Mutual labels:  ruby-on-rails
knowledge
Everything I know: DevOps & CloudNative, Music, Homelab, Blockchain, AI, etc...
Stars: ✭ 84 (+425%)
Mutual labels:  container

CircleCI

NxtRegistry

NxtRegistry is a simple container that allows you to register and resolve values in nested structures.

Installation

Add this line to your application's Gemfile:

gem 'nxt_registry'

And then execute:

$ bundle

Or install it yourself as:

$ gem install nxt_registry

Usage

Simple use case

Instance Level

If you simply need a single global instance of a registry include NxtRegistry::Singleton:

class Example
  include NxtRegistry::Singleton
  
  registry do
    register(:ruby, 'Stone')
    register(:python, 'Snake')
    register(:javascript, 'undefined')
  end
end

Example.resolve(:ruby) # => 'Stone'

Alternatively you can simply create instances of NxtRegistry::Registry:

registry = NxtRegistry::Registry.new do
  register(:andy, 'Andy')
  register(:anthony, 'Anthony')
  register(:aki, 'Aki')
end

registry.resolve(:aki) # => 'Aki'

Class Level

You can also add registries on the class level simply by extending your class with NxtRegistry

class OtherExample
  extend NxtRegistry
 
  registry(:errors) do
    register(KeyError, ->(error) { puts 'KeyError handler' } )
    register(ArgumentError, ->(error) { puts 'ArgumentError handler' } )
  end

  registry(:country_codes) do
    register(:germany, :de)
    register(:england, :uk)
    register(:france, :fr)
  end 
end

OtherExample.registry(:errors).resolve(KeyError)
# KeyError handler
# => nil
OtherExample.registry(:country_codes).resolve(:germany)
# => :de

Register Patterns

You can also register values with patterns as keys. Non pattern keys are always evaluated first and then patterns will be tried to match by definition sequence.

class Example
  extend NxtRegistry
  
  registry :status_codes do
    register(/\A4\d{2}\z/, 'Client errors')
    register(/\A5.*\z/, 'Server errors')
    register('422', 'Unprocessable Entity')
    register(:'503', 'Internal Server Error')
  end
end

Example.registry(:status_codes).resolve('503') # => "Internal Server Error"
Example.registry(:status_codes).resolve(503) # => "Internal Server Error"
Example.registry(:status_codes).resolve(422) # => "Unprocessable Entity"
Example.registry(:status_codes).resolve(404) # => "Client Errors"

Readers

Access your defined registries with the registry(:country_code) method.

Nesting registries

You can also simply nest registries like so:

class Nested
  extend NxtRegistry

  registry :developers do
    register(:frontend) do
      register(:igor, 'Igor')
      register(:ben, 'Ben')
    end
    
    register(:backend) do
      register(:rapha, 'Rapha')
      register(:aki, 'Aki')
    end
  end
end

Nested.registry(:developers).resolve(:frontend, :igor)
# => 'Igor'

Inherit options in nested registries

class Nested
  extend NxtRegistry
  
  registry :developers, default: 'options can be inherited' do
    register(:frontend, inherit_options: true) do
      register(:igor, 'Igor')
      register(:ben, 'Ben')
    end
  end
end

Nested.registry(:developers).resolve(:frontend, :blank)
# => 'options can be inherited'

Defining specific nesting levels of a registry

Another feature of NxtRegistry is that you can define the nesting levels for a registry. Levels allow you to dynamically register values within the defined levels. This means that on any level the registry will resolve to another registry and you can register values into a deeply nested structure.

class Layer
  extend NxtRegistry
  
  registry :from do
    level :to do
      level :via
    end  
  end
end

# On every upper level every resolve returns a registry 
Layer.registry(:from) # => Registry[from]
Layer.registry(:from).resolve(:munich) # => Registry[to] -> {}
Layer.registry(:from).resolve(:amsterdam) # => Registry[to] -> {}
Layer.registry(:from).resolve(:any_key) # => Registry[to] -> {}
Layer.registry(:from).resolve(:munich, :amsterdam) # => Registry[via] -> {}

# Register a value on the bottom level
Layer.registry(:from).resolve(:munich, :amsterdam).register(:train, -> { 'train' })
# Resolve the complete path 
Layer.registry(:from).resolve(:munich, :amsterdam, :train) #  => 'train'

For registries with multiple levels the normal syntax for registering and resolving becomes quite weird and unreadable. This is why every registry can be accessed through it's name or a custom accessor. The above example then can be simplified as follows.

class Layer
  extend NxtRegistry
  
  registry :path, accessor: :from do # registry named path, can be accessed with .from(...)
    level :to do
      level :via
    end  
  end
end

# Register a value
Layer.registry(:path).from(:munich).to(:amsterdam).via(:train, -> { 'train' })
# Resolve the complete path
Layer.registry(:path).from(:munich).to(:amsterdam).via(:train) #  => 'train'

Note that this feature is also available for registries with a single level only.

Restrict keys to a certain set

Use allowed_keys to restrict which keys can be registered on a specific level.

registry :example, allowed_keys: %w[one two three]

Require a certain set of keys to be registered

Use required_keys to enforce a certain set of keys to be registered on a specific level. This is especially helpful if you use registries in multiple places and you want to ensure they all register the same set of keys.

registry :example, required_keys: %w[one two three]

Default values

Use default to register a default value that will be resolved in case an attribute was not registered.

registry :example, default: ->(value) { 'default' }

Blocks

When you register a block value that can be called, it will automatically be called when you resolve the value. If that's not what you want, you can configure your registry (on each level) not to call blocks directly by defining call false

registry :example, call: false do
  register(:one, ->(value) { 'Not called when resolved' } )
end

Memoize

Values are memoized per default. Switch it off with memoize: false

registry :example, memoize: false do
  register(:one, -> { Time.current } )
end

registry.resolve(:one)
# => 2020-01-02 23:56:15 +0100
registry.resolve(:one)
# => 2020-01-02 23:56:17 +0100
registry.resolve(:one)
# => 2020-01-02 23:56:18 +0100

IMPORTANT: whenever you want your value to be evaluated anew every time it is resolved, you should always wrap it in a lambda.

For example, if you're resolving an ENV variable you should do it this way:

registry :example do
  register(:env_variable, -> { ENV['FEATURE_FLAG'] })
end

In this case config can be reloaded on the fly, and tests can also overwrite feature flags, for example.

Resolve callbacks

You can hook into the before and after resolver callbacks in case you need to lay hands on your values before and / or after resolving. A callback can be anything that implements :call to which the value is passed.

registry :example do
  key_resolver ->(key) { key.strip }
  resolver ->(value) { value.upcase }
  
  register(:input, 'output')
end

registry.resolve('  input   ')
# => 'OUTPUT'

Transform keys

NxtRegistry uses a plain ruby hash to store values internally. Per default all keys used are transformed with &:to_s. Thus you can use symbols or strings to register and resolve values. If it's not what you want, switch it off with transform_keys false or define your own key transformer by assigning a block to transform_keys: transform_keys ->(key) { key.upcase }

registry :example do
  transform_keys ->(key) { key.to_s.downcase }
  register(:bombshell, 'hanna')
end

registry.resolve('BOMBSHELL')
# => 'hanna'

Customize registry errors

You can also customize what kind of errors are being raised in case a of a key was not registered or was already registered. by providing blocks or a handler responding to :call for on_key_already_registered and on_key_already_registered

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/nxt_registry.

License

The gem is available as open source under the terms of the MIT License.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].