<?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: Yurii Zinets</title>
    <description>The latest articles on DEV Community by Yurii Zinets (@yuriizinets).</description>
    <link>https://dev.to/yuriizinets</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%2F243133%2F539d811b-04e4-4ee7-b2e9-c2d2fc268978.png</url>
      <title>DEV Community: Yurii Zinets</title>
      <link>https://dev.to/yuriizinets</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yuriizinets"/>
    <language>en</language>
    <item>
      <title>Kyoto on GopherCon 2021! (including text version)</title>
      <dc:creator>Yurii Zinets</dc:creator>
      <pubDate>Wed, 22 Dec 2021 10:29:41 +0000</pubDate>
      <link>https://dev.to/yuriizinets/kyoto-on-gophercon-2021-including-text-version-3lch</link>
      <guid>https://dev.to/yuriizinets/kyoto-on-gophercon-2021-including-text-version-3lch</guid>
      <description>&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Ufe2YVHijb0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Hi everyone!&lt;br&gt;
Today I'd like to present the library named &lt;code&gt;kyoto&lt;/code&gt;. It's an SSR-first go frontend library.&lt;/p&gt;

&lt;p&gt;First, let me introduce myself. I'm Yurii Zinets. Software Engineer at Akamai, but also a Core Developer of BrokerOne Real Estate platform on part-time. The overall story I'm going to tell is actually related to BrokerOne development process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backstory
&lt;/h2&gt;

&lt;p&gt;Before I start to talk about kyoto itself, it's important to know backstory because we are not creating technologies for technologies, but for solving different problems. So, a long story short. In the beginning of the platform creation, we decided to create a prototype first. We took a well-known JavaScript framework with a set of ready to use material components. As usually happens, the prototype became the main project. Over the time, we began to feel the impact of this decision. It was hard to keep the project clean and tidy. We had a lot of difficulties with SSR, memory leaks on the server side and performance score issues. We completely lost control. After discussion, our team decided to drop this prototype and go in more traditional way - use template engine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why template engine?
&lt;/h2&gt;

