<?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: Aaron Saikovski</title>
    <description>The latest articles on DEV Community by Aaron Saikovski (@aaronsaikovski).</description>
    <link>https://dev.to/aaronsaikovski</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1227807%2F4afd5369-df1c-4828-acf8-e7fe2b082cf9.jpeg</url>
      <title>DEV Community: Aaron Saikovski</title>
      <link>https://dev.to/aaronsaikovski</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aaronsaikovski"/>
    <language>en</language>
    <item>
      <title>Daleks - in Go and Ebitengine and Webassembly</title>
      <dc:creator>Aaron Saikovski</dc:creator>
      <pubDate>Fri, 08 Aug 2025 00:47:58 +0000</pubDate>
      <link>https://dev.to/aaronsaikovski/daleks-1984-in-go-and-ebitengine-and-webassemby-7nh</link>
      <guid>https://dev.to/aaronsaikovski/daleks-1984-in-go-and-ebitengine-and-webassemby-7nh</guid>
      <description>&lt;p&gt;Ive tried to recreate a faithful version of the 1984 Classic Mac game Daleks. &lt;br&gt;
I loved his game as a kid and wanted to try to create it using Webassembly, Go and Ebitengine.&lt;/p&gt;

&lt;p&gt;The source code is here: &lt;a href="https://github.com/AaronSaikovski/godaleks" rel="noopener noreferrer"&gt;https://github.com/AaronSaikovski/godaleks&lt;/a&gt;&lt;br&gt;
A playable version is available here: &lt;a href="https://aaronsaikovski.github.io/godaleks" rel="noopener noreferrer"&gt;https://aaronsaikovski.github.io/godaleks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All rights to their respective owners.&lt;/p&gt;

&lt;p&gt;Please be gentle as its very much an alpha version.&lt;br&gt;
keen to hear your feedback!&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%2Fg9l0fp3ish3k72o7vods.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%2Fg9l0fp3ish3k72o7vods.png" alt=" " width="676" height="927"&gt;&lt;/a&gt;&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%2Fjn0nddcu07m9kaz0ks71.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%2Fjn0nddcu07m9kaz0ks71.png" alt=" " width="800" height="598"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>webassembly</category>
      <category>gamedev</category>
      <category>ebitengine</category>
    </item>
    <item>
      <title>How to query your GoodWe Solar inverter API using GoLang.</title>
      <dc:creator>Aaron Saikovski</dc:creator>
      <pubDate>Mon, 19 Feb 2024 04:25:46 +0000</pubDate>
      <link>https://dev.to/aaronsaikovski/how-to-query-your-goodwe-solar-inverter-api-using-golang-1ffg</link>
      <guid>https://dev.to/aaronsaikovski/how-to-query-your-goodwe-solar-inverter-api-using-golang-1ffg</guid>
      <description>&lt;p&gt;Over the past few months I have been doing more and more GoLang development for my side projects and and I have come to the conclusion that Go strikes a very nice balance of productivity and performance. &lt;br&gt;
The binaries that Go produces eliminates the need for JVMs or runtime frameworks that need to be shipped with your application. Everything you need to run your application is in a single native compiled binary. &lt;br&gt;
As a side note I did have a quick look at Rust as an option too but decided to settle on Go for this project. (I am not a Rust developer and might look at it in the future).&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Project Background&lt;/u&gt;&lt;br&gt;
Late 2023 I was thinking of a cool project to stretch my Go development skills a bit and came across &lt;a href="https://binodmx.medium.com/accessing-the-goodwe-sems-portal-api-a-comprehensive-guide-296e0431c285" rel="noopener noreferrer"&gt;this&lt;/a&gt; article. &lt;br&gt;
I thought that I could come up with good solution written in Go to query my solar inverter API and present some meaningful &lt;br&gt;
reporting data. &lt;br&gt;
People asked me why? Because its a good way to learn how to query APIs and manipulate JSON results in Go. Thats why!&lt;br&gt;
After lots of extensive research and looking at other open source projects I found on Github &lt;a href="https://github.com/topics/goodwe" rel="noopener noreferrer"&gt;here&lt;/a&gt;, most of which were in Python and were overly complex and required lots of external dependencies. I settled on writing this in Go.&lt;/p&gt;

