{"componentChunkName":"component---src-templates-tag-js","path":"/tags/mongo-driver/","result":{"data":{"site":{"siteMetadata":{"title":"LoginRadius Blog"}},"allMarkdownRemark":{"totalCount":1,"edges":[{"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/5101a7134dd4fbb552b2c92ea342e1e4/58556/mongo-drivers.webp","srcSet":"/static/5101a7134dd4fbb552b2c92ea342e1e4/61e93/mongo-drivers.webp 200w,\n/static/5101a7134dd4fbb552b2c92ea342e1e4/1f5c5/mongo-drivers.webp 400w,\n/static/5101a7134dd4fbb552b2c92ea342e1e4/58556/mongo-drivers.webp 800w,\n/static/5101a7134dd4fbb552b2c92ea342e1e4/5d27d/mongo-drivers.webp 936w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Chris Yee","github":null,"avatar":null}}}}]}},"pageContext":{"tag":"MongoDriver"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}