&lt;p&gt;So, why did we choose such a radical way? We had several reasons. Unnecessary complexity was one of those reasons.&lt;br&gt;
Not many people really understand how their project setup works under the hood. Webpack with tons of configurations, babel, tree shaking (especially when it doesn't work as expected), lazy loading. You need to bring a significant runtime and Virtual DOM just to render a simple things like articles or pages with minimal dynamic behavior. Template engine reduces overall complexity and allows taking full control over frontend. Also, this approach reduces amount of bugs and quirks because we can find most of the problems on building and testing stages.&lt;/p&gt;

&lt;h2&gt;
  
  
  What problems kyoto is trying to solve?
&lt;/h2&gt;

&lt;p&gt;Our project became much better with this migration, but we faced some common inconveniences. We have started to use more copy-paste. Our handlers became a spaghetti because of asynchronous API and DB requests. And we all have to admit, vanilla JS is quite verbose even for simple dynamic things.&lt;br&gt;
That's why kyoto was born.&lt;/p&gt;

&lt;h2&gt;
  
  
  What features kyoto provides?
&lt;/h2&gt;

&lt;p&gt;First issue I solved is code organization structure.&lt;br&gt;
For each page and component, you have separate Go structure and template definition. You can include data fetching and display logic just right inside a component. Second thing I provided is page rendering lifecycle. This allowed me to solve asynchronous calls issue. You can implement asynchronous method for component, and it will be called with own goroutine under the hood on page rendering. As an example, you have 10 instances of the component on the page.&lt;br&gt;
In that situation, 10 goroutines will be created for each asynchronous call. And the most interesting thing in this library I've implemented is a built-in dynamics functionality, inspired by Hotwire and Laravel Livewire.&lt;br&gt;
It's pretty simple and limited because it's created for simple things. But people really liked it, and I'm extending functions over the time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Future plans
&lt;/h2&gt;

&lt;p&gt;As the project has solidified its core idea, I'm able to make some plans for the future. We are already working on UI Kit, based on Tailwind UI, and already using it for our internal tools. Anyway, it still needs a lot of work. Also, one of the features I'd like to provide is a Server Side State. This approach will reduce the initial amount of data to transfer between server and client. And last, but the most interesting and crazy idea I'm experimenting on is bringing the whole rendering process to the Edge Workers. It's giving to us a serverless setup and insanely fast responses. Unfortunately, Cloudflare Edge Workers have a lot of restrictions (like 1 MB executable size limit) and don't have official support for Go. I was able to run Go on the Edge Workers with tinygo compiler and WASM, but it's not enough to be able to use kyoto as expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;So, here is a quick summary for this talk. I think Go have a big potential and is not limited by current domain. Otherwise, it would be impossible to create tools and libraries like this. I'd like to note that kyoto is not a framework by its own. On my opinion, combination of UI Kit, project blueprints and best practices are actually become a framework. I'm not creating kyoto opposite to JavaScript solutions. Even more, it's possible to integrate them. I just believe that every solution has an own purpose. And I hope this solution will help someone too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/kyoto-framework/kyoto"&gt;https://github.com/kyoto-framework/kyoto&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Presentation materials: &lt;a href="https://github.com/kyoto-framework/gophercon-2021"&gt;https://github.com/kyoto-framework/gophercon-2021&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Bonus links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Scheduler: &lt;a href="https://github.com/kyoto-framework/scheduler"&gt;https://github.com/kyoto-framework/scheduler&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;UIKit (WIP): &lt;a href="https://github.com/kyoto-framework/uikit"&gt;https://github.com/kyoto-framework/uikit&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>showdev</category>
      <category>go</category>
      <category>frontend</category>
      <category>gophercon</category>
    </item>
    <item>
      <title>kyoto on GopherCon 2021!</title>
      <dc:creator>Yurii Zinets</dc:creator>
      <pubDate>Thu, 09 Dec 2021 11:14:25 +0000</pubDate>
      <link>https://dev.to/yuriizinets/kyoto-on-gophercon-2021-511p</link>
      <guid>https://dev.to/yuriizinets/kyoto-on-gophercon-2021-511p</guid>
      <description>&lt;p&gt;For those unfamiliar with kyoto, it's an SSR-first Go Frontend Library. It's my first time going public and I hope it was not as awful as I think 😅 &lt;/p&gt;

&lt;p&gt;Library: &lt;a href="https://github.com/kyoto-framework/kyoto"&gt;https://github.com/kyoto-framework/kyoto&lt;/a&gt;&lt;br&gt;
Talk recording: &lt;a href="https://youtu.be/35eIxI_n5ZM?t=11860"&gt;https://youtu.be/35eIxI_n5ZM?t=11860&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I was really happy to participate, the atmosphere was delightful!&lt;/p&gt;

</description>
      <category>gophercon</category>
      <category>go</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Kyoto: Golang SSR-first Frontend Library</title>
      <dc:creator>Yurii Zinets</dc:creator>
      <pubDate>Wed, 27 Oct 2021 10:45:00 +0000</pubDate>
      <link>https://dev.to/yuriizinets/kyoto-golang-ssr-first-frontend-library-5ekc</link>
      <guid>https://dev.to/yuriizinets/kyoto-golang-ssr-first-frontend-library-5ekc</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/yuriizinets/kyoto"&gt;https://github.com/yuriizinets/kyoto&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This library implements an HTML render engine concept that brings frontend-like components experience to the server side with native html/template on steroids. Supports any serving basis (net/http/gin/etc), that provides io.Writer in response.&lt;/p&gt;

&lt;p&gt;Main motivation is to reduce usage of popular SPA/PWA frameworks where it's not needed because it adds a lot of complexity and overhead. There is no reason to bring significant runtime, VirtualDOM, and Webpack into the project with minimal dynamic frontend behavior. This project proves the possibility of keeping most of the logic on the server's side.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Library: &lt;a href="https://github.com/yuriizinets/kyoto"&gt;https://github.com/yuriizinets/kyoto&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Documentation: &lt;a href="https://kyoto.codes/docs/"&gt;https://kyoto.codes/docs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;UIKit (in active development): &lt;a href="https://github.com/yuriizinets/kyoto-uikit"&gt;https://github.com/yuriizinets/kyoto-uikit&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Starter project: &lt;a href="https://github.com/yuriizinets/kyoto-starter"&gt;https://github.com/yuriizinets/kyoto-starter&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>ssceng: Golang Frontend Components</title>
      <dc:creator>Yurii Zinets</dc:creator>
      <pubDate>Thu, 16 Sep 2021 11:15:17 +0000</pubDate>
      <link>https://dev.to/yuriizinets/ssceng-golang-frontend-components-235k</link>
      <guid>https://dev.to/yuriizinets/ssceng-golang-frontend-components-235k</guid>
      <description>&lt;p&gt;&lt;a href="https://ssceng.codes"&gt;https://ssceng.codes&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>SSC, changes and propositions</title>
      <dc:creator>Yurii Zinets</dc:creator>
      <pubDate>Fri, 30 Apr 2021 09:45:32 +0000</pubDate>
      <link>https://dev.to/yuriizinets/ssc-changes-and-propositions-imm</link>
      <guid>https://dev.to/yuriizinets/ssc-changes-and-propositions-imm</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/yuriizinets/go-ssc"&gt;https://github.com/yuriizinets/go-ssc&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Latest changes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Actions handler simplified. Now, it's implemented as http.HandlerFunc and much easier to use. I've added some documentation for that, but it still far away from "done".&lt;/li&gt;
&lt;li&gt;Actions arguments handling changed. You can just specify as much arguments, as you want in that way: &lt;code&gt;{{ action "ActionName" 1 2 3 }}&lt;/code&gt;. That arguments will be passed as interface slice into your Action.&lt;/li&gt;
&lt;li&gt;Demo page upgraded. It's still not so awesome as need to be, but I'm doing my best :)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Asking for ideas and propositions
&lt;/h2&gt;