&lt;p&gt;So after some trial and error and a few iterations I managed to come up with a Go based, command line utility to query my Goodwe/SEMs Solar inverter to query the APIs and return a JSON result of the measured inverter metrics. Sweet!&lt;br&gt;
One thing to note was the lack of any solid API documentation from the GooodWe APIs and as such a lot of trial and error was involved to get this to work. If you have any updated API documentation on how their APIs work please let me know. I couldn't find anything. :-(&lt;/p&gt;

&lt;p&gt;&lt;u&gt;The solution&lt;/u&gt;&lt;br&gt;
To achieve the desirted outcome, required two separate API calls and passing objects (structs in Go):&lt;br&gt;
1) Obtain a login token - Login to the SEMS Portal API - '&lt;a href="https://www.semsportal.com/api/v1/Common/CrossLogin" rel="noopener noreferrer"&gt;https://www.semsportal.com/api/v1/Common/CrossLogin&lt;/a&gt;'. &lt;br&gt;
The Go function signature looks something like this:&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="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LoginCredentials&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LoginCredentials&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LoginResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&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;2) Then using the login response struct from Step 1 (represented as a JSON Go struct) pass to the inverter API GetMonitorDetailByPowerstationId API here - 'v2/PowerStation/GetMonitorDetailByPowerstationId'.&lt;br&gt;
The Go function signature looks something like this:&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="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;FetchData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Account&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Password&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PowerStationID&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DailySummary&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) Then from the 'FetchData()' Go function a JSON object is returned.&lt;br&gt;
The internal Go function uses a 'interfaces.ISemsDataConstraint' interface constraint to restrict the datatypes to the two structs I defined in the types package:&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="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;ISemsDataConstraint&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InverterData&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DailySummaryData&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Internal Go function signature to get the monitor data is as follows - note the interface type constraint:&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="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;getMonitorData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;interfaces&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ISemsDataConstraint&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;LoginCredentials&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LoginCredentials&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LoginApiResponse&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LoginResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;InverterOutput&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are two output options - Detailed  output and a daily summary view. Use the '--dailysummary' flag to produce a daily summary.&lt;/p&gt;

