<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ishan Khan</title>
    <description>The latest articles on DEV Community by Ishan Khan (@ishankhan21).</description>
    <link>https://dev.to/ishankhan21</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F354018%2Fc3d75be3-b00f-4c23-a8a3-703c95b6e931.png</url>
      <title>DEV Community: Ishan Khan</title>
      <link>https://dev.to/ishankhan21</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ishankhan21"/>
    <language>en</language>
    <item>
      <title>Go Context: Deep Dive</title>
      <dc:creator>Ishan Khan</dc:creator>
      <pubDate>Fri, 31 Jul 2026 05:41:47 +0000</pubDate>
      <link>https://dev.to/ishankhan21/go-context-deep-dive-34oa</link>
      <guid>https://dev.to/ishankhan21/go-context-deep-dive-34oa</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;These notes are part of my personal learning process on Go's &lt;code&gt;context&lt;/code&gt; package and its usages — not an AI-generated blog written for the sake of it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What is context?
&lt;/h2&gt;

&lt;p&gt;In Golang, &lt;code&gt;context.Context&lt;/code&gt; is an inbuilt package used majorly for the following reasons in concurrent systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cancel&lt;/strong&gt; work when it's no longer needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set deadlines/timeouts&lt;/strong&gt; so work doesn't run forever.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass request-scoped values&lt;/strong&gt; (like a trace ID) across API boundaries — e.g., logged-in user metadata, sharing small data values.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Golang has made &lt;code&gt;context&lt;/code&gt; an &lt;strong&gt;explicit, first-class convention&lt;/strong&gt; in the language, so people don't need to create their own abstractions and patterns for these requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why don't other languages (Java, Python, Node.js, etc.) have something like context?
&lt;/h2&gt;

&lt;p&gt;Every backend language — Java, Python, Node.js, etc. — has one or another mechanism for handling the behaviours addressed by &lt;code&gt;context&lt;/code&gt; in Go (thread locals, async locals, cancellationtokens, futures, etc.). Go simply chose to standardize it into a single, explicit type that flows through function signatures.&lt;/p&gt;

&lt;h2&gt;
  
  
  The core Context interface
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// A Context carries a deadline, cancellation signal, and request-scoped values&lt;/span&gt;
&lt;span class="c"&gt;// across API boundaries. Its methods are safe for simultaneous use by multiple&lt;/span&gt;
&lt;span class="c"&gt;// goroutines.&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Done returns a channel that is closed when this Context is canceled&lt;/span&gt;
    &lt;span class="c"&gt;// or times out.&lt;/span&gt;
    &lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="c"&gt;// Err indicates why this context was canceled, after the Done channel&lt;/span&gt;
    &lt;span class="c"&gt;// is closed.&lt;/span&gt;
    &lt;span class="n"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;

    &lt;span class="c"&gt;// Deadline returns the time when this Context will be canceled, if any.&lt;/span&gt;
    &lt;span class="n"&gt;Deadline&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;deadline&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Value returns the value associated with key or nil if none.&lt;/span&gt;
    &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The context package provides functions to derive new &lt;code&gt;Context&lt;/code&gt; values from existing ones. These values form a &lt;strong&gt;tree&lt;/strong&gt;: when a Context is canceled, all Contexts derived from it arealso canceled.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Background&lt;/code&gt; is the root of any Context tree; it is never canceled:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Background returns an empty Context. It is never canceled, has no deadline,&lt;/span&gt;