&lt;p&gt;I'm building development roadmap now and would like to listen for community ideas, about your vision of this concept. Feel free to propose anything you would like to see in this project, I would be very glad for any feedback :)&lt;/p&gt;

</description>
      <category>go</category>
      <category>webdev</category>
      <category>tooling</category>
      <category>programming</category>
    </item>
    <item>
      <title>Frontend components with Golang</title>
      <dc:creator>Yurii Zinets</dc:creator>
      <pubDate>Sat, 24 Apr 2021 08:25:48 +0000</pubDate>
      <link>https://dev.to/yuriizinets/frontend-components-with-golang-4of6</link>
      <guid>https://dev.to/yuriizinets/frontend-components-with-golang-4of6</guid>
      <description>&lt;p&gt;First of all, thank you for attention!&lt;br&gt;
I'd like to present you HTML render engine concept, that brings frontend-like components experience to the server side with native html/template on steroids. Supports any serving basis (nethttp/Gin/etc), that provides io.Writer for response.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3JOwpme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/yuriizinets"&gt;
        yuriizinets
      &lt;/a&gt; / &lt;a href="https://github.com/yuriizinets/ssceng"&gt;
        ssceng
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      ⚙️ Concept of Golang HTML render engine with frontend components and dynamic behavior
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Please, keep in mind that it's work-in-progress, but already used in &lt;a href="https://mybrokerone.com/"&gt;BrokerOne&lt;/a&gt; for some parts of our frontend and already shows good prospects.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;I'm trying to minimize usage of popular SPA/PWA frameworks where it's not needed at all because it adds a lot of complexity and overhead. Nowadays JS ecosystem is overcomplicated and huge. I don't want to separately implement API, API communication layer, bring large runtime, state management engine, VirtualDOM and webpack into project with minimal dynamic frontend behavior.&lt;br&gt;
This project proves posibility to keep most of the logic on the server side.&lt;/p&gt;

&lt;h2&gt;
  
  
  What problems it solves? Why not plain GoKit?
&lt;/h2&gt;

&lt;p&gt;While developing website's frontend with Go I realised some downsides of such approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;With plain html/template your're starting to repeat yourself. It's harder to define reusable parts&lt;/li&gt;
&lt;li&gt;You must to repeat DTO calls for each page, where you're using reusable parts&lt;/li&gt;
&lt;li&gt;With Go's routines approach it's hard to make async-like DTO calls in the handlers&lt;/li&gt;
&lt;li&gt;For dynamic things, you still need to use JS and client-side DOM modification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Complexity is much higher when all of them combined.&lt;/p&gt;