&lt;p&gt;The struct for the daily summary data is as follows:&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="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;types&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;DailySummaryData&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Language&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"language"`&lt;/span&gt;
    &lt;span class="n"&gt;HasError&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt;   &lt;span class="s"&gt;`json:"hasError"`&lt;/span&gt;
    &lt;span class="n"&gt;Msg&lt;/span&gt;      &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"msg"`&lt;/span&gt;
    &lt;span class="n"&gt;Code&lt;/span&gt;     &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"code"`&lt;/span&gt;
    &lt;span class="n"&gt;Data&lt;/span&gt;     &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Kpi&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;MonthGeneration&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="s"&gt;`json:"month_generation"`&lt;/span&gt;
            &lt;span class="n"&gt;Power&lt;/span&gt;           &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="s"&gt;`json:"power"`&lt;/span&gt;
            &lt;span class="n"&gt;TotalPower&lt;/span&gt;      &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="s"&gt;`json:"total_power"`&lt;/span&gt;
            &lt;span class="n"&gt;DayIncome&lt;/span&gt;       &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="s"&gt;`json:"day_income"`&lt;/span&gt;
            &lt;span class="n"&gt;TotalIncome&lt;/span&gt;     &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="s"&gt;`json:"total_income"`&lt;/span&gt;
            &lt;span class="n"&gt;Currency&lt;/span&gt;        &lt;span class="kt"&gt;string&lt;/span&gt;  &lt;span class="s"&gt;`json:"currency"`&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="s"&gt;`json:"kpi"`&lt;/span&gt;
        &lt;span class="n"&gt;Inverter&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;TotalGeneration&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"total_generation"`&lt;/span&gt;
            &lt;span class="n"&gt;DailyGeneration&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"daily_generation"`&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="s"&gt;`json:"inverter"`&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="s"&gt;`json:"data"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main struct 'inverterdata' is too large to list here but its in the 'types' package &lt;a href="https://github.com/AaronSaikovski/gogoodwe/blob/main/cmd/gogoodwe/types/inverterdata.go" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The resulting output has had any sensitive data removed from the underlying structs so hopefully no usernames, addresses will be exposed.&lt;/p&gt;

&lt;p&gt;The Go project layout has gone through a few refactors as well and I think I have settled on a sensible project and package layout. Hit me up if you agree/disagree.&lt;/p&gt;

&lt;p&gt;Some of the big benefits and lessons learned during writing this are&lt;br&gt;
1) Go is awesome at building cross platform/single native binaries with no external runtimes.&lt;br&gt;
2) Produces really clean and easy to read code.&lt;br&gt;
3) Go has really fast performance from compile to runtime.&lt;br&gt;
4) Using some of the advanced Go features such as structs, JSON marshalling, Interfaces and constraints was a learning curve but I think I managed to get my head around these.&lt;br&gt;
5) Pointers in Go are awesome! I used them a lot in this project to pass memory references to structs around and update them by marhalling to JSON.&lt;br&gt;
6) Don't be afraid to refactor your folder and package layouts a few times. I think I did it about five times before I settled on the current layout.&lt;br&gt;
7) Use interfaces and constraints to reduce the amount of code you need to write.&lt;/p&gt;

&lt;p&gt;I hope you enjoy exploring this this tool as much as I enjoyed writing it. &lt;br&gt;
Please feel free to provide any feedback and suggestions on how I can make the code better, or if there are any bugs, please report them &lt;a href="https://github.com/AaronSaikovski/gogoodwe/issues" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The code itself can be found &lt;a href="https://github.com/AaronSaikovski/gogoodwe" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>solar</category>
      <category>goodwe</category>
      <category>go</category>
      <category>api</category>
    </item>
    <item>
      <title>Its 2024 and its time for a look at your Web API Tech Stack.</title>
      <dc:creator>Aaron Saikovski</dc:creator>
      <pubDate>Mon, 08 Jan 2024 06:00:09 +0000</pubDate>
      <link>https://dev.to/aaronsaikovski/its-2024-and-its-time-for-a-look-at-your-web-api-tech-stack-2im7</link>
      <guid>https://dev.to/aaronsaikovski/its-2024-and-its-time-for-a-look-at-your-web-api-tech-stack-2im7</guid>
      <description>&lt;p&gt;Hello everyone, this is my first post for 2024 and I hope you all had a great break. &lt;br&gt;
Over the break I was thinking about some of the technologies I wanted to sink my teeth into in 2024. &lt;br&gt;
The main two I will be focussing on are .Net Core 8 and Go. &lt;br&gt;
For a full stack platform .Net/.Net Core is hard to beat and for pure backend API development you really can't beat Go.&lt;br&gt;
When I was looking at some key features for any API development in .Net Core and Go I came up with this list that I thought I would share:&lt;br&gt;
I have broken this down into a .Net Core Web API Vs. Go list with supporting links.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Native compilation&lt;/strong&gt; or as close to native compiled - Go Wins here. Although .Net 8 has AOT (Ahead of Time) compilation but not all libraries are supported. More info can be found &lt;a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/native-aot?view=aspnetcore-8.0" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Boilerplate/Starter templates&lt;/strong&gt; - I have two projects to help get you started here :-). &lt;a href="https://github.com/AaronSaikovski/go-api-starter" rel="noopener noreferrer"&gt;Go API Starter&lt;/a&gt; and &lt;a href="https://github.com/AaronSaikovski/dotnet-min-api-boilerplate" rel="noopener noreferrer"&gt;.Net Minimal API Starter&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Web Framework&lt;/strong&gt; - Both support a rich web framework, but .Net core wins here from a full stack perspective. But from a pure speed and performance perspective GoLang wins, using the &lt;a href="https://docs.gofiber.io/" rel="noopener noreferrer"&gt;Fibre&lt;/a&gt; framework is unbeatable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Clean architecture&lt;/strong&gt; - Both support this.&lt;br&gt;
&lt;a href="https://www.c-sharpcorner.com/article/clean-architecture-in-asp-net-core-web-api/" rel="noopener noreferrer"&gt;Clean Architecture In ASP.NET Core Web API&lt;/a&gt;&lt;br&gt;
&lt;a href="https://amitshekhar.me/blog/go-backend-clean-architecture" rel="noopener noreferrer"&gt;Go Backend Clean Architecture&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Logging&lt;/strong&gt; - Both support this but its important to ensure that any logging framework supports a zero allocation model. For .Net use &lt;a href="https://github.com/serilog/serilog-aspnetcore" rel="noopener noreferrer"&gt;Serilog&lt;/a&gt; and for GoLang use &lt;a href="https://github.com/rs/zerolog" rel="noopener noreferrer"&gt;Zerolog&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;gRPC&lt;/strong&gt; - Both support this.&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/aspnet/core/grpc/?view=aspnetcore-8.0" rel="noopener noreferrer"&gt;Overview for gRPC on .NET&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/grpc/grpc-go" rel="noopener noreferrer"&gt;gRPC-Go&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Docker/Containers&lt;/strong&gt; - Both support this. Although .Net 8 has a much richer Docker integration (you can remove Docker files altogether) but the .Net docker image size is about 4 times larger. From a size and speed perspective GoLang wins here.&lt;br&gt;
&lt;a href="https://matthewregis.dev/posts/8-steps-for-creating-a-minimal-api-with-docker" rel="noopener noreferrer"&gt;Creating a Minimal API with Docker&lt;/a&gt;&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/dotnet/core/docker/publish-as-container" rel="noopener noreferrer"&gt;Containerize a .NET app with dotnet publish (new way..No Docker file)&lt;/a&gt;&lt;br&gt;
&lt;a href="https://techwasti.com/containerize-the-go-language-rest-api-using-docker" rel="noopener noreferrer"&gt;Containerize the go language REST API using Docker&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rate Limiting&lt;/strong&gt; - Both support this but can be tricky to implement and depends on the algorithm used.&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/aspnet/core/performance/rate-limit?view=aspnetcore-8.0" rel="noopener noreferrer"&gt;Rate limiting middleware in ASP.NET Core&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.calhoun.io/rate-limiting-api-calls-in-go/" rel="noopener noreferrer"&gt;Rate Limiting API Calls in Go&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Profiling&lt;/strong&gt; - Both support this.&lt;br&gt;
&lt;a href="https://dotnetthoughts.net/using-miniprofiler-in-aspnetcore-webapi/" rel="noopener noreferrer"&gt;How to Use Mini Profiler in ASP.NET Core Web API&lt;/a&gt;&lt;br&gt;
&lt;a href="https://granulate.io/blog/golang-profiling-basics-quick-tutorial/" rel="noopener noreferrer"&gt;Golang Profiling: The Basics and a Quick Tutorial&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Github Actions&lt;/strong&gt; - Both support this.&lt;br&gt;
&lt;a href="https://www.milanjovanovic.tech/blog/how-to-build-ci-cd-pipeline-with-github-actions-and-dotnet" rel="noopener noreferrer"&gt;How To Build a CI/CD Pipeline With GitHub Actions And .NET&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/chefgs/github-actions-workflow-for-go-continuous-integration-32id"&gt;GitHub Actions workflow for Go Continuous Integration&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Databases/ORM&lt;/strong&gt;- Both support this but have different implementations.&lt;br&gt;
&lt;a href="https://www.c-sharpcorner.com/article/api-development-using-dapper-and-microsoft-asp-net-core-web-api/" rel="noopener noreferrer"&gt;API Development Using Dapper and Microsoft Asp.NET Core Web API&lt;/a&gt;&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/ef/" rel="noopener noreferrer"&gt;Entity Framework&lt;/a&gt;&lt;br&gt;
&lt;a href="https://gorm.io/" rel="noopener noreferrer"&gt;GORM (ORM library for Golang)&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/volatiletech/sqlboiler" rel="noopener noreferrer"&gt;SQLBoiler (database-first ORM)&lt;/a&gt;&lt;br&gt;
&lt;a href="https://xorm.io/" rel="noopener noreferrer"&gt;XORM (Simple and Powerful ORM for Go)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tracing&lt;/strong&gt; - Both support this.&lt;br&gt;
&lt;a href="https://www.c-sharpcorner.com/UploadFile/2b481f/tracing-in-Asp-Net-web-api/" rel="noopener noreferrer"&gt;Tracing in ASP.Net Web API&lt;/a&gt;&lt;br&gt;
&lt;a href="https://pkg.go.dev/runtime/trace" rel="noopener noreferrer"&gt;Tracing runtime activities in Go.&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Exceptions&lt;/strong&gt; - .Net has the more traditional exception handling approach whereas Go has error return/nil types.&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis/handle-errors?view=aspnetcore-8.0" rel="noopener noreferrer"&gt;How to handle errors in Minimal API apps&lt;/a&gt;&lt;br&gt;
&lt;a href="https://alexrichey.com/articles/2021-09-09-error-handling-in-go-rest-apis.html" rel="noopener noreferrer"&gt;Error Handling in Go REST APIs&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Health Checks&lt;/strong&gt; - Both support this.&lt;br&gt;
&lt;a href="https://www.milanjovanovic.tech/blog/health-checks-in-asp-net-core" rel="noopener noreferrer"&gt;Health Checks In ASP.NET Core For Monitoring Your Applications&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/etherlabsio/healthcheck" rel="noopener noreferrer"&gt;Healthcheck (RESTful Healthcheck API implementation for Go services)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Unit tests&lt;/strong&gt; - Both support this.&lt;br&gt;
&lt;a href="https://timdeschryver.dev/blog/how-to-test-your-csharp-web-api" rel="noopener noreferrer"&gt;How to test your C# Web API&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/stretchr/testify" rel="noopener noreferrer"&gt;Testify&lt;/a&gt;&lt;br&gt;
&lt;a href="https://intercloud.com/our-resources/blog/testing-rest-apis-in-go" rel="noopener noreferrer"&gt;Testing REST APIs in Go&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Endpoint Grouping&lt;/strong&gt; - Both support this.&lt;br&gt;
&lt;a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis?view=aspnetcore-8.0" rel="noopener noreferrer"&gt;Minimal APIs quick reference (Route Groups)&lt;/a&gt; &lt;br&gt;
&lt;a href="https://blog.treblle.com/how-to-structure-your-minimal-api-in-net/" rel="noopener noreferrer"&gt;EndPoint Grouping .Net&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/percoguru/getting-started-with-apis-in-golang-feat-fiber-and-gorm-2n34"&gt;Go Fiber – Route Groups&lt;/a&gt;&lt;br&gt;
&lt;a href="https://medium.com/@uzairahmed01/fiber-framework-in-golang-b5158499c9ad" rel="noopener noreferrer"&gt;Fiber Framework in Golang&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;API Key security&lt;/strong&gt; - Both support this and have very similar implementations.&lt;br&gt;
&lt;a href="https://code-maze.com/aspnetcore-api-key-authentication/" rel="noopener noreferrer"&gt;Implement API Key Authentication in ASP.NET Core&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.gofiber.io/api/middleware/keyauth/" rel="noopener noreferrer"&gt;KeyAuth in Go Fiber&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;API Versioning&lt;/strong&gt; - Both support this.&lt;br&gt;
&lt;a href="https://github.com/dotnet/aspnet-api-versioning/tree/3857a332057d970ad11bac0edfdbff8a559a215d/examples/AspNetCore/WebApi/MinimalApiExample" rel="noopener noreferrer"&gt;.Net MinimalApiExample&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/aofdev/fiber-versioning-boilerplate" rel="noopener noreferrer"&gt;Go Fiber Versioning Boilerplate&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Authentication &amp;amp; Authorization (JWT)&lt;/strong&gt; - Both support this but depends on your use case and what you are authenticating against. JWT links are provided here:&lt;br&gt;
&lt;a href="https://www.infoworld.com/article/3669188/how-to-implement-jwt-authentication-in-aspnet-core.html" rel="noopener noreferrer"&gt;How to implement JWT authentication in ASP.NET Core&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/golang-jwt/jwt" rel="noopener noreferrer"&gt;jwt-go&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So from the comparison above hopefully this will guide you in your decision. For pure speed and lightweight APIS with no startup delays, I recommend Go.&lt;br&gt;
But .Net 8 isnt no slouch either and is a very close second.  Very close. If you are after a rich and mature ecosystem and really amazing tooling, go with ASP.Net 8 Core.&lt;br&gt;
thanks!&lt;/p&gt;

</description>
      <category>go</category>
      <category>csharp</category>
      <category>api</category>
      <category>webapi</category>
    </item>
    <item>
      <title>Welcome !</title>
      <dc:creator>Aaron Saikovski</dc:creator>
      <pubDate>Thu, 07 Dec 2023 20:58:39 +0000</pubDate>
      <link>https://dev.to/aaronsaikovski/welcome--312f</link>
      <guid>https://dev.to/aaronsaikovski/welcome--312f</guid>
      <description>&lt;p&gt;If you made it this far, welcome.&lt;br&gt;
I am back to blogging once again and hopefully you enjoy reading these articles as much as I enjoy writing them. &lt;br&gt;
2024 is going to be a big year and I have lots of articles and topics to cover and other random tech shenanigans as well.&lt;br&gt;
Watch this space and lots to come.&lt;/p&gt;

</description>
      <category>welcome</category>
    </item>
  </channel>
</rss>
