{"componentChunkName":"component---src-templates-tag-js","path":"/tags/golang/","result":{"data":{"site":{"siteMetadata":{"title":"LoginRadius Blog"}},"allMarkdownRemark":{"totalCount":4,"edges":[{"node":{"fields":{"slug":"/engineering/tune-the-go-http-client-for-high-performance/"},"html":"<p>HTTP (hypertext transfer protocol) is a communication protocol that transfers data between client and server. HTTP requests are very essential to access resources from the same or remote server. In Golang, the <code>net/http</code> package comes with the default settings that we need to adjust according to our high-performance requirement.</p>\n<p>For setting up HTTP clients for making requests, most programming languages have different frameworks in place. We will take a hands-on approach in the coming sections to explore how HTTP requests can be made in Golang or Go, as I will refer to the language for the rest of the post.</p>\n<p>While working on the <a href=\"https://www.loginradius.com/blog/engineering/golang-maps/\">Golang projects</a>, I realized that improper configuration of HTTP might crash your server anytime.</p>\n<p>In the time when I was working with HTTP Client, I Observed some problems and their solutions, listed below:</p>\n<h2 id=\"problem1-default-http-client\" style=\"position:relative;\"><a href=\"#problem1-default-http-client\" aria-label=\"problem1 default http client permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Problem:1 Default Http Client</h2>\n<p>The HTTP client does not contain the request timeout setting by default.\nIf you are using http.Get(URL) or &#x26;Client{} that uses the http.DefaultClient. DefaultClient has not timeout setting; it comes with <code>no timeout</code></p>\n<p>Suppose the Rest API where you are making the request is broken, not sending the response back that keeps the connection open. More requests came, and open connection count will increase, Increasing server resources utilization, resulting in crashing your server when resource limits are reached.</p>\n<h3 id=\"solution-dont-use-the-default-http-client-always-specify-the-timeout-in-httpclient-according-to-your-use-case\" style=\"position:relative;\"><a href=\"#solution-dont-use-the-default-http-client-always-specify-the-timeout-in-httpclient-according-to-your-use-case\" aria-label=\"solution dont use the default http client always specify the timeout in httpclient according to your use case permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Solution: Don't use the default HTTP client, always specify the timeout in http.Client according to your use case</h3>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">var httpClient = &http.Client{</span>\n<span class=\"grvsc-line\">  Timeout: time.Second * 10,</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>For the Rest API, it is recommended that timeout should not more than 10 seconds.\nIf the Requested resource is not responded to in 10 seconds, the HTTP connection will be canceled with net/http: request canceled (Client.Timeout exceeded ...) error.</p>\n<h2 id=\"problem2-default-http-transport\" style=\"position:relative;\"><a href=\"#problem2-default-http-transport\" aria-label=\"problem2 default http transport permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Problem:2 Default Http Transport</h2>\n<p>By default, the Golang Http client performs the connection pooling. When the request completes, that connection remains open until the idle connection timeout (default is 90 seconds). If another request came, that uses the same established connection instead of creating a new connection, after the idle connection time, the connection will return to the pool.</p>\n<p>Using the connection pooling will keep less connection open and more requests will be served with minimal server resources.</p>\n<p>When we not defined transport in the http.Client, it uses the default transport <a href=\"https://golang.org/src/net/http/transport.go\">Go HTTP Transport</a></p>\n<p>Default configuration of the HTTP Transport, </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">var DefaultTransport RoundTripper = &Transport{</span>\n<span class=\"grvsc-line\">\t...</span>\n<span class=\"grvsc-line\">\tMaxIdleConns:          100,</span>\n<span class=\"grvsc-line\">\tIdleConnTimeout:       90 * time.Second,</span>\n<span class=\"grvsc-line\">\t...</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">const DefaultMaxIdleConnsPerHost = 2</span></code></pre>\n<p>MaxIdleConns is the connection pool size, and this is the maximum connection that can be open; its default value is 100 connections.</p>\n<p>There is problem with the default setting <code>DefaultMaxIdleConnsPerHost</code> with value of 2 connection,\nDefaultMaxIdleConnsPerHost is the number of connection can be allowed to open per host basic.\nMeans for any particular host out of 100 connection from the connection pool only two connection will be allocated to that host.</p>\n<p>With the more request came, it will process only two requests; other requests will wait for the connection to communicate with the host server and go in the <code>TIME_WAIT</code> state. As more request came, increase the connection to the <code>TIME_WAIT</code> state and increase the server resource utilization; at the limit, the server will crash.</p>\n<h3 id=\"solution-dont-use-default-transport-and-increase-maxidleconnsperhost\" style=\"position:relative;\"><a href=\"#solution-dont-use-default-transport-and-increase-maxidleconnsperhost\" aria-label=\"solution dont use default transport and increase maxidleconnsperhost permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Solution: Don't use Default Transport and increase MaxIdleConnsPerHost</h3>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">t := http.DefaultTransport.(*http.Transport).Clone()</span>\n<span class=\"grvsc-line\">t.MaxIdleConns = 100</span>\n<span class=\"grvsc-line\">t.MaxConnsPerHost = 100</span>\n<span class=\"grvsc-line\">t.MaxIdleConnsPerHost = 100</span>\n<span class=\"grvsc-line\">\t</span>\n<span class=\"grvsc-line\">httpClient = &http.Client{</span>\n<span class=\"grvsc-line\">  Timeout:   10 * time.Second,</span>\n<span class=\"grvsc-line\">  Transport: t,</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>By increasing connection per host and the total number of idle connection, this will increase the performance and serve more request with minimal server resources.</p>\n<p>Connection pool size and connection per host count can be increased as per server resources and requirements.</p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>In this article, we discussed the problems around the 'net/http' client default configurations. By changing some of the default settings of HTTP Client, we can achieve a High-performance HTTP client for production use. If you want to learn more about http, here is an interesting post on <a href=\"https://www.loginradius.com/blog/engineering/http-security-headers/\">HTTP security headers</a> If you like what you read, share your thoughts in the comment section.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n</style>","frontmatter":{"date":"January 12, 2021","updated_date":null,"title":"How to Use the HTTP Client in GO To Enhance Performance","tags":["Golang","HTTP","Performance"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/68276d4b4277ad09e329598038e91917/14b42/index.jpg","srcSet":"/static/68276d4b4277ad09e329598038e91917/f836f/index.jpg 200w,\n/static/68276d4b4277ad09e329598038e91917/2244e/index.jpg 400w,\n/static/68276d4b4277ad09e329598038e91917/14b42/index.jpg 800w,\n/static/68276d4b4277ad09e329598038e91917/47498/index.jpg 1200w,\n/static/68276d4b4277ad09e329598038e91917/ec6c5/index.jpg 1280w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Mayank Agarwal","github":"mayankagrwal","avatar":null}}}},{"node":{"fields":{"slug":"/engineering/what-is-the-new-go-1-15/"},"html":"<p>Go announced <a href=\"https://blog.golang.org/\">Go 1.15</a> version on 11 Aug 2020. Highlighted updates and features include Substantial improvements to the Go linker, Improved allocation for small objects at high core counts, X.509 CommonName deprecation, GOPROXY supports skipping proxies that return errors, New embedded tzdata package, Several Core Library improvements and more. </p>\n<p>As <a href=\"https://golang.org/doc/go1compat\">Go promise</a> for maintaining backward compatibility. After upgrading to the latest Go 1.15 version, almost all existing Golang applications or programs continue to compile and run as older Golang version.</p>\n<p>Download the latest Go Version from <a href=\"https://golang.org/dl/\">Golang</a>.</p>\n<h3 id=\"operating-system-and-platform-compatibility\" style=\"position:relative;\"><a href=\"#operating-system-and-platform-compatibility\" aria-label=\"operating system and platform compatibility permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Operating system and platform compatibility</h3>\n<h4 id=\"macos\" style=\"position:relative;\"><a href=\"#macos\" aria-label=\"macos permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>macOS</h4>\n<p>Go 1.14 version announced some changes for the macOS. According to announcement  </p>\n<blockquote>\n<p>Go 1.14 is the last release that will run on macOS 10.11 El Capitan. Go 1.15 will require macOS 10.12 Sierra or later.</p>\n</blockquote>\n<p>The lastest macOS 10.15 (Catalina) is no longer supporting 32-bit binaries. Go 1.14 will likely to be the last Go release to support 32-bit binaries on iOS, iPadOS, watchOS, and tvOS (the darwin/arm port). Go continues to support the 64-bit darwin/amd64 port.</p>\n<h4 id=\"windows\" style=\"position:relative;\"><a href=\"#windows\" aria-label=\"windows permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Windows</h4>\n<p>Go now generates Windows ASLR executables when -buildmode=pie cmd/link flag is provided. Go command uses <code>-buildmode=pie</code> by default on Windows.</p>\n<p>The -race and -msan flags now always enable <code>-d=checkptr</code>, which checks uses of unsafe. Pointer. This was previously the case on all OSes except Windows.</p>\n<h4 id=\"android\" style=\"position:relative;\"><a href=\"#android\" aria-label=\"android permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Android</h4>\n<p>Mobile applications were crashing in some devices due to some invalid lld linker versions so now avoiding the crashing the latest Go 1.15 version explicitly selects the lld linker available in recent versions of the NDK. This explicitly lld linker avoids crashes on some devices. it becomes the default NDK linker in a future NDK version.</p>\n<h3 id=\"smaller-binaries--performance-improvements\" style=\"position:relative;\"><a href=\"#smaller-binaries--performance-improvements\" aria-label=\"smaller binaries  performance improvements permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Smaller binaries &#x26; Performance improvements</h3>\n<p>Always new Go 1.15 brings many minor/major performance improvements. The first major improvement has reduced the executable's binary size by almost 5% - 10% as compared to Go 1.14. As Brad Fitzpatrick <a href=\"https://twitter.com/bradfitz/status/1256348714198654976?lang=en\">tweet</a>, test program down from 8.2MB in Go 1.14 to 3.9MB in 1.15. </p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 80.76923076923077%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAABYlAAAWJQFJUiTwAAACiUlEQVQ4y5WTW2/aQBCFnXD3FdvccTAYgzH1BeMQIJCkuTV5iCpVykulqv//X5zOLEJVW6VpH45md737zczxrrTcP+L5y1e8vH7D5u4Fo3gLL9liEK5ovEFz+AHW2Qz2IETDnYv5MR51nLe9GFK6uUW2e8D+8TO29y9YXD4gv3pCsrnDcv8Jq5tnZLQWrz+iNYr+gP2eQHLnFxhFG0Sra4TLPcL8CvPza8wppts7Me5NUpH9ePhvkuLzNTZX1wjyG/iLHTxq04vW8KntINtR67kA2XzgWNFbYuDTfY7vr2tY0Q3s+Ba2l8I+C4Rn7J3p8HhGIGrLfUfcsmL1IJ2WUFNUdPtnGI0ncEdjJIulkOdPoOp1FEoVFMvVN1UolaE3HUiybkGSJBSLRTj9PrLFAlEUwXUH6HY6UBUF5VJJ7HlPSr1JQKMhJgUCdrpdxHGM3W6Hi4s1ujT/F5AknRyAZvsnsERVNJtNjMdjpGkK3/dxcnLYeIzvVmi2IFW1Q8unpwUBzLIM0+lUVMrzarX6HxUSsD+coFatQNcNWJaFDvnGMk0TffK01+vRNx0Kecmq1+tQVfXtCmfxEsOhiyAIEIahiI7joNFoCHES9pJBrVZLJONEnMQwDMiyDE3TSCpUizz0ggiddpugQ+EfH+aqGM5gBnBkiOu6AswQFlfKVXNSs24cgH6YwB0MRPYugZIkERrQGkNqtZrwkce2bRNAPVRHYAbphv5ry64/o7uXUBV99AnIVyagn7JcZri83Ir7mOc5XaMVPG8k9qRpgl5KXV07cNYd6MODp7JB99CdRvRC6IM7Qk0l8zXyheJBhljTDFOs1xQNFVkVsazJKOsyKoaCCvnHr4Vfyg/oqpwpFWDL7wAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"image 1\"\n        title=\"image 1\"\n        src=\"/static/216a02ed439988a46672b5b77a351a6a/e5715/lr-tweet1.png\"\n        srcset=\"/static/216a02ed439988a46672b5b77a351a6a/a6d36/lr-tweet1.png 650w,\n/static/216a02ed439988a46672b5b77a351a6a/e5715/lr-tweet1.png 768w,\n/static/216a02ed439988a46672b5b77a351a6a/dd104/lr-tweet1.png 1064w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 80.76923076923077%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAABYlAAAWJQFJUiTwAAACYUlEQVQ4y5WSW3eaUBCFQV0rUcGIIqgEEbkoF0G8BWM0Mdqmq13NS/vWvvX//4bdYUy72jfz8K05Z2D22XPOCNvTK758/4lvP35hc3xFuD4gWD7Cm20xWexxO56j781g+LO3mOGWKPbFuuemnNdHU2h2DCHJn7Hcv2C1/4Tp3QGL3Qtm90fihPn2A4LFDvHqEUl+QLx+4n9mmyMiyqWbZ+LIdJ0EqhVCcJMcXrpBuNxzQfFjQbEeZ1sWYpH7s0hxQCHEhz98pLodCxV0hiTopfd8wpScTuYP/wkGdMgovsMwWsGO1hSJcAWLKHLONIc5WZBQTESM4JO7NH9iMnKxOXzGw+krtbnHlNCsAM2+A8XwoPTdc2Rcyp/3bdMnxueWr+UWBEFAS+1gmqRIZxk0vYtypUJ5EaVy5SLEUgk32gBCVbphQUVRMB6PEQQB2u0WyuUy59+DrPYhyIrKG1Es4erqCtVqFbIss7v3CjZUA4LWM6GqbViWhU6ng1qtxsL1ep1dt1otzl3mkASv31ru9XrcbpIk8H0fruvyFYRhCMdxIEnS+wR1XedCz/OYQkxVVXZZfC/RpV8kWJWavDHNAaIoYodpmmK32yHPc76Kyx/lH4dFYZZlWC6XLLTdbrFer/+2KoriZYI1+dySQpdvGAZj2zY/0HA4JOcmjZF6+SsbgxEaUh2NhowajYyuddCl+1RpFq/ptc/uBFRoLsViTZRLNPCUK4l/4pvDNs2hMZrAGnlQu7fQDQvJfAU/TOBOYoyjBNJNm/GCGH3ThtY3YTk+BlRjewFH03ZRk5to9mz8BmAjmKWlNCj4AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"image 1\"\n        title=\"image 1\"\n        src=\"/static/f97cca2c10ac4080b1558296d5a61401/e5715/lr-tweet2.png\"\n        srcset=\"/static/f97cca2c10ac4080b1558296d5a61401/a6d36/lr-tweet2.png 650w,\n/static/f97cca2c10ac4080b1558296d5a61401/e5715/lr-tweet2.png 768w,\n/static/f97cca2c10ac4080b1558296d5a61401/dd104/lr-tweet2.png 1064w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Go 1.15 has improved the code build process now unused code is eliminating in the new linker, along with several targeted improvements, such as Clements's CL 230544, which reduces the number of stack and register maps included in the executable.  </p>\n<h3 id=\"standard-library-additions\" style=\"position:relative;\"><a href=\"#standard-library-additions\" aria-label=\"standard library additions permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Standard library additions</h3>\n<p>Always in every new version release Go come with various minor changes and updates to the library. I m including some useful and important changes  </p>\n<h4 id=\"tzdata-package\" style=\"position:relative;\"><a href=\"#tzdata-package\" aria-label=\"tzdata package permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>tzdata Package</h4>\n<p>A new embedded tzdata package was added that permits embedding the timezone database into a program. Importing this package (as import _ \"time/tzdata\") which allows the program to find timezone information without the timezone database on the local system. We can also embed the timezone database by building with -tags timet/zdata. This approach increases the size of the program by about 800 KB. This might be useful and can test some code with the virtualized environments like <a href=\"https://play.golang.org/\">Go playground</a>.</p>\n<h4 id=\"x509-commonname-deprecation\" style=\"position:relative;\"><a href=\"#x509-commonname-deprecation\" aria-label=\"x509 commonname deprecation permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>X.509 CommonName deprecation</h4>\n<p>Go older versions were using CommonName field on X.509 certificates as a hostname if there is no Subject\nAlternative Names, would be disabled by default. If Still want to use this legacy behavior then we need to add x509ignoreCN=0 in the GODEBUG environment variable.</p>\n<h4 id=\"neturl-package\" style=\"position:relative;\"><a href=\"#neturl-package\" aria-label=\"neturl package permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>net/url Package</h4>\n<p>The <code>net/url</code> package adds a new URL. The redacted () method that returns the URL as a string. This is proposed in the <a href=\"https://github.com/golang/go/issues/34855\">Issue 34855</a>. It is a very useful improvement for audit logging and security. It's a simple derivation from the URL.String() that masks the password if exists from the string being passed. It does not modify at all to the URL itself but a copy of it.</p>\n<h3 id=\"summary\" style=\"position:relative;\"><a href=\"#summary\" aria-label=\"summary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Summary</h3>\n<p>Go 1.15 has released with various improvements, bug fixes. We can get all improvements, closed proposals and features details for the Go GitHub repository.</p>\n<h3 id=\"referance\" style=\"position:relative;\"><a href=\"#referance\" aria-label=\"referance permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Referance</h3>\n<ul>\n<li><a href=\"https://blog.golang.org/\">Go Blog</a></li>\n<li><a href=\"https://golang.org/doc/go1.15\">Go 1.15</a></li>\n</ul>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"September 07, 2020","updated_date":null,"title":"What's new in the go 1.15","tags":["Go","Golang","Go 1.15"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/d85b112d59a5149f84548b866984f6db/ee604/index.png","srcSet":"/static/d85b112d59a5149f84548b866984f6db/69585/index.png 200w,\n/static/d85b112d59a5149f84548b866984f6db/497c6/index.png 400w,\n/static/d85b112d59a5149f84548b866984f6db/ee604/index.png 800w,\n/static/d85b112d59a5149f84548b866984f6db/f3583/index.png 1200w,\n/static/d85b112d59a5149f84548b866984f6db/5707d/index.png 1600w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Vijay Singh Shekhawat","github":"code-vj","avatar":null}}}},{"node":{"fields":{"slug":"/engineering/a-journey-from-node-to-golang/"},"html":"<p>Migrating your existing code to a new programming language is a very tedious task. We need to have a proper set of requirements and some obvious benchmarking between the new and existing technology.</p>\n<p>So here our journey started to transform (not convert) our existing code to a new language. You might be thinking why I have used the word transformation instead of conversion, so -</p>\n<p><strong>Conversion:</strong> Conversion is just about writing your existing code in different languages as it is.</p>\n<p><strong>Transformation:</strong> Transformation is about leveraging all possible benefits of a new language and convert accordingly.</p>\n<h2 id=\"why-we-decided-to-change\" style=\"position:relative;\"><a href=\"#why-we-decided-to-change\" aria-label=\"why we decided to change permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Why we decided to change?</h2>\n<p>The idea of migrating code to a new programming language started with a simple requirement: we wanted to take our cloud solution to on-premise as well. Till now, our services were written in NodeJS for a cloud solution and it was doing pretty well. The performance was also good but there is nothing that cannot be improved upon. So, along with performance improvement, we started to find out that <strong>can we make a GUI or CLI using existing NodeJS code that can take our solution on-premise?</strong></p>\n<p>Answer for that was practically YES. but, technically NO. If we’re writing apps with a GUI, Node can’t do it on its own. We had to use some other projects which provide GUI creation capabilities (eg: ElectronJS, NW.js, etc). Making CLI seemed doable but there were also problems like the inablility to have single file distribution for our code. And the ability to download a single file and execute commands - without an installer, or even a setup process - does wonders for a user. This also makes the product easily backward-compatible.</p>\n<p>Also, another factor came in that it was better to switch to a technology that works closely with gRPC.</p>\n<p>So, we drew out a few goals for our new solution</p>\n<ul>\n<li>Zero deployment dependencies</li>\n<li>Performance upgradation</li>\n<li>Single file distribution</li>\n<li>Easily compatible with gRPC</li>\n<li>Good memory management</li>\n<li>Better readability and maintainability</li>\n</ul>\n<p>After research with our requirement, we were able to figure out that we can achieve these with GoLang, developed by Google.\nOn the basis of our research, we also did some benchmarking on different node js frameworks and GoLang.</p>\n<p><strong>Benchmarking sever</strong> we’ve used with below configurations</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 536px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 37.5%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABJ0AAASdAHeZh94AAABcklEQVQoz12R3W6CQBCFef+XsDY22qQ2aRsfQL2xWu2VIrIq/0v9VyICoqc7Y/BCki+zO+yZPQe0p3IZ5fIzSqUn1GqvqFReUK3W0Gg0UH+ro15/x8fnF9rtNprNJlqtFtdi/Yi2XC6xWq0YGYag/Xq9ge/7GOs6hiMd680G+/0eu92O2W6393UBvSe08/mM0+nEJEnCNU1THmiaApPJBFKGyPOc+1mW3Stpi30xQzlcgZ7L5YLr9cpCOhQEAQ+cChOmEOx8sVhwlVIyYXiDHJKGDGmDwS8sy2KEErquh0TdSHU0HMG2LYwnBnQV37LmmM8tNSRU712+NJSB+kRrdhfH8W0gCU0xhWEYcBwXKTlUkYWYwfV81XPY7Ww2R6CcpVnKcQvukclhvz9QlvfcpMgUPc/P+FNRyA0N45jKled5Ch/HY6wipqy5kXFkQut1e+h0vtHt/fDfi6JICY5wbBvG2IAfSI5CPRpE9XCIGDr7yD95q00P4KxcEAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"server\"\n        title=\"server\"\n        src=\"/static/0bf48f56fa9abf07626bc03e9f1cccad/2d920/server.png\"\n        srcset=\"/static/0bf48f56fa9abf07626bc03e9f1cccad/2d920/server.png 536w\"\n        sizes=\"(max-width: 536px) 100vw, 536px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p><strong>The benchmarking result</strong> was pretty much similor to what we are thinking. Here are the benchmarking results -</p>\n<h4 id=\"100000-requests-5000-concurrency\" style=\"position:relative;\"><a href=\"#100000-requests-5000-concurrency\" aria-label=\"100000 requests 5000 concurrency permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>100000 Requests 5000 Concurrency</h4>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 17.07692307692308%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABJ0AAASdAHeZh94AAAAtklEQVQI1yWO24qDMBRF/f8/c6xYI3TAcTA1TaJipY54RVlNMw+Hc9n7LHaQJAlhGHKJL3y5XilF0zTkeU6aptR146pGCEFZSrquo6oqr7VtS1H8cLt9Y4zhwwqEE67XhDiO3UPJuq4cx8HweiHlnX3f3W3hLiXDMHCeJ89n5zTpfdZaB7OM48hvURBkWUYURYhMME2TBy7L4g1aG+Z59rvWmr7v2baNPwdWD+XnT0pj/4HKJX8DRDXcuO7y3E8AAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"sheet1\"\n        title=\"sheet1\"\n        src=\"/static/6233a9b39dd838b4a50d59199181f7d5/e5715/sheet1.png\"\n        srcset=\"/static/6233a9b39dd838b4a50d59199181f7d5/a6d36/sheet1.png 650w,\n/static/6233a9b39dd838b4a50d59199181f7d5/e5715/sheet1.png 768w,\n/static/6233a9b39dd838b4a50d59199181f7d5/2cffa/sheet1.png 1092w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h4 id=\"100000-requests-7500-concurrency\" style=\"position:relative;\"><a href=\"#100000-requests-7500-concurrency\" aria-label=\"100000 requests 7500 concurrency permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>100000 Requests 7500 Concurrency</h4>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 16.76923076923077%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABJ0AAASdAHeZh94AAAAs0lEQVQI1zWOyQ6CQBQE/f9Pw0BAxANBZUARCDAQHJawlMMkHjqvDy9ddbJtG8uy+N/X601RFIRhyMX3Tc/zHM/zeD5jqqoiTVOCa0BZlkRRRBDcyLIMR2+cPNfF1XEcByEE8zyzbRtN0yCShGVZmKaJRPe269j3nbqu9W/Cuq4Gln1y+m/P437Xg5psnc/4Vx+lBsZxNJGyNbZKKYZhMAYH5ABKKY3lATosP3qw7VpEHPMDW8vcvhsKSCoAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"sheet2\"\n        title=\"sheet2\"\n        src=\"/static/6da55e8d7c1586aca7b288226698ae0e/e5715/sheet2.png\"\n        srcset=\"/static/6da55e8d7c1586aca7b288226698ae0e/a6d36/sheet2.png 650w,\n/static/6da55e8d7c1586aca7b288226698ae0e/e5715/sheet2.png 768w,\n/static/6da55e8d7c1586aca7b288226698ae0e/db3a5/sheet2.png 1087w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>There was a big difference. For better clarity let’s see the below graphs.</p>\n<h3 id=\"total-time-taken-for-tests\" style=\"position:relative;\"><a href=\"#total-time-taken-for-tests\" aria-label=\"total time taken for tests permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Total Time taken for Test(s)</h3>\n<p>In the below chart, we can clearly see that Golang won the competition and Hapi has taken the maximum time to finish the test.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 600px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 61.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAAB60lEQVQoz4WSvWsUQRjG7y+xFCxFLVXsRCw1VQJWWghpxCbGwsRCtIohIpgi2ikoCn6QJhI5QkwiRDAkomcCgXjx7vbjZmdn5/NxZnY37mqCAw87O/Pub573mW1wzhEEAaIo8ur1ev49SRKEYeglhIAbxhj8bzTKQveRe+4nrTWkzOXmB8nVNkryQbDcVd1Z1Wm9zjrMsgyubafqacpKWEdKaXCh8Wolw0srxlVtz3hnFYdxHMNBqyf/nRTNDE6PE5y8RRDS+q5UBlzaWIrlBiHEA6WUe3k5ZEA0Hs1xPF8S6Kca5+8lOHc3Qc+uv10VmJnnCBONydkMFyYoPv2QObB0mMOMb8UBW22F46MEF21xRLWHnb2ToNvXGJyiODpC8O2nwugzhiPX+5hfF3Vg6azU5i+FM7cJLj38F3hlOsWpMYLWrsLYC4ZjNwiaG4VDxpi9EEdX2NiRGH5M8eRDhq1OHVi27ICXp+k+QPHnP1Q6D7T5VeHQMMHVGWaBGiduEgzcd0Bj4YmF5MChB6lv+XtbY+Qpw+FrxLZcOPTZWSkpsN2O8WZxF8vrXQQxxexKF80vISjjeP85xJwVTTkW1kK8W+4gIhlWW328/tjBTje1Sakc6DLzt26cVXdSmacqhGJNV+blutmbO9RvekJ3qnRQx1IAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"total-time-taken-for-test\"\n        title=\"total-time-taken-for-test\"\n        src=\"/static/ec9779e9c601a6da5e89dfb80919b4bf/0a47e/total-time-taken-for-test.png\"\n        srcset=\"/static/ec9779e9c601a6da5e89dfb80919b4bf/0a47e/total-time-taken-for-test.png 600w\"\n        sizes=\"(max-width: 600px) 100vw, 600px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h3 id=\"request-per-second-s-and-transfer-rate-kbs\" style=\"position:relative;\"><a href=\"#request-per-second-s-and-transfer-rate-kbs\" aria-label=\"request per second s and transfer rate kbs permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Request per second (s) and Transfer Rate kb/s</h3>\n<p>In the below chart, we can see that Golang served maximum requests per second.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 600px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 61.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAAB2ElEQVQoz5VTv08bMRi9f46lUgcGVAm1gg1VlVi6wN6NjaErIztDpTIEUFSRENoiUZHyo6mSlIQL8V3uh++Su3Nev88+Q0ClEpY+3/v82c/P72wnTVMMh0Mdo9EIvufBHQgI4cH3fQRBAI++wnUhaI6guhACvI7bdDrFbHOUUsjzXBdssReASAJEYUgRIUoSTPo9JL6HMI71JkzI83m9Dc6dLMuQ0AJbTFtXKOIQTP14srIEj4geEDIoisLIJ9xZeQN5XLvLn9u0Qiml3rWgo7ffLiFuHGqFnP9LyVMxozAvFRXoEKE8rpucvS1VznqscUlgT2LxfxXaUGQJx51iJpzxWONyQ0ebbT0srELj4fj3L2S9P6ZWeqStGI+Rnp/p+YoG8uEtVHmNtMKYrgLvQGdE990ywtoXXbz9sIabzQ2N84sf8D7tGFa3g9bCC+RRqNP++iqiulnjlC5gQiLXtyX2Xy5Afa2iTaPf368h+LgBSbi5tY3rlUUkhE+O2rian6PrFeFiAJy9fgVZrRhC7vjaRLHE58YAzd0KkpsuTroZGruHGLea6MdMco7w9Bu8OEelfo3ewR4mdMzazwCXe1Wkbh/FFMbD+ydk/rZ6or9/ZOoBto05/gIrAJAmZs9rvQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"request-per-second-and-transfer-rate-kb-s\"\n        title=\"request-per-second-and-transfer-rate-kb-s\"\n        src=\"/static/bcfe26c697b7f0b731fbc82f581b4e67/0a47e/request-per-second-and-transfer-rate-kb-s.png\"\n        srcset=\"/static/bcfe26c697b7f0b731fbc82f581b4e67/0a47e/request-per-second-and-transfer-rate-kb-s.png 600w\"\n        sizes=\"(max-width: 600px) 100vw, 600px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h3 id=\"request-per-second-s-and-time-per-request-ms\" style=\"position:relative;\"><a href=\"#request-per-second-s-and-time-per-request-ms\" aria-label=\"request per second s and time per request ms permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Request per second (s) and Time per request (ms)</h3>\n<p>The below chart is showing that the Number of requests is very high compared to other node js frameworks.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 600px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 61.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAAB20lEQVQoz42TW2vUQBTH8y2toKD46gcQH3wX9KldWZ988PIkoriF9qUEL1Qtsm2x2wqCuN0um5hkN5vrZC5/55xsErUqDpzMf86Z+c05kxknz3MEQcC2WCwQRXN4foj5PLI2RxzH3Ieex/EwDNmiKEKWZaBmjEHTHBpIKVdOg7IyGH8XSJMYSZJguVwitwvFdILEwpcrX5qm0FrzOuob7RCsKIo2YIymLa027GttlQnFf/H/ZhaoUIkSQhrcelrgq68403NA/W9QB1Q1sBAaFzcyjCaSgUrptpT/NQaSEKJg4NX7GU7OamAlNdRfFkr1Z81AyqTJ8Eq/AzbWnCsZ6cbPvp/GHZB2qUQLHE0qnvD4rYB7VFpNWdAR0NkqjAOFO4PCViUZ8vKjwCyqeJ5uMhRlV/LxrL5PN55kePCu1lvDEr0dzfpoXGGtl4MQtNGlexkOvHoesRz+m1ry/Vtbt8Hh1IYK3HwO9O6+AqZDPDwErl3fgX60jpEPXLjtIxi8gBQVLvcLvO4/A2bfuHiHyForJGkGd9/Hl7195KGHQ1v63sBFeXKAcQLsup8Qf3iDKFNw35/ibGsTpX1lu8cxPm9uI5+eQjUvpXs+knepizv/Ne3XoHtsulXE+AHk4pLmxln/1AAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"request-per-second-and-time-per-request\"\n        title=\"request-per-second-and-time-per-request\"\n        src=\"/static/dcf7cdee87f4343ba96554487cd3e553/0a47e/request-per-second-and-time-per-request.png\"\n        srcset=\"/static/dcf7cdee87f4343ba96554487cd3e553/0a47e/request-per-second-and-time-per-request.png 600w\"\n        sizes=\"(max-width: 600px) 100vw, 600px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h3 id=\"total-data-transferred\" style=\"position:relative;\"><a href=\"#total-data-transferred\" aria-label=\"total data transferred permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Total Data Transferred</h3>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 600px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 61.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAACCElEQVQoz32TzWsTQRiHVwVLpQe9FPHgH+BJBL8FJQj+BcWDqEUQgp8HsYKoFxGJB6U99KJgg1DwIHiyfqGoeBALobX0YhNE0xhjdZM0yc7uzM7j7G42iU3owDAfvPN7n/djLCkltVod6bksVX0qyw0a9RqOcBGlEtVyFVcso2p5qo5DvvILISS+nadRtXE9idYa3/fD1QoE6/U6wnUBTWvo9l4rPzpqFZ59s+qWWSTWEowvoxnrRObjrwSPPkp6Dd3DcTAsz/Mol8shZeBFBTShR8XQWIPk+B/UtwXc0jxuZY5spcjS3x9QWkB5jrHrQUgHvo49GsFTac2ZkQ/kjhzEHt1K8fVGBieT3BpNwJVNyOJ8RGrEViUMPZrcDk9okpfekT20F/vuIIUXfax9eIyrt3fAWQs3P4Mf+pa9c/hfSoxBLJhL7Me+t5nCyw30pU9wPbULLqxBFuaaoXUQKqVCOtdUuV1+M1UHYWKfIQwE+1k/cZxrqZ1w3sJbnG0SqjbhaoJhDi+/J3f4gCHcYgQH6E+f5Mad3XBxnRH80i3YXZR2yEfva4bPvSG7Zzt2aoDClIX1YIiRm9vgtIVcnOkOOc5d0OCO+QlCiGia/XRO8Gn6O/nnzyhlnvDz62MmZ9/yOTOFn3mKU/ltPoQX2gZvg2hbRels2ZC04yb4H7K5rmxsvaKx/wHhpmMjBdxxEQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"chart\"\n        title=\"chart\"\n        src=\"/static/b6d6b3964620b206772933fe75bd7d45/0a47e/chart.png\"\n        srcset=\"/static/b6d6b3964620b206772933fe75bd7d45/0a47e/chart.png 600w\"\n        sizes=\"(max-width: 600px) 100vw, 600px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>All the data clearly shows the direction so we decided to move to GoLang.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"August 11, 2020","updated_date":null,"title":"A journey from Node to GoLang","tags":["NodeJs","Golang","Performance"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/0cb80044e5634c85f2b1002c7c3661d8/2a4de/node-go.png","srcSet":"/static/0cb80044e5634c85f2b1002c7c3661d8/69585/node-go.png 200w,\n/static/0cb80044e5634c85f2b1002c7c3661d8/497c6/node-go.png 400w,\n/static/0cb80044e5634c85f2b1002c7c3661d8/2a4de/node-go.png 600w","sizes":"(max-width: 600px) 100vw, 600px"}}},"author":{"id":"Narendra Pareek","github":"pareek-narendra","avatar":null}}}},{"node":{"fields":{"slug":"/engineering/custom-encoders-in-the-mongo-go-driver/"},"html":"<p>The official supported drivers for Mongo for Go have been officially released for several months now and is slowly seeing more usage. Although many of the features of standard Mongo drivers have been implemented within the supported driver, the documentation for a majority of the features are still in the process of being created. This post will provide some information on how to set up custom JSON encoders so you can change how BSON operators are processed whenever Mongo documents are marshalled into JSON. For this blog, a custom date and object id encoder will be created to handle the BSON operators and transform them into more easily processed JSON.</p>\n<p>This blog assumes that you have a basic understanding of Go and how to write some code in the language. If you want to follow along with the guide, you will also require a working Mongo instance, as well as your environment set up for Go.</p>\n<p>Before interacting with the database, we can set up a quick Go application that finds data from a Mongo database and outputs it. For this example, the Mongo database is set up with a collection containing documents with a name, a date and the object id. For our blog, the Mongo document that is being worked with is quite simple:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\"> : </span><span class=\"mtk11\">ObjectId</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;5de6b0850f3c7b5cce642529&quot;</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&quot;Name&quot;</span><span class=\"mtk1\"> : </span><span class=\"mtk8\">&quot;dateOne&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&quot;Date&quot;</span><span class=\"mtk1\"> : </span><span class=\"mtk11\">ISODate</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;2019-04-08T11:55:02.658Z&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>A simple main function that retrieves data from Mongo and outputs the JSON string is as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">func</span><span class=\"mtk1\"> </span><span class=\"mtk11\">main</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\"> </span><span class=\"mtk4\">struct</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\tID   primitive.ObjectID </span><span class=\"mtk8\">`bson:&quot;_id&quot;`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\tName </span><span class=\"mtk10\">string</span><span class=\"mtk1\">             </span><span class=\"mtk8\">`bson:&quot;Name&quot;`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\tDate primitive.DateTime </span><span class=\"mtk8\">`bson:&quot;Date&quot;`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk12\">ctx</span><span class=\"mtk1\">, </span><span class=\"mtk12\">cancel</span><span class=\"mtk1\"> := context.</span><span class=\"mtk11\">WithTimeout</span><span class=\"mtk1\">(context.</span><span class=\"mtk11\">Background</span><span class=\"mtk1\">(), </span><span class=\"mtk7\">10</span><span class=\"mtk1\">*time.Second)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk12\">client</span><span class=\"mtk1\">, </span><span class=\"mtk12\">connErr</span><span class=\"mtk1\"> := mongo.</span><span class=\"mtk11\">Connect</span><span class=\"mtk1\">(ctx, options.</span><span class=\"mtk11\">Client</span><span class=\"mtk1\">().</span><span class=\"mtk11\">ApplyURI</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> connErr != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\tlog.</span><span class=\"mtk11\">Fatal</span><span class=\"mtk1\">(connErr)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk12\">collection</span><span class=\"mtk1\"> := client.</span><span class=\"mtk11\">Database</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;test&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">Collection</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;dates&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk12\">filter</span><span class=\"mtk1\"> := bson.M{</span><span class=\"mtk8\">&quot;Name&quot;</span><span class=\"mtk1\">: </span><span class=\"mtk8\">&quot;dateOne&quot;</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk12\">findErr</span><span class=\"mtk1\"> := collection.</span><span class=\"mtk11\">FindOne</span><span class=\"mtk1\">(ctx, filter).</span><span class=\"mtk11\">Decode</span><span class=\"mtk1\">(&result)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> findErr != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\tlog.</span><span class=\"mtk11\">Fatal</span><span class=\"mtk1\">(findErr)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\tfmt.</span><span class=\"mtk11\">Print</span><span class=\"mtk1\">(result.Date)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk12\">data</span><span class=\"mtk1\">, </span><span class=\"mtk12\">writeErr</span><span class=\"mtk1\"> := bson.</span><span class=\"mtk11\">MarshalExtJSON</span><span class=\"mtk1\">(result, </span><span class=\"mtk4\">false</span><span class=\"mtk1\">, </span><span class=\"mtk4\">false</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> writeErr != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\tlog.</span><span class=\"mtk11\">Fatal</span><span class=\"mtk1\">(writeErr)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\tfmt.</span><span class=\"mtk11\">Print</span><span class=\"mtk1\">(</span><span class=\"mtk11\">string</span><span class=\"mtk1\">(data))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk11\">cancel</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The function MarshalExtJSON is a part of the bson package that is a part of the driver. It uses a default registry to define the rules when converting Mongo primitive types into JSON. The arguments it takes are the Go struct being passed in, whether the result should be returned in canonical form (For more details, check this <a href=\"https://docs.mongodb.com/manual/reference/mongodb-extended-json/%5D(https://docs.mongodb.com/manual/reference/mongodb-extended-json/)\">link</a>, and whether HTML strings are escaped.</p>\n<p>The output of this function when reading our document produces a JSON string with all the BSON operators included.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">: {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk8\">&quot;$oid&quot;</span><span class=\"mtk1\">:</span><span class=\"mtk8\">&quot;5de6b0850f3c7b5cce642529&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk8\">&quot;Name&quot;</span><span class=\"mtk1\">:</span><span class=\"mtk8\">&quot;dateOne&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk8\">&quot;Date&quot;</span><span class=\"mtk1\">:{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk8\">&quot;$date&quot;</span><span class=\"mtk1\">:</span><span class=\"mtk8\">&quot;2019-04-08T11:55:02.658Z&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Using custom encoders, we can change how the bson package marshals the JSON and remove all the BSON operators. The first thing to do is to define package level variables that will hold the types of the Mongo primitives that need to be changed in the JSON response. Outside the main function, include these two lines:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">tOID</span><span class=\"mtk1\"> = reflect.</span><span class=\"mtk11\">TypeOf</span><span class=\"mtk1\">(primitive.ObjectID{})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">tDateTime</span><span class=\"mtk1\"> = reflect.</span><span class=\"mtk11\">TypeOf</span><span class=\"mtk1\">(primitive.</span><span class=\"mtk11\">DateTime</span><span class=\"mtk1\">(</span><span class=\"mtk7\">0</span><span class=\"mtk1\">))</span></span></code></pre>\n<p>Next, we can make new functions to customize how these types are handled. For the date encoding, we want to have the Date key matched with the returned date string.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">func</span><span class=\"mtk1\"> </span><span class=\"mtk11\">dateTimeEncodeValue</span><span class=\"mtk1\">(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) </span><span class=\"mtk10\">error</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">jDateFormat</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;2006-01-02T15:04:05.999Z&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> !val.</span><span class=\"mtk11\">IsValid</span><span class=\"mtk1\">() || val.</span><span class=\"mtk11\">Type</span><span class=\"mtk1\">() != tDateTime {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk15\">return</span><span class=\"mtk1\"> bsoncodec.ValueEncoderError{Name: </span><span class=\"mtk8\">&quot;DateTimeEncodeValue&quot;</span><span class=\"mtk1\">, Types: []reflect.Type{tDateTime}, Received: val}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk12\">ints</span><span class=\"mtk1\"> := val.</span><span class=\"mtk11\">Int</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk12\">t</span><span class=\"mtk1\"> := time.</span><span class=\"mtk11\">Unix</span><span class=\"mtk1\">(</span><span class=\"mtk7\">0</span><span class=\"mtk1\">, ints*</span><span class=\"mtk7\">1000000</span><span class=\"mtk1\">).</span><span class=\"mtk11\">UTC</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">return</span><span class=\"mtk1\"> vw.</span><span class=\"mtk11\">WriteString</span><span class=\"mtk1\">(t.</span><span class=\"mtk11\">Format</span><span class=\"mtk1\">(jdateFormat))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The parameters in this function are pre-defined within the driver package of the driver. This involves passing in the BSON encoding context, the value writer and the value that is being processed. The value writer and the value are the parameters that we use within our function.</p>\n<p>First, we check if the value passed in is the correct type. If there is an issue with the value, then an error is thrown during the encoding. Next, we can set the format we want our date string to appear in, and process our value into a Go Time object. After that, we can use the value writer to write the formatted date into our JSON string.</p>\n<p>Similar to the custom date encoding, the object id encoding function has the same structure.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">func</span><span class=\"mtk1\"> </span><span class=\"mtk11\">objectIDEncodeValue</span><span class=\"mtk1\">(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) </span><span class=\"mtk10\">error</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> !val.</span><span class=\"mtk11\">IsValid</span><span class=\"mtk1\">() || val.</span><span class=\"mtk11\">Type</span><span class=\"mtk1\">() != tOID {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk15\">return</span><span class=\"mtk1\"> bsoncodec.ValueEncoderError{Name: </span><span class=\"mtk8\">&quot;ObjectIDEncodeValue&quot;</span><span class=\"mtk1\">, Types: []reflect.Type{tOID}, Received: val}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk12\">s</span><span class=\"mtk1\"> := val.</span><span class=\"mtk11\">Interface</span><span class=\"mtk1\">().(primitive.ObjectID).</span><span class=\"mtk11\">Hex</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">return</span><span class=\"mtk1\"> vw.</span><span class=\"mtk11\">WriteString</span><span class=\"mtk1\">(s)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>First, we check if the type is valid, and if it is, we simply write out the object id as a hex string. To create the hex string, we first convert the value into an interface, then cast it as an object id to allow the Hex function to be called.</p>\n<p>Now that our two functions are created to handle the BSON types, we can create our custom registry.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">func</span><span class=\"mtk1\"> </span><span class=\"mtk11\">createCustomRegistry</span><span class=\"mtk1\">() *bsoncodec.RegistryBuilder {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">primitiveCodecs</span><span class=\"mtk1\"> bson.PrimitiveCodecs</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk12\">rb</span><span class=\"mtk1\"> := bsoncodec.</span><span class=\"mtk11\">NewRegistryBuilder</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        bsoncodec.DefaultValueEncoders{}.</span><span class=\"mtk11\">RegisterDefaultEncoders</span><span class=\"mtk1\">(rb)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        bsoncodec.DefaultValueDecoders{}.</span><span class=\"mtk11\">RegisterDefaultDecoders</span><span class=\"mtk1\">(rb)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\trb.</span><span class=\"mtk11\">RegisterEncoder</span><span class=\"mtk1\">(tDateTime, bsoncodec.</span><span class=\"mtk11\">ValueEncoderFunc</span><span class=\"mtk1\">(dateTimeEncodeValue))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\trb.</span><span class=\"mtk11\">RegisterEncoder</span><span class=\"mtk1\">(tOID, bsoncodec.</span><span class=\"mtk11\">ValueEncoderFunc</span><span class=\"mtk1\">(objectIDEncodeValue))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\tprimitiveCodecs.</span><span class=\"mtk11\">RegisterPrimitiveCodecs</span><span class=\"mtk1\">(rb)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk15\">return</span><span class=\"mtk1\"> rb</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>In this function, we are setting up our registry to use our custom encoders, while also setting up default encoders for all other types that are being marshalled. Using the bsoncodec package, the NewRegistryBuilder function is called to initialize a new registry. Next, we set up this registry with the default encoders and decoders that are pre-programmed in the driver using RegisterDefaultEncoders. During this step, we can also register encoders and decoders for raw types by calling RegisterPrimitiveCodecs. Finally, we can include our custom encoders by calling RegisterEncoder on the custom registry struct. Our encoder will be called whenever the type defined in the first argument in RegisterEncoder is found in the struct being marshalled.</p>\n<p>To ensure our new custom registry is being used, we have to do two things. The first is to build the custom registry. This should be done before the marshalling of the struct.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">customRegistry</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">createCustomRegistry</span><span class=\"mtk1\">().</span><span class=\"mtk11\">Build</span><span class=\"mtk1\">()</span></span></code></pre>\n<p>Next, we need to change the marshalling method to use the new custom registry instead of the default one. We can do this by changing the method being used to marshal the struct.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">customData</span><span class=\"mtk1\">, </span><span class=\"mtk12\">writeErr</span><span class=\"mtk1\"> := bson.</span><span class=\"mtk11\">MarshalExtJSONWithRegistry</span><span class=\"mtk1\">(customRegistry, result, </span><span class=\"mtk4\">false</span><span class=\"mtk1\">, </span><span class=\"mtk4\">false</span><span class=\"mtk1\">)</span></span></code></pre>\n<p>The function MarshalExtJSONWithRegistry takes the same parameters as MarshalExtJSON, but also requires a custom registry to be passed in as the first parameter. We pass in the custom registry we created into the method to allow the marshalling to use our custom encoders. As a result, when printing our new JSON string output, we get this:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">{</span><span class=\"mtk8\">&quot;_id&quot;</span><span class=\"mtk1\">:</span><span class=\"mtk8\">&quot;5de6b0850f3c7b5cce642529&quot;</span><span class=\"mtk1\">,</span><span class=\"mtk8\">&quot;Name&quot;</span><span class=\"mtk1\">:</span><span class=\"mtk8\">&quot;dateOne&quot;</span><span class=\"mtk1\">,</span><span class=\"mtk8\">&quot;Date&quot;</span><span class=\"mtk1\">:</span><span class=\"mtk8\">&quot;2019-04-08T11:55:02.658Z&quot;</span><span class=\"mtk1\">}</span></span></code></pre>\n<p>The Mongo driver for Go is still in active development and new versions continue to be released. Hopefully this blog provides some useful information on how the driver works while new documentation is being created.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n</style>","frontmatter":{"date":"December 03, 2019","updated_date":null,"title":"Custom Encoders in the Mongo Go Driver","tags":["Go","Golang","MongoDriver"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.25,"src":"/static/0bf88d6b53aaaf119a2556b41f4c8383/ee604/mongo-drivers.png","srcSet":"/static/0bf88d6b53aaaf119a2556b41f4c8383/69585/mongo-drivers.png 200w,\n/static/0bf88d6b53aaaf119a2556b41f4c8383/497c6/mongo-drivers.png 400w,\n/static/0bf88d6b53aaaf119a2556b41f4c8383/ee604/mongo-drivers.png 800w,\n/static/0bf88d6b53aaaf119a2556b41f4c8383/30c15/mongo-drivers.png 936w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Chris Yee","github":null,"avatar":null}}}}]}},"pageContext":{"tag":"Golang"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}