&lt;span class="c"&gt;// and has no values. Background is typically used in main, init, and tests,&lt;/span&gt;
&lt;span class="c"&gt;// and as the top-level Context for incoming requests.&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fchuevt4gzhvcalu0h5bx.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fchuevt4gzhvcalu0h5bx.gif" alt="Nested context behaviour" width="680" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;context.Background()&lt;/code&gt; vs &lt;code&gt;context.TODO()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Both create an empty context and behave identically at runtime — the difference is purely &lt;strong&gt;semantic intent&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;context.Background()&lt;/code&gt;&lt;/strong&gt; — Use when you are &lt;em&gt;intentionally&lt;/em&gt; starting a root context, i.e., you know this is the top of your context tree.

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Example:&lt;/em&gt; the &lt;code&gt;main&lt;/code&gt; function of a server, the root of a controller, the start of a background worker, or a long-running goroutine.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;context.TODO()&lt;/code&gt;&lt;/strong&gt; — Use as a placeholder when you're unsure which context to use for now, but a proper context &lt;em&gt;definitely&lt;/em&gt; should flow through the execution chain later.

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Example:&lt;/em&gt; you're mid-refactor, the caller doesn't pass a context yet but should, or you're unsure which context to use.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Usage Examples
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;API servers / data jobs&lt;/strong&gt; — Each request is typically handled by a new goroutine. During the lifecycle of a request you may need to make downstream API calls, so &lt;code&gt;context&lt;/code&gt; can be used to time out the request if the downstream API doesn't respond within its SLA. You can also pass small request-scoped data through the context (logged-in user ID, name, APM tracedata, etc.). If the request lifecycle spawns more goroutines for parallel operations, the same context can be used to signal cancellation to those child goroutines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenTelemetry instrumentation&lt;/strong&gt; — Go's OTEL libraries follow correct context patterns very efficiently. Regardless of the framework — Echo, &lt;code&gt;net/http&lt;/code&gt;, Gorilla Mux, gRPC, etc. —the OTEL middleware hooks into every incoming request, reads trace propagation data from the HTTP headers, and derives a new context with the remote trace information and a newserver-side span embedded into it. As the request flows through the handler and triggers downstream calls (DBs, external APIs), each call derives yet another child context with a newchild span attached to the parent trace. At no point is any context mutated — every step is a new immutable derived context, forming a chain that mirrors the trace tree.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Functions
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;context.Background()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Root context — never cancelled, no values, no deadline. Entry point for all context trees.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;context.TODO()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Placeholder root — identical to &lt;code&gt;Background()&lt;/code&gt; at runtime, signals intent to replace later.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;context.WithValue(parent, key, val)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Derives a new context embedding a key-value pair. No cancellation behaviour.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;context.WithCancel(parent)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Derives a child that is cancelled when &lt;code&gt;cancel()&lt;/code&gt; is called or the parent is cancelled.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;context.WithDeadline(parent, time.Time)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cancels at an absolute point in time, or when &lt;code&gt;cancel()&lt;/code&gt; is called.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;context.WithTimeout(parent, duration)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sugar over &lt;code&gt;WithDeadline&lt;/code&gt; — takes a duration instead of an absolute time.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;context.WithCancelCause(parent)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Like &lt;code&gt;WithCancel&lt;/code&gt;, but &lt;code&gt;cancel(err)&lt;/code&gt; attaches a cause retrievable via &lt;code&gt;context.Cause(ctx)&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;context.WithDeadlineCause(parent, time.Time, err)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Like &lt;code&gt;WithDeadline&lt;/code&gt;, but attaches a cause error when the deadline fires.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;context.WithTimeoutCause(parent, duration, err)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Like &lt;code&gt;WithTimeout&lt;/code&gt;, but attaches a cause error when the timeout fires.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;context.WithoutCancel(parent)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Derives a context that is never cancelled but inherits all values from the parent. Useful for detaching background tasks from the requestlifecycle.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;context.AfterFunc(ctx, f)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Schedules &lt;code&gt;f&lt;/code&gt; to run in a new goroutine after &lt;code&gt;ctx&lt;/code&gt; is cancelled. Does not create a new context.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Memory management
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Allocation — where contexts live
&lt;/h3&gt;

&lt;p&gt;Context values almost always escape to the heap rather than living on the stack. The Go compiler determines this via escape analysis, and contexts consistently fail to stay on the stack for three reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They are passed as the Context interface, Interface boxing forces heap allocation&lt;/li&gt;
&lt;li&gt;They frequently cross goroutine boundaries&lt;/li&gt;
&lt;li&gt;The cancel closure returned by WithCancel/WithTimeout captures a pointer to the context, causing it to outlive the creating function&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The only exception is context.Background() and context.TODO() — these are package-level singletons allocated once at program startup in the data segment. Every call to them returns the same pointer, zero allocation. &lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;First parameter convention&lt;/strong&gt; — Context must always be the first parameter of any function that involves I/O or forwards request-scoped data. Conventionally named &lt;code&gt;ctx&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Immutability&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Always derive a new context from the previous one using the &lt;code&gt;WithX&lt;/code&gt; functions. This keeps context objects atomic — child functions or APIs can't screw them up by reference, and
it's much safer to use.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory management&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;WithCancel&lt;/code&gt; / &lt;code&gt;WithTimeout&lt;/code&gt; / &lt;code&gt;WithDeadline&lt;/code&gt; &lt;strong&gt;must always&lt;/strong&gt; be paired with &lt;code&gt;defer cancel()&lt;/code&gt;, otherwise you're trading memory for convenience (goroutine/timer leaks until the
parent is cancelled).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pkg.go.dev/context" rel="noopener noreferrer"&gt;https://pkg.go.dev/context&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://go.dev/blog/context" rel="noopener noreferrer"&gt;https://go.dev/blog/context&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>programming</category>
      <category>backenddevelopment</category>
    </item>
    <item>
      <title>Go dependency injection with Uber Fx and Echo</title>
      <dc:creator>Ishan Khan</dc:creator>
      <pubDate>Sat, 23 Nov 2024 09:49:08 +0000</pubDate>
      <link>https://dev.to/ishankhan21/go-dependency-injection-with-uber-fx-and-echo-5cl1</link>
      <guid>https://dev.to/ishankhan21/go-dependency-injection-with-uber-fx-and-echo-5cl1</guid>
      <description>&lt;p&gt;In this post we will go through how to use Uber Fx for dependency injection/singletons with Echo Web framework.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Are Singletons and Dependency Injection Important?&lt;/strong&gt;&lt;br&gt;
