Package goldi implements a lazy dependency injection framework for go. Goldi is MIT-Licensed
Package provider provide a lazy-initalized value in context. it's a useful for DI(Dependencies Inject).
Package xstats is a generic client for service instrumentation. xstats is inspired from Go-kit's metrics (https://github.com/go-kit/kit/tree/master/metrics) package but it takes a slightly different path. Instead of having to create an instance for each metric, xstats use a single instance to log every metrics you want. This reduces the boiler plate when you have a lot a metrics in your app. It's also easier in term of dependency injection. Talking about dependency injection, xstats comes with a xhandler.Handler integration so it can automatically inject the xstats client within the net/context of each request. Each request's xstats instance have its own tags storage ; This let you inject some per request contextual tags to be included with all observations sent within the lifespan of the request. xstats is pluggable and comes with integration for StatsD and DogStatsD, the Datadog (http://datadoghq.com) augmented version of StatsD with support for tags. More integration may come later (PR welcome).
Package di implements a dependency injection (DI) container.
Package resource provides an abstraction for loading external data from multiple sources in a manner compatible with dependency injection and configuration-driven programming.
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package controllerruntime provides tools to construct Kubernetes-style controllers that manipulate both Kubernetes CRDs and aggregated/built-in Kubernetes APIs. It defines easy helpers for the common use cases when building CRDs, built on top of customizable layers of abstraction. Common cases should be easy, and uncommon cases should be possible. In general, controller-runtime tries to guide users towards Kubernetes controller best-practices. The main entrypoint for controller-runtime is this root package, which contains all of the common types needed to get started building controllers: The examples in this package walk through a basic controller setup. The kubebuilder book (https://book.kubebuilder.io) has some more in-depth walkthroughs. controller-runtime favors structs with sane defaults over constructors, so it's fairly common to see structs being used directly in controller-runtime. A brief-ish walkthrough of the layout of this library can be found below. Each package contains more information about how to use it. Frequently asked questions about using controller-runtime and designing controllers can be found at https://github.com/kubernetes-sigs/controller-runtime/blob/master/FAQ. Every controller and webhook is ultimately run by a Manager (pkg/manager). A manager is responsible for running controllers and webhooks, and setting up common dependencies (pkg/runtime/inject), like shared caches and clients, as well as managing leader election (pkg/leaderelection). Managers are generally configured to gracefully shut down controllers on pod termination by wiring up a signal handler (pkg/manager/signals). Controllers (pkg/controller) use events (pkg/events) to eventually trigger reconcile requests. They may be constructed manually, but are often constructed with a Builder (pkg/builder), which eases the wiring of event sources (pkg/source), like Kubernetes API object changes, to event handlers (pkg/handler), like "enqueue a reconcile request for the object owner". Predicates (pkg/predicate) can be used to filter which events actually trigger reconciles. There are pre-written utilies for the common cases, and interfaces and helpers for advanced cases. Controller logic is implemented in terms of Reconcilers (pkg/reconcile). A Reconciler implements a function which takes a reconcile Request containing the name and namespace of the object to reconcile, reconciles the object, and returns a Response or an error indicating whether to requeue for a second round of processing. Reconcilers use Clients (pkg/client) to access API objects. The default client provided by the manager reads from a local shared cache (pkg/cache) and writes directly to the API server, but clients can be constructed that only talk to the API server, without a cache. The Cache will auto-populate with watched objects, as well as when other structured objects are requested. Caches may also have indexes, which can be created via a FieldIndexer (pkg/client) obtained from the manager. Indexes can used to quickly and easily look up all objects with certain fields set. Reconcilers may retrieve event recorders (pkg/recorder) to emit events using the manager. Clients, Caches, and many other things in Kubernetes use Schemes (pkg/scheme) to associate Go types to Kubernetes API Kinds (Group-Version-Kinds, to be specific). Similarly, webhooks (pkg/webhook/admission) may be implemented directly, but are often constructed using a builder (pkg/webhook/admission/builder). They are run via a server (pkg/webhook) which is managed by a Manager. Logging (pkg/log) in controller-runtime is done via structured logs, using a log set of interfaces called logr (https://godoc.org/github.com/go-logr/logr). While controller-runtime provides easy setup for using Zap (https://go.uber.org/zap, pkg/log/zap), you can provide any implementation of logr as the base logger for controller-runtime. Metrics (pkg/metrics) provided by controller-runtime are registered into a controller-runtime-specific Prometheus metrics registry. The manager can serve these by an HTTP endpoint, and additional metrics may be registered to this Registry as normal. You can easily build integration and unit tests for your controllers and webhooks using the test Environment (pkg/envtest). This will automatically stand up a copy of etcd and kube-apiserver, and provide the correct options to connect to the API server. It's designed to work well with the Ginkgo testing framework, but should work with any testing setup. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package disgord provides Go bindings for the documented Discord API, and allows for a stateful Client using the Session interface, with the option of a configurable caching system or bypass the built-in caching logic all together. Create a Disgord session to get access to the REST API and socket functionality. In the following example, we listen for new messages and write a "hello" message when our handler function gets fired. Session interface: https://godoc.org/github.com/LaevusDexter/disgord/#Session Disgord also provides the option to listen for events using a channel. The setup is exactly the same as registering a function. Simply define your channel, add buffering if you need it, and register it as a handler in the `.On` method. Never close a channel without removing the handler from Disgord. You can't directly call Remove, instead you inject a controller to dictate the handler's lifetime. Since you are the owner of the channel, disgord will never close it for you. Here is what it would look like to use the channel for handling events. Please run this in a go routine unless you know what you are doing. Disgord handles sharding for you automatically; when starting the bot, when discord demands you to scale up your shards (during runtime), etc. It also gives you control over the shard setup in case you want to run multiple instances of Disgord (in these cases you must handle scaling yourself as Disgord can not). Sharding is done behind the scenes, so you do not need to worry about any settings. Disgord will simply ask Discord for the recommended amount of shards for your bot on startup. However, to set specific amount of shards you can use the `disgord.ShardConfig` to specify a range of valid shard IDs (starts from 0). starting a bot with exactly 5 shards Running multiple instances each with 1 shard (note each instance must use unique shard ids) Handle scaling options yourself > Note: if you create a CacheConfig you don't have to set every field. > Note: Only LFU is supported. > Note: Lifetime options does not currently work/do anything (yet). A part of Disgord is the control you have; while this can be a good detail for advanced users, we recommend beginners to utilise the default configurations (by simply not editing the configuration). Example of configuring the cache: If you just want to change a specific field, you can do so. The fields are always default values. > Note: Disabling caching for some types while activating it for others (eg. disabling channels, but activating guild caching), can cause items extracted from the cache to not reflect the true discord state. Example, activated guild but disabled channel caching: The guild is stored to the cache, but it's channels are discarded. Guild channels are dismantled from the guild object and otherwise stored in the channel cache to improve performance and reduce memory use. So when you extract the cached guild object, all of the channel will only hold their channel ID, and nothing more. To keep it safe and reliable, you can not directly affect the contents of the cache. Unlike discordgo where everything is mutable, the caching in disgord is immutable. This does reduce performance as a copy must be made (only on new cache entries), but as a performance freak, I can tell you right now that a simple struct copy is not that expensive. This also means that, as long as discord sends their events properly, the caching will always reflect the true state of discord. If there is a bug in the cache and you keep getting the incorrect data, please file an issue at github.com/LaevusDexter/disgord so it can quickly be resolved(!) Whenever you call a REST method from the Session interface; the cache is always checked first. Upon a cache hit, no REST request is executed and you get the data from the cache in return. However, if this is problematic for you or there exist a bug which gives you bad/outdated data, you can bypass it by using Disgord flags. In addition to disgord.IgnoreCache, as shown above, you can pass in other flags such as: disgord.SortByID, disgord.OrderAscending, etc. You can find these flags in the flag.go file. `disgord_diagnosews` will store all the incoming and outgoing JSON data as files in the directory "diagnose-report/packets". The file format is as follows: unix_clientType_direction_shardID_operationCode_sequenceNumber[_eventName].json `json_std` switches out jsoniter with the json package from the std libs. `disgord_removeDiscordMutex` replaces mutexes in discord structures with a empty mutex; removes locking behaviour and any mutex code when compiled. `disgord_parallelism` activates built-in locking in discord structure methods. Eg. Guild.AddChannel(*Channel) does not do locking by default. But if you find yourself using these discord data structures in parallel environment, you can activate the internal locking to reduce race conditions. Note that activating `disgord_parallelism` and `disgord_removeDiscordMutex` at the same time, will cause you to have no locking as `disgord_removeDiscordMutex` affects the same mutexes. `disgord_legacy` adds wrapper methods with the original discord naming. eg. For REST requests you will notice Disgord uses a consistency between update/create/get/delete/set while discord uses edit/update/modify/close/delete/remove/etc. So if you struggle find a REST method, you can enable this build tag to gain access to mentioned wrappers. `disgordperf` does some low level tweaking that can help boost json unmarshalling and drops json validation from Discord responses/events. Other optimizations might take place as well. `disgord_websocket_gorilla` replaces nhooyr/websocket dependency with gorilla/websocket for gateway communication. In addition to the typical REST endpoints for deleting data, you can also use Client/Session.DeleteFromDiscord(...) for basic deletions. If you need to delete a specific range of messages, or anything complex as that; you can't use .DeleteFromDiscord(...). Not every struct has implemented the interface that allows you to call DeleteFromDiscord. Do not fret, if you try to pass a type that doesn't qualify, you get a compile error.
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package echo provides dependency injection definitions.
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package psyringe provides an easy to use, lazy and concurrent dependency injector. Psyringe makes dependency injection very easy for well-written Go code. It uses Go's type system to decide what to inject, and uses channels to orchestrate value construction, automatically being as concurrent as your dependency graph allows. Psyringe does not rely on messy struct field tags nor verbose graph construction syntax. It is very flexible and has a small interface, allowing you to tailor things like scopes and object lifetimes very easily using standard Go code. The example tests should speak for themselves, but if you want a deeper explanation of how Psyringe works, read on. Constructors and values added to psyringe have an implicit "injection type". This is the type of value that constructor or value represents in the graph. For non-constructor values, the injection type is the type of the value itself, determined by reflect.GetType(). For constructors, it is the type of the first output (return) value. It is important to understand this concept, since a single psyringe can have only one value or constructor per injection type. Go does not have an explicit concept of "constructor". In Psyringe, constructors are defined as any function that returns either a single value, or two values where the second is an error. They can have any number of input parameters. A Psyringe knows how to populate fields in a struct with values of any injection type that has been added to it. When called upon to generate a value, via a call to Inject, the Psyringe implicitly constructs a directed acyclic graph (DAG) from the constructors and values, channelling values of each injection type into the relevant parameter of any constructors which require it, and ultimately into any fields of that type in the target struct which require it. For a given Psyringe, each constructor will be called at most once. After that, the generated value is provided directly without calling the constructor again. Thus every value in a Psyringe is effectively a singleton. The Clone method allows taking snapshots of a Psyringe in order to re-use its constructor graph whilst generating new values. It is idiomatic to use multiple Psyringes with differing scopes to inject different fields into the same object. Contrived example showing how to create a Psyringe with interdependent constructors and then inject their values into a struct that depends on them.
Package echo provides dependency injection definitions.
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Service Provider Interface used for dependency injection IOC. Service Descriptor used for dependency injection IOC. Service Provider used for dependency injection IOC. Service Scope used for dependency injection IOC. Service Type Enum used for dependency injection IOC.
Package inject provides utilities for mapping and injecting dependencies in various ways.
Package controllerruntime provides tools to construct Kubernetes-style controllers that manipulate both Kubernetes CRDs and aggregated/built-in Kubernetes APIs. It defines easy helpers for the common use cases when building CRDs, built on top of customizable layers of abstraction. Common cases should be easy, and uncommon cases should be possible. In general, controller-runtime tries to guide users towards Kubernetes controller best-practices. The main entrypoint for controller-runtime is this root package, which contains all of the common types needed to get started building controllers: The examples in this package walk through a basic controller setup. The kubebuilder book (https://book.kubebuilder.io) has some more in-depth walkthroughs. controller-runtime favors structs with sane defaults over constructors, so it's fairly common to see structs being used directly in controller-runtime. A brief-ish walkthrough of the layout of this library can be found below. Each package contains more information about how to use it. Frequently asked questions about using controller-runtime and designing controllers can be found at https://github.com/kubernetes-sigs/controller-runtime/blob/master/FAQ.md. Every controller and webhook is ultimately run by a Manager (pkg/manager). A manager is responsible for running controllers and webhooks, and setting up common dependencies (pkg/runtime/inject), like shared caches and clients, as well as managing leader election (pkg/leaderelection). Managers are generally configured to gracefully shut down controllers on pod termination by wiring up a signal handler (pkg/manager/signals). Controllers (pkg/controller) use events (pkg/events) to eventually trigger reconcile requests. They may be constructed manually, but are often constructed with a Builder (pkg/builder), which eases the wiring of event sources (pkg/source), like Kubernetes API object changes, to event handlers (pkg/handler), like "enqueue a reconcile request for the object owner". Predicates (pkg/predicate) can be used to filter which events actually trigger reconciles. There are pre-written utilities for the common cases, and interfaces and helpers for advanced cases. Controller logic is implemented in terms of Reconcilers (pkg/reconcile). A Reconciler implements a function which takes a reconcile Request containing the name and namespace of the object to reconcile, reconciles the object, and returns a Response or an error indicating whether to requeue for a second round of processing. Reconcilers use Clients (pkg/client) to access API objects. The default client provided by the manager reads from a local shared cache (pkg/cache) and writes directly to the API server, but clients can be constructed that only talk to the API server, without a cache. The Cache will auto-populate with watched objects, as well as when other structured objects are requested. The default split client does not promise to invalidate the cache during writes (nor does it promise sequential create/get coherence), and code should not assume a get immediately following a create/update will return the updated resource. Caches may also have indexes, which can be created via a FieldIndexer (pkg/client) obtained from the manager. Indexes can used to quickly and easily look up all objects with certain fields set. Reconcilers may retrieve event recorders (pkg/recorder) to emit events using the manager. Clients, Caches, and many other things in Kubernetes use Schemes (pkg/scheme) to associate Go types to Kubernetes API Kinds (Group-Version-Kinds, to be specific). Similarly, webhooks (pkg/webhook/admission) may be implemented directly, but are often constructed using a builder (pkg/webhook/admission/builder). They are run via a server (pkg/webhook) which is managed by a Manager. Logging (pkg/log) in controller-runtime is done via structured logs, using a log set of interfaces called logr (https://godoc.org/github.com/go-logr/logr). While controller-runtime provides easy setup for using Zap (https://go.uber.org/zap, pkg/log/zap), you can provide any implementation of logr as the base logger for controller-runtime. Metrics (pkg/metrics) provided by controller-runtime are registered into a controller-runtime-specific Prometheus metrics registry. The manager can serve these by an HTTP endpoint, and additional metrics may be registered to this Registry as normal. You can easily build integration and unit tests for your controllers and webhooks using the test Environment (pkg/envtest). This will automatically stand up a copy of etcd and kube-apiserver, and provide the correct options to connect to the API server. It's designed to work well with the Ginkgo testing framework, but should work with any testing setup. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support This example creates a simple application Controller that is configured for ReplicaSets and Pods. This application controller will be running leader election with the provided configuration in the manager options. If leader election configuration is not provided, controller runs leader election with default values. Default values taken from: https://github.com/kubernetes/apiserver/blob/master/pkg/apis/config/v1alpha1/defaults.go * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package `di` implements basic dependency injection (DI) container.
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package inject provides utilities for mapping and injecting dependencies in various ways.
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
package goject provides a reflect based injector. A large application built with dependency injection in mind will typically involve the boring work of setting up the object Container. This library attempts to take care of this boring work by creating and connecting the various objects. Its use involves you seeding the object Container with some (possibly incomplete) objects, where the underlying types have been tagged for injection. Given this, the library will populate the objects creating new ones as necessary. It uses singletons by default, supports optional private instances as well as named instances. It works using Go's reflection package and is inherently limited in what it can do as opposed to a code-gen system with respect to private fields. The usage pattern for the library involves struct tags. It requires the tag format used by the various standard libraries, like json, xml etc. It involves tags in one of the three forms below: The first no value syntax is for the common case of a singleton dependency of the associated type. The second triggers creation of a private instance for the associated type. Finally the last form is asking for a named dependency called "dev logger".
Dependency Injection by annotations for Golang https://github.com/lokstory/digo
Package godi implements a small and lightweight container used for dependency injection without code generation. Its main component is the Container interface, which can be instantiated with NewContainer. Now dependencies can be bound to the container either instantiating or as a singleton and queried form the Container's ResolverFunc. It's recommended to pass the Container's ResolverFunc with the context of your application, allowing you to access the dependency injection container easily.
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package fx is a framework that makes it easy to build applications out of reusable, composable modules. Fx applications use dependency injection to eliminate globals without the tedium of manually wiring together function calls. Unlike other approaches to dependency injection, Fx works with plain Go functions: you don't need to use struct tags or embed special types, so Fx automatically works well with most Go packages. Basic usage is explained in the package-level example below. If you're new to Fx, start there! Advanced features, including named instances, optional parameters, and value groups, are explained under the In and Out types. To test functions that use the Lifecycle type or to write end-to-end tests of your Fx application, use the helper functions and types provided by the go.uber.org/fx/fxtest package.
/ A dependency injection library for Go. / / This library provides the `Injector` type that is used for providing values and / after being configured with a collection of `Module`-s. / The library also provides iinterfaces for defining modules both from structs with provider methods and / dynamically generated providers.
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package wrap creates a fast and flexible middleware stack for http.Handlers. Each middleware is a wrapper for another middleware and implements the Wrapper interface. Features Wrappers can be found at http://godoc.org/github.com/go-on/wrap-contrib/wraps. A (mountable) router that plays fine with wrappers can be found at http://godoc.org/github.com/go-on/router. Benchmarks (Go 1.3) Initial inspiration came from Christian Neukirchen's rack for ruby some years ago. The core of this package is the New function that constructs a stack of middlewares that implement the Wrapper interface. If the global DEBUG flag is set before calling New then each middleware call will result in calling the Debug method of the global DEBUGGER (defaults to a logger). To help constructing middleware there are some adapters like WrapperFunc, Handler, HandlerFunc, NextHandler and NextHandlerFunc each of them adapting to the Wrapper interface. To help sharing per request context there is a Contexter interface that must be implemented by the ResponseWriter. That can easily be done be providing a middleware that injects a context that wraps the current ResponseWriter and implements the Contexter interface. It must a least support the extraction of the wrapped ResponseWriter. Then there are functions to validate implementations of Contexter (ValidateContextInjecter) and to validate them against wrappers that store and retrieve the context data (ValidateWrapperContexts). An complete example for shared contexts can be found in the file example_context_test.go. Furthermore this package provides some ResponseWriter wrappers that also implement Contexter and that help with development of middleware. These are Buffer, Peek and EscapeHTML. Buffer is a simple buffer. A middleware may pass it to the next handlers ServeHTTP method as a drop in replacement for the response writer. After the ServeHTTP method is run the middleware may examine what has been written to the Buffer and decide what to write to the "original" ResponseWriter (that may well be another buffer passed from another middleware). The downside is the body being written two times and the complete caching of the body in the memory which will be inacceptable for large bodies. Therefor Peek is an alternative response writer wrapper that only caching headers and status code but allowing to intercept calls of the Write method. All middleware without the need to read the whole response body should use Peek or provide their own ResponseWriter wrapper (then do not forget to implement the Contexter interface). Finally EscapeHTML provides a response writer wrapper that allows on the fly html escaping of the bytes written to the wrapped response writer. It is pretty easy to write your custom middleware. You should start with a new struct type - that allows you to add options as fields later on. Then you could use the following template to implement the Wrapper interface If you need to run the next handler in order to inspect what it did, replace the response writer with a Peek (see NewPeek) or if you need full access to the written body with a Buffer. To form a middleware stack, simply use New() and pass it the middlewares. They get the request top-down. There are some adapters to let for example a http.Handler be a middleware (Wrapper) that does not call the next handler and stops the chain. To use per request context a custom type is needed that carries the context data and the user is expected to create and inject a Contexter supporting this type. Here is a template for a middleware that you could use to write middleware that wants to use / share context. For context sharing the user has to implement the Contexter interface in a way that supports all types the used middlewares expect. Here is a template for an implementation of the Contexter interface At any time there must be only one Contexter in the whole middleware stack and its the best to let it be the first middleware. Then you don't have to worry if its there or not (the Stack function might help you). The corresponding middleware stack would look like this If your application / handler also uses context data, it is a good idea to implement it as ContextWrapper as if it were a middleware and pass it ValidateWrapperContexts(). So if your context is wrong, you will get nice panics before your server even starts. And this is always in sync with your app / middleware. If for some reason the original ResponseWriter is needed (to type assert it to a http.Flusher for example), it may be reclaimed with the help of ReclaimResponseWriter(). You might want to look at existing middlewares to get some ideas: http://godoc.org/github.com/go-on/wrap-contrib/wraps 1. Should the context not better be an argument to a middleware function, to make this dependency visible in documentation and tools? Answer: A unified interface gives great freedom when organizing and ordering middleware as the middleware in between does not have to know about a certain context type if does not care about it. It simply passes the ResponseWriter that happens to have context down the middleware stack chain. On the other hand, exposing the context type by making it a parameter has the effect that every middleware will need to pass this parameter to the next one if the next one needs it. Every middleware is then tightly coupled to the next one and reordering or mixing of middleware from different sources becomes impossible. However with the ContextHandler interface and the ValidateWrapperContexts function we have a way to guarantee that the requirements are met. And this solution is also type safe. 2. A ResponseWriter is an interface, because it may implement other interfaces from the http libary, e.g. http.Flusher. If it is wrapped that underlying implementation is not accessible anymore Answer: When the Contexter is validated, it is checked, that the Context method supports http.ResponseWriter as well (and that it returns the underlying ResponseWriter). Since only one Contexter may be used within a stack, it is always possible to ask the Contexter for the underlying ResponseWriter. This is what helper functions like ReclaimResponseWriter(), Flush(), CloseNotify() and Hijack() do. 3. Why is the recommended way to use the Contexter interface to make a type assertion from the ResponseWriter to the Contexter interface without error handling? Answer: Middleware stacks should be created before the server is handling requests and then not change anymore. And you should run tests. Then the assertion will blow up and that is correct because there is no reasonable way to handle such an error. It means that either you have no context in your stack or you inject the context to late or the context does not handle the kind of type the middleware expects. In each case you should fix it early and the panic forces you to do. Use the DEBUG flag to see what's going on. 4. What happens if my context is wrapped inside another context or response writer? Answer: You should only have one Contexter per application and inject it as first wrapper into your middleware stack. All context specific data belongs there. Having multiple Contexter in a stack is considered a bug. The good news is that you now can be sure to be able to access all of your context data everywhere inside your stack. Never should a context wrap another one. There also should be no need for another context wrapping ResponseWriter because every type can be saved by a Contexter with few code. All response writer wrappers of this package implement the Contexter interface and every response writer you use should. 5. Why isn't there any default context object? Why do I have to write it on my own? Answer: To write your own context and context injection has several benefits: 6. Why is the context data accessed and stored via type switch and not by string keys? Answer: Type based context allows a very simple implementation that namespaces across packages needs no extra memory allocation and is, well, type safe. If you need to store multiple context data of the same type, simple defined an alias type for each key. 7. Is there an example how to integrate with 3rd party middleware libraries that expect context? Answer: Yes, have a look at http://godoc.org/github.com/go-on/wrap-contrib/third-party. 8. What about spawning goroutines / how does it relate to code.google.com/p/go.net/context? If you need your request to be handled by different goroutines and middlewares you might use your Contexter to store and provide access to a code.google.com/p/go.net/context Context just like any other context data. The good news is that you can write you middleware like before and extract your Context everywhere you need it. And if you have middleware in between that does not know about about Context or other context data you don't have build wrappers around that have Context as parameter. Instead the ResponseWriter that happens to provide you a Context will be passed down the chain by the middleware. "At Google, we require that Go programmers pass a Context parameter as the first argument to every function on the call path between incoming and outgoing requests." (Sameer Ajmani, http://blog.golang.org/context) This is not neccessary anymore. And it is not neccessary for any type of contextual data because that does not have to be in the type signature anymore.
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package crypto wraps the crypto/rand package making it easier to use with type oriented dependency injection frameworks.
Package pg provides opinionated Postgres types and providers for setting up Postgres DB connections using dependency injection.
Package xstats is a generic client for service instrumentation. xstats is inspired from Go-kit's metrics (https://github.com/go-kit/kit/tree/master/metrics) package but it takes a slightly different path. Instead of having to create an instance for each metric, xstats use a single instance to log every metrics you want. This reduces the boiler plate when you have a lot a metrics in your app. It's also easier in term of dependency injection. Talking about dependency injection, xstats comes with a xhandler.Handler integration so it can automatically inject the xstats client within the net/context of each request. Each request's xstats instance have its own tags storage ; This let you inject some per request contextual tags to be included with all observations sent within the lifespan of the request. xstats is pluggable and comes with integration for StatsD and DogStatsD, the Datadog (http://datadoghq.com) augmented version of StatsD with support for tags. More integration may come later (PR welcome).
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Package goneedle - dependency injection package for golang. goneedle makes bootstrap of an app much easier. Using a straight forward API that should easily integrate with existing code. goneedle also helps with graceful start and graceful shutdown by adding life cycle API for dependencies, allowing releasing resources in easy and safe way Injectable is an instance that can be injected as dependency to another and be dependent on other injectables in order to declare injectable, an injectable must expose it's dependencies and what it returns using a provider. A provider is a function, that the arguments are the dependency and the return type is what it provides Provider can also return an error Provider can also return multiple types Store is a place that stores all the injectables, life cycles and initializes them. Your story with goneedle starts with assume the following providers: Add them them to the store, notice the order of adding injectables doesn't matter since goneedle resolve the dependency graph and decides on initialization order initialize all the injectables Retrieve the initialized values: Some notes: • Lazy initialization is possible, calling Store#With before Store#Initialize will initialize only the params the provided callback expects • It is possible to add on-construction and on-destruction hooks, allowing to start a service and shutdown gracefully. see examples or docs • Most of the Store methods may return an error (see each method doc for possible errors), for all of these methods there is another method with Must prefix that will panic if error, but allows chaining. e.g Store#MustAddInjectable() • See the examples folder since it contain full usage examples
Package iris implements the highest realistic performance, easy to learn Go web framework. Iris provides a beautifully expressive and easy to use foundation for your next website, API, or distributed app. Low-level handlers compatible with `net/http` and high-level fastest MVC implementation and handlers dependency injection. Easy to learn for new gophers and advanced features for experienced, it goes as far as you dive into it! Source code and other details for the project are available at GitHub: 12.1.8 The only requirement is the Go Programming Language, at least version 1.13. Wiki: Examples: Middleware: Home Page:
Package di helps implement Dependency Injection for web development. Dependency Injection aims to make dependencies accessible to its clients without them having to construct or ask for their dependencies explicitly. This raises the questions di uses factories to isolate dependency construction and make them available via struct fields. This makes them accessible to code that uses them residing in methods on those structs. To that end di provides the types Dispatcher, Binding and interfaces ApplicationFactory, RequestFactory, Controller and Router. A Controller represents a type whose methods can serve HTTP requests and exports Bindings. A Binding specifies binds an HTTP request with a specific <Verb,Path> to a method on that Controller. A Controller can be registered with a Dispatcher teaching it how to route requests. ApplicationFactory and RequestFactory encapsulate all object construction including Controllers. Dispatcher uses the factories to get hold of a Controller object for the request and call the appropriate method. The Dispatcher uses a Router to handle request multiplexing. The flow of control while serving requests looks like The example demonstrates how to wire everything up.
Package wire is runtime depedency injection/wiring for golang. It's designed to be strict to avoid your go application running without proper dependency injected.
Package alice provides an additive dependency injection container.
Package controllerruntime alias' common functions and types to improve discoverability and reduce the number of imports for simple Controllers. This example creates a simple application Controller that is configured for ReplicaSets and Pods. * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler. * Start the application. TODO(pwittrock): Update this example when we have better dependency injection support
Director contains a few common loop flow control patterns that can be dependency-injected, generally to simplify running goroutines forever in the backround. It has a single interface and a few implementations of the interface. The externalization of the loop flow control makes it easy to test the internal functions of background goroutines by, for instance, only running the loop once while under test. The design is that any errors which need to be returned from the loop will be passed back on a DoneChan whose implementation is left up to the individual Looper.