&lt;p&gt;This engine tries to bring components and async experience to the traditional server side rendering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Component approach in mix with &lt;code&gt;html/template&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Asynchronous operations&lt;/li&gt;
&lt;li&gt;Component methods, that can be called from client side (Server Side Actions, SSA)&lt;/li&gt;
&lt;li&gt;Different types of components communication (parent, cross)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>webdev</category>
      <category>tooling</category>
      <category>programming</category>
    </item>
    <item>
      <title>GoogletransX update!</title>
      <dc:creator>Yurii Zinets</dc:creator>
      <pubDate>Tue, 06 Oct 2020 10:05:16 +0000</pubDate>
      <link>https://dev.to/yuriizinets/googletransx-update-4h73</link>
      <guid>https://dev.to/yuriizinets/googletransx-update-4h73</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/yuriizinets/googletransx"&gt;https://github.com/yuriizinets/googletransx&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hi guys! :)&lt;br&gt;
A bit earlier, I published my extended version of &lt;strong&gt;Googletrans&lt;/strong&gt; (check &lt;a href="https://dev.to/yuriizinets/googletransx-free-unlimited-translation-pia"&gt;&lt;strong&gt;here&lt;/strong&gt;&lt;/a&gt;). And now, I'd like to introduce to you some changes&lt;/p&gt;
&lt;h2&gt;
  
  
  Interface translation
&lt;/h2&gt;

&lt;p&gt;From now, with &lt;code&gt;TranslateInterface&lt;/code&gt; you can translate your structured data directly! Without handling fields getting and setting by yourself. It supports all the features, that &lt;code&gt;github.com/stretchr/objx&lt;/code&gt; provides (nested interfaces, slices, etc)&lt;/p&gt;

&lt;p&gt;Example is here:&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;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/yuriizinets/googletransx"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&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="s"&gt;"A"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&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="s"&gt;"B"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"I'm a test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s"&gt;"D"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Example"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Example"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s"&gt;"C"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Example"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;TranslateParams&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Src&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Dest&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"ru"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;TranslateField&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Src&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="s"&gt;"A.B"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Dest&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="s"&gt;"A.B_ru"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Params&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Src&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;    &lt;span class="s"&gt;"A.D"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Dest&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="s"&gt;"A.D_ru"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Params&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;TranslateInterface&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// Will be map[A:map[B:I'm a test B_ru:Я тест D:[Example Example] D_ru:[пример пример]] C:Example]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Ordered results from bulk
&lt;/h2&gt;

&lt;p&gt;It wasn't in the plans, but &lt;code&gt;TranslateInterface&lt;/code&gt; requires correctly ordered results from &lt;code&gt;BulkTranslate&lt;/code&gt;. So, UID field is added for &lt;code&gt;TranslateParams&lt;/code&gt; struct. It's optional, you can just leave it as-is, BulkTranslate will put UIDs for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;I hope, that changes will be useful for you.&lt;br&gt;
&lt;strong&gt;Thank you for your attention, and good luck!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  P.S.
&lt;/h2&gt;

&lt;p&gt;Don't forget to check my another articles and packages!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/yuriizinets/go-private-packages-3bo"&gt;Go private packages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/yuriizinets/goplaces-go-algolia-places-api-wrapper-3lk6"&gt;GoPlaces: Go Algolia Places API Wrapper&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Go private packages</title>
      <dc:creator>Yurii Zinets</dc:creator>
      <pubDate>Sun, 04 Oct 2020 07:33:07 +0000</pubDate>
      <link>https://dev.to/yuriizinets/go-private-packages-3bo</link>
      <guid>https://dev.to/yuriizinets/go-private-packages-3bo</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;git submodules&lt;/em&gt; &lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;What's the matter?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Imagine a situation when you're following best practices, splitting your code on different parts, and ... facing an issue to collect them.&lt;br&gt;
Unfortunately, go does not support private packages well.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;So, how?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I'll describe the situation I faced. Private go mod packages, located in the GitLab subgroup (let's say &lt;code&gt;gitlab.com/org/department/repo1.git&lt;/code&gt; just for example)&lt;/p&gt;

&lt;p&gt;First, go not actually supports GitLab subgroups. To bypass that issue, we need to set GOPRIVATE env variable and add .git in the end:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ GOPRIVATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"gitlab.com/org/department"&lt;/span&gt; go get gitlab.com/org/department/repo1.git 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Second barrier is access to that repo. SSH key must be added to the platform, I didn't found a way to fetch with https.&lt;/p&gt;