Singletons and dependency injection are very important while working with complex backend services, Singletons are important for resource efficiency, thread safety, ex. you cannot create new DB connections for every DB query etc. Dependency injection is useful for creating loosely coupled, testable and flexible code which can be easily extended.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/uber-go/fx" rel="noopener noreferrer"&gt;Uber Fx&lt;/a&gt; is a dependency injection framework for golang build by Uber which is integrated in all the golang services in Uber to have uniform structure of code across services, code reuse is easier and makes servers efficient. &lt;br&gt;
&lt;a href="https://echo.labstack.com/" rel="noopener noreferrer"&gt;Echo&lt;/a&gt; is one of the most popular go webserver framework known for being high performant, extensible and minimalist. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Case Study: Order Management Service:&lt;/strong&gt;&lt;br&gt;
Suppose we have a hypothetical Order Management Service, Where have couple of endpoints to fetch user profile details, users orders, order details etc. &lt;br&gt;
The service interacts with multiple databases like MogoDB, Reids, MySQL and other components like Logger, Configuration Loader, HTTP/GRPC Client Services, Other Application Modules/Services(each with its dependencies).&lt;br&gt;
&lt;em&gt;&lt;strong&gt;Challenge:&lt;/strong&gt;&lt;/em&gt; These modules rely on shared resources like database connections, logger, HTTP clients etc, Managing them manually initializing, sharing, and wiring dependencies can quickly become overwhelming. Also ensuring all the dependencies are singletons across the project adds another layer of complexity. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fblw77xzzq3j1m4v8ygmm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fblw77xzzq3j1m4v8ygmm.png" alt="Dependencies structure" width="800" height="409"&gt;&lt;/a&gt;&lt;br&gt;
Manual initialisations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func main(){
    redisConenction := db.GetRedisconnection()
    mongoConnection := db.GetMongoConnection()

    orderService := services.NewOrderService(redisConenction, mongoConnection)
    userService := services.NewUserService(redisConenction, mongoConnection, orderService)
    // Other Services...

    // Init controllers
    userController := controllers.NewUserController(userService)
    // Other controller...

    StartEchoServer(controllers)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Below is the code snippet required to creating all the services with UberFx.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import (
    "github.com/Ishankhan21/go-fiber-fx/controllers"
    "github.com/Ishankhan21/go-fiber-fx/db"
    "github.com/Ishankhan21/go-fiber-fx/services"
    "go.uber.org/fx"
)

func main() {
    fx.New(
        fx.Provide(
            db.GetRedisconnection,
            db.GetMongoConnection,
            services.NewUserService,
            services.NewOrderService,
            controllers.NewUserController),
        fx.Invoke(StartEchoServer)).Run()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full Code in &lt;a href="https://github.com/Ishankhan21/go-echo-fx/tree/master" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementation Steps:&lt;/strong&gt;&lt;br&gt;
1.Define Constructors: Create constructors for your dependencies, such as database connections, logger, and HTTP clients.&lt;br&gt;
2.Integrate Uber Fx: Register these constructors with Uber Fx and let it handle initialization and injection.&lt;br&gt;
3.Use Dependencies in Handlers: In your Echo handlers, Uber Fx automatically injects the required dependencies.&lt;/p&gt;

&lt;p&gt;Wrapping Up:&lt;br&gt;
By combining Uber Fx with Echo, you can build clean, maintainable, and scalable backend services. Uber Fx handles the complexity of dependency management, allowing you to focus on writing business logic rather than wiring dependencies manually.&lt;/p&gt;

&lt;p&gt;References: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/uber-go/fx" rel="noopener noreferrer"&gt;https://github.com/uber-go/fx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=LDGKQY8WJEM" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=LDGKQY8WJEM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=nLskCRJOdxM" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=nLskCRJOdxM&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>dependencyinjection</category>
      <category>uberfx</category>
      <category>designpatterns</category>
    </item>
  </channel>
</rss>
