<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Golang on Osmar Petry</title><link>https://osmarpetry.dev/tags/golang/</link><description>Recent content in Golang on Osmar Petry</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Sun, 01 Jun 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://osmarpetry.dev/tags/golang/rss.xml" rel="self" type="application/rss+xml"/><item><title>Domain-Driven, Data-Oriented Design (DDDOD)</title><link>https://osmarpetry.dev/blog/dddod/</link><pubDate>Sun, 01 Jun 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/dddod/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;&#10;&lt;p&gt;Bill Kennedy adapts Domain-Driven Design principles to Go by emphasising data flow and simplicity. DDDOD keeps the focus on reliable data transformations while preserving idiomatic Go patterns.&lt;/p&gt;&#10;&lt;h2 id="why-not-pure-ddd"&gt;Why not pure DDD?&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Traditional DDD can introduce excessive abstraction and ceremony in Go projects.&lt;/li&gt;&#10;&lt;li&gt;Too many layers and interfaces obscure intent, reducing maintainability.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="core-pillars"&gt;Core pillars&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Data-oriented design&lt;/strong&gt;: prioritise data models and their transformations; ensure data can cross layers safely.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Validation &amp;amp; trust&lt;/strong&gt;: embed validation logic early; fail fast to maintain integrity.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Structured layers&lt;/strong&gt;: app → business → storage; each layer defines clear contracts and side-effects.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Domain isolation&lt;/strong&gt;: separate bounded contexts to prevent accidental coupling and cascading failures.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="implementation-tips"&gt;Implementation tips&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Use packages to reflect domains (&lt;code&gt;internal/user&lt;/code&gt;, &lt;code&gt;internal/auth&lt;/code&gt;); avoid grab-bag packages like &lt;code&gt;common&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Expose only necessary APIs; keep implementation details private.&lt;/li&gt;&#10;&lt;li&gt;Guard entry points with validation and logging to catch anomalies early.&lt;/li&gt;&#10;&lt;li&gt;Leverage functional options or constructors to initialize services with dependencies explicitly.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="references"&gt;References&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Bill Kennedy, “Domain-Driven, Data-Oriented Design” talk and articles (Ardan Labs).&lt;/li&gt;&#10;&lt;li&gt;Ardan Labs Service repository as a starter kit: &lt;a href="https://github.com/ardanlabs/service" target="_blank" rel="noreferrer"&gt;https://github.com/ardanlabs/service&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related-notes"&gt;Related Notes&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;[[ddd|Domain-Driven Design: Tackling Complexity in the Heart of Software]]&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Gophers 2025 — Event Report</title><link>https://osmarpetry.dev/blog/gophers-2025-event/</link><pubDate>Tue, 20 May 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/gophers-2025-event/</guid><description>&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;&#10;&lt;p&gt;Gophers 2025 brought the Go community together in Anita Garibaldi, Santa Catarina, for two full days of talks, panels, and hands-on workshops. Sessions ranged from organizational culture and dependency-injection strategies to Kubernetes tuning, automation, game development with Ebiten, and end-to-end observability. This report consolidates every note found in the &lt;code&gt;Gophers 2025/&lt;/code&gt; directory into a single English-language document. It follows the event chronologically and highlights technical takeaways, workshop content, a real-world case study, and concrete action items.&lt;/p&gt;</description></item><item><title>Go Serialization Options</title><link>https://osmarpetry.dev/blog/go-serialization-options/</link><pubDate>Mon, 12 May 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/go-serialization-options/</guid><description>&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;&#10;&lt;p&gt;Go types can expose custom wire formats through &lt;code&gt;encoding/json&lt;/code&gt; and related packages. The main choices are &lt;code&gt;MarshalText&lt;/code&gt; / &lt;code&gt;UnmarshalText&lt;/code&gt;, &lt;code&gt;MarshalJSON&lt;/code&gt; / &lt;code&gt;UnmarshalJSON&lt;/code&gt;, or explicit helper functions. Each option trades off convenience, control, and complexity.&lt;/p&gt;&#10;&lt;h2 id="1-marshaltext--unmarshaltext"&gt;1. &lt;code&gt;MarshalText&lt;/code&gt; / &lt;code&gt;UnmarshalText&lt;/code&gt;&lt;/h2&gt;&#10;&lt;p&gt;Implements &lt;code&gt;encoding.TextMarshaler&lt;/code&gt; and &lt;code&gt;encoding.TextUnmarshaler&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;This converts values to plain text. JSON, XML, and other encoders automatically use it when a custom JSON marshaler is absent.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;MarshalText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="nb"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;UnmarshalText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#9;&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="2-marshaljson--unmarshaljson"&gt;2. &lt;code&gt;MarshalJSON&lt;/code&gt; / &lt;code&gt;UnmarshalJSON&lt;/code&gt;&lt;/h2&gt;&#10;&lt;p&gt;Implements &lt;code&gt;json.Marshaler&lt;/code&gt; and &lt;code&gt;json.Unmarshaler&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Package Oriented Design</title><link>https://osmarpetry.dev/blog/pod-go/</link><pubDate>Mon, 12 May 2025 00:00:00 +0000</pubDate><guid>https://osmarpetry.dev/blog/pod-go/</guid><description>&lt;h2 id="summary"&gt;Summary&lt;/h2&gt;&#10;&lt;p&gt;Bill Kennedy’s Package Oriented Design (POD) emphasises starting and ending architectural decisions at the package level. Each package should provide a focused solution for a domain problem to keep code composable, testable, and maintainable.&lt;/p&gt;&#10;&lt;h2 id="definition"&gt;Definition&lt;/h2&gt;&#10;&lt;p&gt;POD identifies where each package belongs and the design rules it follows. Packages act as the building blocks of Go applications, supporting composition and isolation.&lt;/p&gt;&#10;&lt;h2 id="guiding-philosophy"&gt;Guiding philosophy&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Purpose over storage:&lt;/strong&gt; packages should provide behaviour, not just hold utilities.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Encapsulation:&lt;/strong&gt; expose only necessary APIs and hide implementation details.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Portability:&lt;/strong&gt; a consistent package structure makes discussion and reuse easier across projects.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Layering:&lt;/strong&gt; organise code into purposeful layers, such as &lt;code&gt;kit&lt;/code&gt;, &lt;code&gt;application&lt;/code&gt;, and &lt;code&gt;service&lt;/code&gt;, with explicit interaction rules.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="benefits"&gt;Benefits&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Modularity:&lt;/strong&gt; domain-specific packages reduce unwanted coupling.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Maintainability:&lt;/strong&gt; clear responsibilities make testing and refactoring easier.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Scalability:&lt;/strong&gt; well-defined package boundaries support growth in complexity and team size.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="package-responsibilities"&gt;Package responsibilities&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Live in one place per domain, such as &lt;code&gt;internal/user&lt;/code&gt; or &lt;code&gt;internal/platform&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Provide a specific solution and avoid generic buckets like &lt;code&gt;common&lt;/code&gt; or &lt;code&gt;util&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Export only the API needed by consumers and keep implementation details private.&lt;/li&gt;&#10;&lt;li&gt;Name files to reflect behaviour so callers understand what the package delivers.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="layering-cheat-sheet"&gt;Layering cheat-sheet&lt;/h2&gt;&#10;&lt;h3 id="kit"&gt;&lt;code&gt;kit&lt;/code&gt;&lt;/h3&gt;&#10;&lt;p&gt;Shared libraries with zero dependency on application packages.&lt;/p&gt;</description></item></channel></rss>