&lt;p&gt;Pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Native experience (go get, which handles &lt;code&gt;go.mod&lt;/code&gt; changes itself)
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSH key must be set&lt;/li&gt;
&lt;li&gt;go.mod package name must fully correspond that naming (with &lt;code&gt;.git&lt;/code&gt; in the end)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Problem is solved ... or not?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The first problem was faced in just after half an hour. It's a CI/CD, or just building step.&lt;br&gt;
As we understood from previous "summary", SSH key must be added. We are using Docker to build our project, and passing SSH key to the Dockerfile build actually is a security problem.&lt;/p&gt;
&lt;h2&gt;
  
  
  Alternative way
&lt;/h2&gt;

&lt;p&gt;I found a solution in &lt;strong&gt;&lt;em&gt;git submodules&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;replace&lt;/em&gt;&lt;/strong&gt; feature for the &lt;code&gt;go.mod&lt;/code&gt;.&lt;br&gt;
Just add needed repo as a project submodule with &lt;code&gt;git submodule add&lt;/code&gt; and add naming replacement in the &lt;code&gt;go.mod&lt;/code&gt;.&lt;br&gt;
For example:&lt;/p&gt;

&lt;p&gt;Adding submodule&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git submodule add ../repo1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pulling newly added repo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git submodule update --init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding &lt;code&gt;go.mod&lt;/code&gt; replacement&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;replace gitlab.com/org/department/repo1.git =&amp;gt; ./repo1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's all! Handling package as a submodule is much easier than go package.&lt;/p&gt;

&lt;p&gt;P.S. Don't forget to add submodules pulling in your CI! In case of GitLab it's &lt;code&gt;GIT_SUBMODULE_STRATEGY: recursive&lt;/code&gt; variable.&lt;/p&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

</description>
      <category>go</category>
      <category>git</category>
      <category>webdev</category>
    </item>
    <item>
      <title>GoogletransX: Free unlimited translation</title>
      <dc:creator>Yurii Zinets</dc:creator>
      <pubDate>Sat, 19 Sep 2020 11:01:49 +0000</pubDate>
      <link>https://dev.to/yuriizinets/googletransx-free-unlimited-translation-pia</link>
      <guid>https://dev.to/yuriizinets/googletransx-free-unlimited-translation-pia</guid>
      <description>&lt;p&gt;Hi guys!&lt;br&gt;
I'd like to share with you my work on extending existing google translate library project with some features.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yuriizinets/googletransx"&gt;https://github.com/yuriizinets/googletransx&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  So, what features?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;All that original library functionality, including unlimited free translates! :)&lt;/li&gt;
&lt;li&gt;BulkTranslate with goroutines processing&lt;/li&gt;
&lt;li&gt;HTML translate support&lt;/li&gt;
&lt;li&gt;Built-in API server for integrations&lt;/li&gt;
&lt;li&gt;Dockerized server&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why not original library?
&lt;/h2&gt;

&lt;p&gt;To be honest, I started that project due to absence of normal BulkTranslate functionality. I had to translate a really huge amount of different data, and to make it fast and functional I created fork with extended features.&lt;/p&gt;

&lt;h2&gt;
  
  
  API server? For what?
&lt;/h2&gt;

&lt;p&gt;Golang may be not the only language in the project. For simple integration I bundled functionality as a simple API to use that as a service.&lt;/p&gt;

&lt;p&gt;P.S.&lt;br&gt;
I hope that it will be useful for you. Even if not, thank you for your attention :)&lt;/p&gt;

</description>
      <category>go</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>translate</category>
    </item>
    <item>
      <title>GoPlaces: Go Algolia Places API Wrapper</title>
      <dc:creator>Yurii Zinets</dc:creator>
      <pubDate>Sun, 13 Sep 2020 16:10:15 +0000</pubDate>
      <link>https://dev.to/yuriizinets/goplaces-go-algolia-places-api-wrapper-3lk6</link>
      <guid>https://dev.to/yuriizinets/goplaces-go-algolia-places-api-wrapper-3lk6</guid>
      <description>&lt;p&gt;Hi, guys!&lt;br&gt;
I'm new to the Golang and that ecosystem, so I'd like to share with you my small experimental library :)&lt;/p&gt;

&lt;p&gt;Sometimes geocoding functionality is needed on the server side, but Algolia Places only provides basic API for that purpose. So, I decided to wrap that API with small Go library to simplify work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/yuriizinets/goplaces"&gt;https://github.com/yuriizinets/goplaces&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>algolia</category>
      <category>geosearch</category>
      <category>geocoding</category>
    </item>
  </channel>
</rss>
