<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Emir Ribic</title>
    <link>https://dev.ribic.ba/</link>
    <description>Recent content on Emir Ribic</description>
    <generator>Hugo</generator>
    <language>en</language>
    <copyright>2024 © Emir Ribic - &lt;a href=&#34;https://creativecommons.org/licenses/by/3.0/&#34;&gt;Some rights reserved&lt;/a&gt;; please attribute properly and link back. Code snippets are &lt;a href=&#34;https://choosealicense.com/licenses/mit/&#34;&gt;MIT Licensed&lt;/a&gt;</copyright>
    <lastBuildDate>Sun, 26 Jan 2025 12:00:00 +0200</lastBuildDate>
    <atom:link href="https://dev.ribic.ba/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Recover panics in all Goroutines you start</title>
      <link>https://dev.ribic.ba/recover-panics-goroutines/</link>
      <pubDate>Sun, 26 Jan 2025 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/recover-panics-goroutines/</guid>
      <description>&lt;p&gt;I recently joined a project where the codebase was written in Go. While the codebase had numerous issues, one stood out: the server restarted unexpectedly and frequently. After examining the server logs, I discovered the culprit—panic-induced crashes in Goroutines. The underlying issue was that the codebase didn&amp;rsquo;t handle panic recovery in all the Goroutines it started.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Danger of Running Untrusted Code</title>
      <link>https://dev.ribic.ba/code-scam/</link>
      <pubDate>Thu, 21 Nov 2024 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/code-scam/</guid>
      <description>&lt;p&gt;Recently I was invited to a project on UpWork by someone claiming to have issues running his code. Before he started the contracted, I was invited to a GitHub repository, accepted - and executed the code locally. Nothing looked suspicious, until I dwelled deeper into the code. Lesson learned: never run untrusted code on your machine.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How I failed to properly transfer this website&#39;s domain</title>
      <link>https://dev.ribic.ba/failed-domain-transfer/</link>
      <pubDate>Mon, 06 May 2024 06:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/failed-domain-transfer/</guid>
      <description>&lt;p&gt;I used to run my blog at a different domain, ribice.ba .For personal reasons and other projects that I now host on this domain, I decided to transfer my programming blog to dev.ribic.ba. As I had no experience with domain migrations, I just set up the 301 redirect and submitted this change to Google Search Console. It went horribly wrong.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Switching to iPhone from Android - again</title>
      <link>https://dev.ribic.ba/android-to-iphone-again/</link>
      <pubDate>Sun, 05 May 2024 06:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/android-to-iphone-again/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve written a very lengthy post six and a half years ago about my journey from Android to iPhone (&lt;a href=&#34;https://dev.ribic.ba/android-to-iphone/&#34;&gt;here&lt;/a&gt;). After seven years, I found myself making the familiar journey back to iPhone from Android. In December last year, I took the plunge and invested in an iPhone 15 Pro along with an Apple Watch 9, eager to explore the latest offerings from Apple. I&amp;rsquo;ve been using it for a few months now and I&amp;rsquo;m ready to share my thoughts on the switch. Most of my reasoning from the last post still stands today, but there are a few things that have changed.&lt;/p&gt;</description>
    </item>
    <item>
      <title>My Google Pixel 5 is unable to make emergency calls</title>
      <link>https://dev.ribic.ba/google-pixel-emergency/</link>
      <pubDate>Thu, 04 Apr 2024 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/google-pixel-emergency/</guid>
      <description>&lt;p&gt;Yesterday, I experienced a car accident while driving to the city center. A vehicle collided with me from behind, prompting me to follow standard procedure by attempting to call the police for a proper assessment. However, my attempts to dial 112, the emergency number in Europe, were unsuccessful. The call wouldn&amp;rsquo;t connect, forcing me to resort to contacting a friend to call the police on my behalf. This process was awkward and consumed valuable time. It left me pondering the potent ial consequences had I been in a life-threatening situation.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Getting message from ChatGPT Assistants/Threads API</title>
      <link>https://dev.ribic.ba/working-with-assistant-api/</link>
      <pubDate>Tue, 20 Feb 2024 00:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/working-with-assistant-api/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve recently played with ChatGPT Assistant/Threads API and had to spend some time to get the actual response. For simple queries the message is included in the response, but for threads/run APIs it requires a bit more of engineering. Here&amp;rsquo;s how to get the message from the response.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hosting multiple WordPress sites on a single VPS - the easy way</title>
      <link>https://dev.ribic.ba/multiple-wordpress-single-vps/</link>
      <pubDate>Tue, 30 Jan 2024 02:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/multiple-wordpress-single-vps/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m managing multiple WordPress websites that were hosted in different ways. I use them for personal blogs (such as ribic.ba), personal projects and local portals. I was looking for a way to host and manage them easily on a single VPS - and found &lt;a href=&#34;https://easyengine.io/&#34;&gt;EasyEngine&lt;/a&gt; to be a perfect solution for my needs.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Deploying to EMR Serverless via EMR CLI</title>
      <link>https://dev.ribic.ba/emr-serverless-dockerfile/</link>
      <pubDate>Mon, 29 Jan 2024 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/emr-serverless-dockerfile/</guid>
      <description>&lt;p&gt;Recently as part of my academic studies I had to deploy a PySpark application to EMR Serverless. I encountered a couple of issues along the way - most of them related to me trying to get a newer version of Python running on the cluster. This post will cover the issues I encountered and how I resolved them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Sending CodeDeploy deployment notifications to Slack with Terraform</title>
      <link>https://dev.ribic.ba/codedeploy-slack-notifications-terraform/</link>
      <pubDate>Wed, 04 Oct 2023 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/codedeploy-slack-notifications-terraform/</guid>
      <description>&lt;p&gt;At PolymerSearch, we use CodeDeploy to deploy our services to AWS. We have a Slack channel where we post deployment notifications. We used to manually manage our infrastructure, but we recently switched to Terraform. Part of the migration required adding these Slack notifications, and since it wasn&amp;rsquo;t a straightforward process, this post will explain how to do it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Defer your mutex Unlocks</title>
      <link>https://dev.ribic.ba/defer-mutex-unlocks/</link>
      <pubDate>Sat, 25 Feb 2023 08:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/defer-mutex-unlocks/</guid>
      <description>&lt;p&gt;A few weeks ago we had an incident where our RabbitMQ was blocked and no new messages were processed. Restarting the service temporary resolved the issue, but the underlying the problem was still there. It was caused by a mutex that stayed locked after a panic. Even though we did recover from panic - the mutex remained to be locked.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Be Above Average</title>
      <link>https://dev.ribic.ba/above-average/</link>
      <pubDate>Thu, 24 Nov 2022 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/above-average/</guid>
      <description>&lt;p&gt;Being average (among the general populace) is easy. Most of the time it requires you to do nothing. Never strive for being average - the bar for that is too low.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Easy memory-saving tricks in Go</title>
      <link>https://dev.ribic.ba/golang-memory-savings/</link>
      <pubDate>Wed, 03 Aug 2022 03:04:31 +0200</pubDate>
      <guid>https://dev.ribic.ba/golang-memory-savings/</guid>
      <description>&lt;p&gt;Unless you&amp;rsquo;re prototyping a service - you probably care about the memory usage of your application. With a smaller memory footprint, the infrastructure costs are reduced and scaling becomes a bit easier/delayed. Even though Go is known for not consuming a lot of memory, there are ways to further reduce the consumption. Some of them require lots of refactoring, but many are very easy to do.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Back to Google - after de-googling my phone</title>
      <link>https://dev.ribic.ba/degoogle/</link>
      <pubDate>Thu, 04 Nov 2021 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/degoogle/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m an avid Android user for 10+ years. Like many other tech-oriented people, I&amp;rsquo;m not a fan of Google and its policies (a few reasons listed later), and I&amp;rsquo;m constantly trying to use alternatives where possible. I&amp;rsquo;ve used Custom ROMs for years (with Google apps), but recently used my phone for 4+ months without any Google service. The previous week I reinstalled Google&amp;rsquo;s factory image - here&amp;rsquo;s why and what next steps I plan to make to keep my privacy.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Glice v2 - Adding support for go.mod</title>
      <link>https://dev.ribic.ba/glice-v2/</link>
      <pubDate>Tue, 27 Jul 2021 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/glice-v2/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://github.com/ribice/glice&#34;&gt;Glice&lt;/a&gt; has been the first open-source project I published on my GitHub account. It&amp;rsquo;s a dependency checker for Go that used to go through all .go files, parse the imports and fetch the licenses for third-party dependencies. Long overdue I&amp;rsquo;ve added support for projects using Go Modules and did a major refactor simultaneously.&lt;/p&gt;</description>
    </item>
    <item>
      <title>HTTP logging in Go</title>
      <link>https://dev.ribic.ba/go-logging/</link>
      <pubDate>Wed, 14 Apr 2021 08:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/go-logging/</guid>
      <description>&lt;p&gt;Having good logging is crucial for running and debugging applications in production. It reduces your issue to resolution time by providing details about every action, request, and response. Designing a good logging system isn&amp;rsquo;t a trivial task, and requires an eye for detail. Here&amp;rsquo;s how I do it in Go!&lt;/p&gt;</description>
    </item>
    <item>
      <title>Removing null values from maps or JSON with Go</title>
      <link>https://dev.ribic.ba/golang-null-values/</link>
      <pubDate>Wed, 17 Feb 2021 00:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/golang-null-values/</guid>
      <description>&lt;p&gt;Recently I was given a task of removing all keys that have null values from an arbirtrary json. We do data processing of Excel/csv files and have default config generated for them server-side. Users provide custom configuration (column types, names, headers, sorting &amp;hellip;) and these two get merged. Problem was - if key existed and had null value it would override the key that had a value. Obviously there may be other ways to do this, but this is a very generic solution that can be used in most cases.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A robust RabbitMQ client in Go</title>
      <link>https://dev.ribic.ba/golang-rabbitmq-client/</link>
      <pubDate>Sun, 02 Aug 2020 08:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/golang-rabbitmq-client/</guid>
      <description>&lt;p&gt;A few months ago I started working on a project that heavily relies on RabbitMQ as a message broker. We have two clients communicating with Go, one via AMQP (RabbitMQ) and the other through HTTP. As our dependency on RabbitMQ is big, I had to write a robust client that does graceful shutdowns, panic recoveries, is multithreaded, logs everything nicely, and more.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Pushing data upstream in Context</title>
      <link>https://dev.ribic.ba/context-upstream/</link>
      <pubDate>Sat, 23 May 2020 08:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/context-upstream/</guid>
      <description>&lt;p&gt;Go&amp;rsquo;s context is a hefty tool that was added as an official package back in 1.7. The context package provides contextual information that a goroutine may need such as how long it should run and how and when it should end. It can also pass informational key-value pairs for use down the call chain.&#xA;But what if we need to pass information up in the call chain? Pointers come to the rescue.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Updating Goroutines post-creation</title>
      <link>https://dev.ribic.ba/updating-goroutines-post-creation/</link>
      <pubDate>Sun, 02 Feb 2020 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/updating-goroutines-post-creation/</guid>
      <description>&lt;p&gt;One of the greatest things about Go is how it deals with concurrency. It is far simpler compared to other languages. It uses so-called &lt;code&gt;goroutines&lt;/code&gt; - a lightweight thread managed by the Go runtime. While they are mostly used for asynchronous, fire-and-forget stuff (most common usage being HTTP multiplexers), I recently needed to have them updated post creation. The obvious first choice in Go would be to use channels, but trying to build the solution with them caused me some issues, which made me opt for a far simpler one - maps.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Writing RESTful APIs in Go, 3 years later</title>
      <link>https://dev.ribic.ba/rest-api-go3/</link>
      <pubDate>Mon, 20 Jan 2020 08:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/rest-api-go3/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve started working with Go in early 2017, and since then most of my work has been writing RESTful APIs with it. With time I gained experience. and I constantly change the way I write APIs in Go. After a year of working with Go, I&amp;rsquo;ve released &lt;a href=&#34;https://www.dev.ribic.ba/go-restful-starter-kit/&#34;&gt;Gorsk&lt;/a&gt; - a Golang RESTful starter kit, &lt;a href=&#34;https://www.dev.ribic.ba/refactoring-gorsk/&#34;&gt;and an update to it 6 months later&lt;/a&gt;. I get many emails and questions on how to use it properly, which means that something like Gorsk is highly needed. Over time I&amp;rsquo;d like to keep it up-to-date with my latest views on how to write REST APIs in Go, and this blog post serves as a first step in the next iteration.&lt;/p&gt;</description>
    </item>
    <item>
      <title>A Year in Review - 2019</title>
      <link>https://dev.ribic.ba/2019/</link>
      <pubDate>Wed, 01 Jan 2020 08:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/2019/</guid>
      <description>&lt;p&gt;I never felt confident writing my &amp;lsquo;year in review&amp;rsquo; until this year. I felt that I haven&amp;rsquo;t much to share, and even if I had I thought it wasn&amp;rsquo;t interesting. After reading a few similar posts from other bloggers, and having quite an interesting year, I thought that this year would be good to start with.&lt;/p&gt;</description>
    </item>
    <item>
      <title>dt - Go&#39;s missing datetime package</title>
      <link>https://dev.ribic.ba/golang-datetime/</link>
      <pubDate>Thu, 10 Oct 2019 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/golang-datetime/</guid>
      <description>&lt;p&gt;Go&amp;rsquo;s standard library contains a single date package - time. The type provided by it, Time, contains date, time and location information. More often than not we don&amp;rsquo;t need location info, or we need to represent date/time only. &lt;a href=&#34;https://github.com/ribice/dt&#34;&gt;&lt;code&gt;dt&lt;/code&gt;&lt;/a&gt; provides exactly that, a time-zone-independent representation of time that follows the rules of the proleptic Gregorian calendar with exactly 24-hour days, 60-minute hours, and 60-second minutes.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Working with enums in Go</title>
      <link>https://dev.ribic.ba/golang-enums/</link>
      <pubDate>Fri, 04 Oct 2019 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/golang-enums/</guid>
      <description>&lt;p&gt;Enums (short of enumerators), identifiers that behave like constants, are useful parts of many languages. Unfortunately, enums in Go aren&amp;rsquo;t as useful due to Go&amp;rsquo;s implementation. The biggest drawback is that they aren&amp;rsquo;t strictly typed, thus you have to manually validate them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Building a Cloud Function that generates PDFs from provided URL</title>
      <link>https://dev.ribic.ba/cloud-function-html-to-pdf/</link>
      <pubDate>Tue, 16 Jul 2019 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/cloud-function-html-to-pdf/</guid>
      <description>&lt;p&gt;At my current company, we generate PDF reports for our customers that contains detailed statistics for checks done on a car. We did so by generating an HTML using Go Templating engine, then using Headless chrome inside docker container to generate PDF from HTML. Since we&amp;rsquo;re running on App Engine, we had to use Flex environment in order to support custom docker image, which resulted in higher cost and significantly slower deployment times. To move the service to standard environment, I rewrote the PDF generation to a Cloud Function.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Building a live chat with Go, NATS, Redis and Websockets</title>
      <link>https://dev.ribic.ba/goch/</link>
      <pubDate>Wed, 10 Jul 2019 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/goch/</guid>
      <description>&lt;p&gt;Building a live-chat server is a good practice for learning a &amp;lsquo;backend&amp;rsquo; programming language. You need to provide an uninterrupted stream of data (think WebSockets), message storer and ideally a pubsub mechanism to send a message to all subscribed consumers. &lt;a href=&#34;https://github.com/ribice/goch&#34;&gt;Goch&lt;/a&gt; is no different, besides HTTP and REST endpoint it uses WebSockets, Redis, and NATS-streaming to support live-chat messaging. Read how it runs and how you can build your own live-chat in Go.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Deploying GoBuffalo app using Dokku</title>
      <link>https://dev.ribic.ba/buffalo-dokku/</link>
      <pubDate>Thu, 06 Jun 2019 00:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/buffalo-dokku/</guid>
      <description>&lt;p&gt;Last few months I spent my free time building Confello - a tech conference aggregator. You can read more about it &lt;a href=&#34;https://dev.ribic.ba/launching-confello/&#34;&gt;HERE&lt;/a&gt;. I built it with &lt;a href=&#34;https://gobuffalo.io/en&#34;&gt;GoBuffalo&lt;/a&gt;, a Go Web Framework. At first, I deployed the website on Heroku using the provided &lt;a href=&#34;https://github.com/gobuffalo/buffalo-heroku&#34;&gt;buffalo-heroku&lt;/a&gt; plugin. Before launching, I wanted to optimize the website on reverse proxy (gzip, expire headers &amp;hellip;). Since Heroku doesn&amp;rsquo;t provide access to reverse proxy (Nginx), I looked for another solution. I found Dokku - which turned out to be great and easy to work with.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Launching Confello</title>
      <link>https://dev.ribic.ba/launching-confello/</link>
      <pubDate>Thu, 30 May 2019 00:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/launching-confello/</guid>
      <description>&lt;p&gt;Last few months I spent some of my free time working on a project I felt was missing in the tech space. I&amp;rsquo;m proud to announce that today we&amp;rsquo;re making Confello, a tech conference aggregator website, available for public. Find, browse and discuss your favorite tech Conferences at Confello!&lt;/p&gt;</description>
    </item>
    <item>
      <title>Google Datastore with a relational data model</title>
      <link>https://dev.ribic.ba/relational-datastore/</link>
      <pubDate>Mon, 28 Jan 2019 02:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/relational-datastore/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been working on a medium-sized European software as service (SaaS) for the last two years. Almost everything we use comes from Google, which includes &lt;a href=&#34;https://cloud.google.com/datastore/docs/concepts/overview&#34;&gt;Cloud Datastore&lt;/a&gt; as our primary source of truth. I&amp;rsquo;m not advocating against it - depending on your use-case it might be a great fit. Instead, I&amp;rsquo;m presenting the issues we have with it (and other NoSQL/document databases) due to our domain models being very relational.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why you should start blogging</title>
      <link>https://dev.ribic.ba/why-you-should-blog/</link>
      <pubDate>Mon, 10 Dec 2018 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/why-you-should-blog/</guid>
      <description>&lt;p&gt;There are plenty of good reasons why you should start blogging right now or at least consider doing it. I&amp;rsquo;ve blogged previously about a decade ago and started doing it again since last year. I&amp;rsquo;ve seen plenty of benefits from this blog (and the previous one) and will talk about them in this blog post. In the end, I will propose a few modern solutions needed for starting your own blog.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Refactoring Gorsk - Why and how</title>
      <link>https://dev.ribic.ba/refactoring-gorsk/</link>
      <pubDate>Sun, 28 Oct 2018 08:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/refactoring-gorsk/</guid>
      <description>&lt;p&gt;Refactoring source code should be a constant process in software&amp;rsquo;s lifecycle. I advocate for 20-25% of time spent on developing software to be used on refactoring exclusively. After working with &lt;a href=&#34;https://github.com/ribice/gorsk&#34;&gt;Gorsk&lt;/a&gt; in two projects running now in production (one of them being a large SaaS), I&amp;rsquo;ve found many things I don&amp;rsquo;t like about it. During the development of those projects I refactored some things, but I decided the base needs to be updated too.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Beyond REST</title>
      <link>https://dev.ribic.ba/beyond-rest/</link>
      <pubDate>Sat, 15 Sep 2018 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/beyond-rest/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been dealing with RESTful services for the last three years, both professionally and for hobby projects. Since I came from SOAP/XML/Oracle background, REST felt so great and modern. Even though I felt late to the party, I think I didn&amp;rsquo;t lose that much. However, with the advancement of Cloud Native projects, I feel like I&amp;rsquo;m getting behind modern tools and technologies. And I want to change that.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Marshal YAML fields into map[string]string</title>
      <link>https://dev.ribic.ba/golang-yaml-string-map/</link>
      <pubDate>Thu, 30 Aug 2018 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/golang-yaml-string-map/</guid>
      <description>&lt;p&gt;Recently we moved some of our hard-coded web-app configuration values into a YAML file. Arguing aside (YAML vs TOML vs &amp;hellip;), YAML does a great job being easily readable by us - humans. By default, the &lt;a href=&#34;https://github.com/go-yaml/yaml&#34;&gt;yaml library&lt;/a&gt; marshals maps into &lt;code&gt;map[string]interface{}&lt;/code&gt;, requiring a small change to get it marshaled into &lt;code&gt;map[string]string&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Twisk - Golang RPC starter kit</title>
      <link>https://dev.ribic.ba/twisk/</link>
      <pubDate>Thu, 16 Aug 2018 00:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/twisk/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://github.com/ribice/twisk&#34;&gt;Twisk&lt;/a&gt;, an acronym for Twirp starter kit, helps you get started with a simple Golang RPC framework with protobuf service definitions - &lt;a href=&#34;https://github.com/twitchtv/twirp&#34;&gt;Twirp&lt;/a&gt;. It features everything from authorization, implemented CRUD on a single entity, logging, configuration and more. Using minimal dependencies, idiomatic code and best practices, it helps you get started with Golang backend API development - both JSON and Protobuf.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Serve SwaggerUI within your Golang application</title>
      <link>https://dev.ribic.ba/serving-swaggerui-golang/</link>
      <pubDate>Sun, 10 Jun 2018 01:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/serving-swaggerui-golang/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve previously written &lt;a href=&#34;https://www.dev.ribic.ba/swagger-golang/&#34;&gt;an Article&lt;/a&gt; on generating OpenAPI (Swagger) spec automatically within Golang. It&amp;rsquo;s the most popular article on this blog since lots of developers are searching for it. In it, I mentioned that in order to serve the swagger.json with SwaggerUI, a Docker instance is required that will serve SwaggerUI. There is an easier way to implement it, and this article will demonstrate how to do it with net/http, Gin and Echo.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Switched from Mac to Ubuntu</title>
      <link>https://dev.ribic.ba/mac-to-ubuntu/</link>
      <pubDate>Mon, 04 Jun 2018 02:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/mac-to-ubuntu/</guid>
      <description>&lt;p&gt;After being a Mac user for about a year, I decided to switch to GNU/Linux or to be more precise Ubuntu, for plenty of reasons. After few weeks of researching what laptop to buy, I asked for a Thinkpad X1 Carbon 5th Gen from my company. Besides writing a software review,this articles include hardware comparison between the Thinkpad and MacBookPro (ntb 2016) as well.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Working with Go Web Frameworks - Gin and Echo</title>
      <link>https://dev.ribic.ba/golang-web-frameworks/</link>
      <pubDate>Sat, 26 May 2018 00:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/golang-web-frameworks/</guid>
      <description>&lt;p&gt;Recently I spent a lot of time working with both Gin and Echo. Primarily I wrote an open source restful starter kit named Gorsk (&lt;a href=&#34;https://github.com/ribice/gorsk&#34;&gt;GitHub&lt;/a&gt;/&lt;a href=&#34;https://dev.ribic.ba/go-restful-starter-kit/&#34;&gt;Blog post&lt;/a&gt;). Besides Gorsk, I&amp;rsquo;m working on two web apps utilizing Gin/Echo. Even though the reasons for (not) using Golang&amp;rsquo;s &amp;lsquo;Web frameworks&amp;rsquo; are mentioned quite often, I have built my own opinion on these.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Removing comments</title>
      <link>https://dev.ribic.ba/disabling-comments/</link>
      <pubDate>Mon, 16 Apr 2018 08:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/disabling-comments/</guid>
      <description>&lt;p&gt;A decade ago I was happy if there were comments on my blog. Ten years later, having a full-time job, family and lots of other responsibilities I have no feeling about them. I feel good helping and informing others, but I feel comments on this blog aren&amp;rsquo;t benefiting much in this area (helping others). Additionally, I prefer the cleaner look and shorter loading times of the website. Therefore, comments are no more.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Automate Chrome with Golang and ChromeDP</title>
      <link>https://dev.ribic.ba/golang-chrome-automation/</link>
      <pubDate>Wed, 04 Apr 2018 08:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/golang-chrome-automation/</guid>
      <description>&lt;p&gt;Until recently I never knew how simple it could be to automate a task in the browser. A client wanted me to build simple automation script for Chrome - it would log into his Drupal website, open Bootstrap settings and change cdn&amp;rsquo;s to the one found in config file. Sounded bit hard at the beginning, but after playing an hour with chromedp it became quite trivial. Example repo is available on &lt;a href=&#34;https://www.github.com/ribice/golang-chrome-automation&#34;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Golang restful starter kit - GORSK</title>
      <link>https://dev.ribic.ba/go-restful-starter-kit/</link>
      <pubDate>Mon, 26 Mar 2018 08:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/go-restful-starter-kit/</guid>
      <description>&lt;p&gt;There are many ways to write a (RESTful) backend in Go. Most of the available tutorials are way too simple, with all the presented content fitting into a single file (or at most two-three). More complex examples are quite rare, and even most of them miss lots of things for the sake of reducing complexity. That&amp;rsquo;s one of the reasons I wrote &lt;a href=&#34;https://github.com/ribice/gorsk&#34;&gt;Gorsk&lt;/a&gt; - to have a fully functional example of a RESTful backend (in Golang) utilizing best practices, idiomatic code, and minimal dependencies.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Convert txt files to csv with Golang</title>
      <link>https://dev.ribic.ba/txt-csv-golang/</link>
      <pubDate>Fri, 16 Feb 2018 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/txt-csv-golang/</guid>
      <description>&lt;p&gt;Recently I found a client that needed to convert a list of txt files into csv - and he wanted the solution to be written in Go. Looking at the source files, I&amp;rsquo;m assuming the text files are generated by a script or a tool that extracts the data from somewhere. The good thing is that the provided files were very simple, so they are perfect for a tutorial like this.&lt;/p&gt;</description>
    </item>
    <item>
      <title>After being completely honest, Upwork banned my account for &#39;being dishonest&#39;</title>
      <link>https://dev.ribic.ba/upwork-suspended/</link>
      <pubDate>Tue, 13 Feb 2018 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/upwork-suspended/</guid>
      <description>&lt;p&gt;There are plenty of articles online despising Upwork. For those that don&amp;rsquo;t know, Upwork is &amp;rsquo;the world&amp;rsquo;s largest online workplace where savvy businesses and professional freelancers go to work!&amp;rsquo; Once I felt comfortable writing Go - I decided I could take some small side gigs to make connections and earn some extra cash. For reasons still unclear to me, that didn&amp;rsquo;t last for long.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Elasticsearch query examples with Golang</title>
      <link>https://dev.ribic.ba/golang-elastic/</link>
      <pubDate>Sun, 04 Feb 2018 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/golang-elastic/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve heard of Elasticsearch quite a while ago but started using around 6-7 months ago. It&amp;rsquo;s a very fine piece of technology, allowing you to create blazingly fast queries with very complex structure. Comming from a SQL background, I spent quality time reading through the official docs to write even the most basic queries. The purpose of this article is to save you that time and get you straight to work.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Create Golang API documentation with SwaggerUI</title>
      <link>https://dev.ribic.ba/swagger-golang/</link>
      <pubDate>Thu, 04 Jan 2018 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/swagger-golang/</guid>
      <description>&lt;p&gt;Having a documentation for you your APIs is more useful than you might be thinking. Even if you don&amp;rsquo;t expose your APIs publicly, having the docs for your frontend or mobile team is way easier than sending them screenshots/snippets or using a paid product like Postman/Insomnia (premium version with syncing). With SwaggerUI, you can get a well-designed documentation for all your APIs automatically. When moving to Go I had issues setting it up, due to lacking documentation/tutorials, so I decided to write one.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Fixing corrupt archive in Golang</title>
      <link>https://dev.ribic.ba/go-corrupt-archive/</link>
      <pubDate>Fri, 15 Dec 2017 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/go-corrupt-archive/</guid>
      <description>&lt;p&gt;Recently I had an issue sending JSON via API to our analytics tool. After few days of troubleshooting, I realized what was the problem during the weekend when the file being uploaded was of lower size due to less amount of data during weekends. Obviously, I decided to zip its contents, afterward facing a problem with a corrupted archive.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How to reduce JSON file size</title>
      <link>https://dev.ribic.ba/reduce-json-size/</link>
      <pubDate>Sat, 09 Dec 2017 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/reduce-json-size/</guid>
      <description>&lt;p&gt;When I started writing this article, it had a quite different title. To be precise: &amp;ldquo;Uploading large JSON files to Zoho Reports.&amp;rdquo; But, reducing JSON size might be useful in so many areas, I decided not to limit it to Zoho and changed the title.&lt;/p&gt;&#xA;&lt;p&gt;Shortly, I&amp;rsquo;ll explain how I managed to reduce and split JSON files of several gigabytes to the desired size - size limited by the provided API, with help of few tools.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Glice - Golang dependency and license checker</title>
      <link>https://dev.ribic.ba/glice/</link>
      <pubDate>Fri, 01 Dec 2017 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/glice/</guid>
      <description>&lt;p&gt;Did you ever want to check licenses of third-party dependencies in your Go project? Me neither. However, if you want to do something like that, I made a simple tool written in Go - glice. By running it in your Go project, it gets project&amp;rsquo;s dependencies (with a possibility of recursive dependencies), then for third-party ones gets the license from GitHub API.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Windows to Mac - Power user&#39;s perspective</title>
      <link>https://dev.ribic.ba/win-to-mac/</link>
      <pubDate>Sun, 19 Nov 2017 08:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/win-to-mac/</guid>
      <description>&lt;p&gt;For quite some time I had a desire to switch to Mac / OSX, due to several reasons. Mainly, the *nix environment always attracted me, Apple&amp;rsquo;s hardware quality and the general feeling of OSX. Lots of friends (developers) around me had Macs, and the tutorials from developers I enjoy watching were mostly recorded on Macs. Yes, there&amp;rsquo;s GNU/Linux, and I used it occasionally, but for reasons mentioned later, I couldn&amp;rsquo;t switch to only using it.&lt;/p&gt;&#xA;&lt;p&gt;Half a year ago I switched jobs, moved from Windows to Mac only, being forced to relearn many things about my daily computer usage.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kiss - A stupidly simple Hugo blogging theme</title>
      <link>https://dev.ribic.ba/hugo-kiss/</link>
      <pubDate>Mon, 16 Oct 2017 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/hugo-kiss/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m a huge fan of &lt;a href=&#34;https://gohugo.io&#34;&gt;Hugo&lt;/a&gt; - not only as a Gopher but because I feel quite comfortable working with it - even though I work full-time as a backend developer and I&amp;rsquo;ve got no working experience with frontend - just some basic html/css/js. After deciding to start a blog, I searched for the simplest theme possible and decided to go with Hemingway. Unfortunately, &lt;a href=&#34;https://github.com/tanksuzuki&#34;&gt;Tanksuzuki&lt;/a&gt;, the developer of Hemingway, abandoned the theme and doesn&amp;rsquo;t respond to issues and pull requests for nearly a year, even though he&amp;rsquo;s being active on Github. I did plenty of changes on this theme and decided to share it with the community.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Switching to iPhone from Android - Power user&#39;s experience</title>
      <link>https://dev.ribic.ba/android-to-iphone/</link>
      <pubDate>Sat, 16 Sep 2017 12:00:00 +0200</pubDate>
      <guid>https://dev.ribic.ba/android-to-iphone/</guid>
      <description>&lt;p&gt;There are many Android power users out there thinking of switching to iPhone. Or at least how would the switch affect them and their daily phone usage. What&amp;rsquo;s better in the Apple ecosystem and what&amp;rsquo;s worse?&#xA;As a power user, I&amp;rsquo;ve taken the step myself to see whether I could use an iPhone as a daily driver for some time. Below are my observations and experiences of this switch.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Getting started - again</title>
      <link>https://dev.ribic.ba/getting-started/</link>
      <pubDate>Tue, 12 Sep 2017 17:04:31 +0200</pubDate>
      <guid>https://dev.ribic.ba/getting-started/</guid>
      <description>&lt;p&gt;I wanted to start my blog, again, for quite some time. I used to run few blogs of mine quite successfully several years ago, but I stopped blogging once I started working full-time. My previous employer wasn&amp;rsquo;t very supportive of working from home (things like blogging, working on OSS or for profit), so I slowly complied with that and lived on, even though I never agreed with that policy for so many reasons.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
