{"componentChunkName":"component---src-templates-blog-list-template-js","path":"/engineering/17","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"excerpt":"HTTP (hypertext transfer protocol) is a communication protocol that transfers data between client and server. HTTP requests are very…","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,"description":"In this post, we will discuss how to make HTTP requests for higher performance in Go, and also how to tune it.","title":"How to Use the HTTP Client in GO To Enhance Performance","tags":["Golang","HTTP","Performance"],"pinned":null,"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":{"excerpt":"One fairly popular question that got asked on programming bulletin boards has to do with the similarities and differences between React’s…","fields":{"slug":"/engineering/react-constructor-get-initial-state/"},"html":"<p>One fairly popular question that got asked on programming bulletin boards has to do with the similarities and differences between React’s <code>constructor</code> and the built in method <code>getInitialState</code>. While the simple answer to this question is indeed simple: “getInitialState is the ES5 friendly method to define the initial state of a React component,” there are a couple more details around <code>getInitialState</code> as well as React’s ES5 support that are interesting and useful to highlight.</p>\n<h2 id=\"constructor-vs-getinitialstate-with-or-without-classes\" style=\"position:relative;\"><a href=\"#constructor-vs-getinitialstate-with-or-without-classes\" aria-label=\"constructor vs getinitialstate with or without classes 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>Constructor vs getInitialState: With or without Classes:</h2>\n<p>One of the fundamental differences between ES5 and ES6 in regards to React implementation is the new <code>class</code> keyword. It allows definition of React components as classes, which is a familiar data structure for anyone who has had experience with more traditional object-oriented languages such as Java or C++. The class structure also allows for natural organization of the component’s elements like state, props, lifecycle methods and member functions. However, ES5 did not provide the same convenience. So instead of defining a React component as a class:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">HelloWorld</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">React</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Component</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">render</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Hello World</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>You would rely on a helper module called <code>create-react-class</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">createReactClass</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;create-react-class&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">HelloWorld</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">createReactClass</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">render</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Hello World</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span></code></pre>\n<p>And it is within the object passed into <code>create-react-class</code> that you could define an initial state by populating the <code>getInitialState</code> attribute:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">HelloWorld</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">createReactClass</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">getInitialState</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> {</span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">props</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">render</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Hello </span><span class=\"mtk4\">{this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">state</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span></code></pre>\n<p>Which, in ES6 implementation would be the equivalent of:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">HelloWorld</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">React</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Component</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span><span class=\"mtk12\">props</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">super</span><span class=\"mtk1\">(</span><span class=\"mtk12\">props</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">state</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">props</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">render</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Hello </span><span class=\"mtk4\">{this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">state</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<h2 id=\"autobinding\" style=\"position:relative;\"><a href=\"#autobinding\" aria-label=\"autobinding 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>Autobinding</h2>\n<p>One difference worth noting is that the <code>create-react-class</code> method automatically binds <code>this</code> to every attribute method. This no longer holds true if you define React components using the common ES6 class syntax, making it so that you have to manually bind <code>this</code> to internal methods:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">HelloWorld</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">React</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Component</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span><span class=\"mtk12\">props</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">super</span><span class=\"mtk1\">(</span><span class=\"mtk12\">props</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">state</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">props</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">changeName</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">changeName</span><span class=\"mtk1\">.</span><span class=\"mtk11\">bind</span><span class=\"mtk1\">(</span><span class=\"mtk4\">this</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">changeName</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setState</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;World&quot;</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Or otherwise use the “arrow function” shorthand which takes care of binding:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">HelloWorld</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">React</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Component</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span><span class=\"mtk12\">props</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">super</span><span class=\"mtk1\">(</span><span class=\"mtk12\">props</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">state</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">props</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">changeName</span><span class=\"mtk1\"> = () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setState</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;World&quot;</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<h2 id=\"parting-words\" style=\"position:relative;\"><a href=\"#parting-words\" aria-label=\"parting words 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>Parting Words</h2>\n<p>Since the update to ES6, there have been multiple new React iterations. You could now forgo the <code>constructor</code> declaration altogether and just declare <code>state</code> inline as a class member, or utilize React Hooks as a new way to initialize states. However, the ES5 support remains useful for legacy systems and adds to the overall flexibility of React as a toolset.</p>\n<p>You can read more about React's ES5 support <a href=\"https://reactjs.org/docs/react-without-es6.html\">in the official doc entry here</a>, and <a href=\"https://reactjs.org/blog/2015/01/27/react-v0.13.0-beta-1.html\">the v0.13.0 beta release blog entry here</a>, for the respective ES6 changes.</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 .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk17 { color: #808080; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n</style>","frontmatter":{"date":"January 05, 2021","updated_date":null,"description":"No ES6? No problem. getInitialState is the ES5 friendly method to define the initial state of a React component.","title":"Constructor vs getInitialState in React","tags":["JavaScript","React"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/4fcf496b1fdd8d1d7ae98e1ab30f19b6/ee604/index.png","srcSet":"/static/4fcf496b1fdd8d1d7ae98e1ab30f19b6/69585/index.png 200w,\n/static/4fcf496b1fdd8d1d7ae98e1ab30f19b6/497c6/index.png 400w,\n/static/4fcf496b1fdd8d1d7ae98e1ab30f19b6/ee604/index.png 800w,\n/static/4fcf496b1fdd8d1d7ae98e1ab30f19b6/efc77/index.png 865w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Nathan Nguyen","github":"nathannguyenn","avatar":null}}}},{"node":{"excerpt":"In JavaScript, web workers allow developers to benefit from parallel programming. Parallel programming enables various computations to be…","fields":{"slug":"/engineering/web-workers/"},"html":"<p>In JavaScript, web workers allow developers to benefit from parallel programming. Parallel programming enables various computations to be performed at the same time by applications. </p>\n<p>Web Workers are a browser feature that allows scripts to be executed on a separate thread from the main execution thread of your web application. This allows the main thread of your web application to run without being blocked by slow scripts in your application.</p>\n<h3 id=\"isnt-javascript-already-asynchronous\" style=\"position:relative;\"><a href=\"#isnt-javascript-already-asynchronous\" aria-label=\"isnt javascript already asynchronous 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>Isn't JavaScript already asynchronous?</h3>\n<p>Well, sort of. This has been something that had confused me many a time when I was initially learning about JavaScript. JavaScript a synchronous, single-threaded language. However, JavaScript has features that allow you to execute asynchronous code, which is handled by browser engines (on your client) or by your OS (in NodeJS), which are capable of executing code in multiple threads.</p>\n<p>We work with asynchronous methods in JavaScript by either using callbacks, <a href=\"https://compile7.org/decompile/callback-vs-promises-vs-async-await/\">Promises or async/await</a>. We'll use Promises as an example for exploring asynchronicity in JavaScript.</p>\n<p>Promises are proxies for values that are not yet available when the Promise is created. This lets you organize parts of your code to run when the value becomes available or if something goes wrong.</p>\n<p>This does not mean that your code is running asynchronously. As I mentioned before, JavaScript code is executed on a single thread. The callback that processes the response from your created Promises still runs on your single main thread. Promises do, however, allow you to spawn asynchronous tasks, such as file I/O or making an HTTP request which runs outside of your code. This allows your main thread to work on something else while waiting for these tasks to return a response. This means that the callback functions which run after a response is received are called asynchronously.</p>\n<p>I feel that the distinction between your code running asynchronously vs. being called asynchronously is important, as you will see that you are not able to perform computationally expensive tasks without blocking your main thread, even when using Promises.</p>\n<p>Here is an example of using an expensive function (finding prime numbers) wrapped in a Promise.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">findPrimeNumbers</span><span class=\"mtk1\">(</span><span class=\"mtk12\">max</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Promise</span><span class=\"mtk1\">((</span><span class=\"mtk12\">resolve</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;starting findPrimeNumbers&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">primes</span><span class=\"mtk1\"> = [];</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">for</span><span class=\"mtk1\"> (</span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">0</span><span class=\"mtk1\">; </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> &lt; </span><span class=\"mtk12\">max</span><span class=\"mtk1\">; </span><span class=\"mtk12\">i</span><span class=\"mtk1\">++) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">i</span><span class=\"mtk1\"> === </span><span class=\"mtk7\">0</span><span class=\"mtk1\"> || </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> === </span><span class=\"mtk7\">1</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">continue</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">isPrime</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">true</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">for</span><span class=\"mtk1\"> (</span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">y</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">2</span><span class=\"mtk1\">; </span><span class=\"mtk12\">y</span><span class=\"mtk1\"> &lt; </span><span class=\"mtk12\">i</span><span class=\"mtk1\">; ++</span><span class=\"mtk12\">y</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">i</span><span class=\"mtk1\"> % </span><span class=\"mtk12\">y</span><span class=\"mtk1\"> === </span><span class=\"mtk7\">0</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">isPrime</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">false</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk15\">break</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">isPrime</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">primes</span><span class=\"mtk1\">.</span><span class=\"mtk11\">push</span><span class=\"mtk1\">(</span><span class=\"mtk12\">i</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;prime numbers found&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">resolve</span><span class=\"mtk1\">(</span><span class=\"mtk12\">primes</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;a&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">findPrimeNumbers</span><span class=\"mtk1\">(</span><span class=\"mtk7\">100000</span><span class=\"mtk1\">).</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;b&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;c&quot;</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>You'll find that the above program will print the following:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">a</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">starting</span><span class=\"mtk1\"> </span><span class=\"mtk12\">findPrimeNumbers</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">prime</span><span class=\"mtk1\"> </span><span class=\"mtk12\">numbers</span><span class=\"mtk1\"> </span><span class=\"mtk12\">found</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">c</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">b</span></span></code></pre>\n<p>The ordering of <code>a</code>, <code>b</code>, and <code>c</code> is not particularly noteworthy, as we already know that the callback for the <code>findPrimeNumbers</code> function will only execute after the main thread has nothing left to do, after printing <code>c</code>.</p>\n<p>What I did find interesting was that the statement printing <code>c</code> waits until the <code>findPrimeNumbers</code> function completes before being executed. To prevent functions like this from blocking the main thread, we'll have to use Web Workers.</p>\n<p>Web Workers run in a separate thread altogether, with no access to the context of the main thread. Data is sent between the worker and the main thread using a system of messages: the <code>postMessage()</code> method is used to send a message from one to the other, and the <code>onmessage</code> event handler is used to receive and respond to messages.</p>\n<p>First we need to create the script (we'll just call it <code>find-prime-numbers.js</code>) that the Web Worker will run:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">onmessage</span><span class=\"mtk1\"> = (</span><span class=\"mtk12\">event</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">data</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">event</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">primes</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">findPrimeNumbers</span><span class=\"mtk1\">(</span><span class=\"mtk11\">parseInt</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">postMessage</span><span class=\"mtk1\">(</span><span class=\"mtk12\">primes</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">findPrimeNumbers</span><span class=\"mtk1\">(</span><span class=\"mtk12\">max</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;starting findPrimeNumbers&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">primes</span><span class=\"mtk1\"> = [];</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">for</span><span class=\"mtk1\"> (</span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">0</span><span class=\"mtk1\">; </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> &lt; </span><span class=\"mtk12\">max</span><span class=\"mtk1\">; </span><span class=\"mtk12\">i</span><span class=\"mtk1\">++) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">i</span><span class=\"mtk1\"> === </span><span class=\"mtk7\">0</span><span class=\"mtk1\"> || </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> === </span><span class=\"mtk7\">1</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">continue</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">isPrime</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">true</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">for</span><span class=\"mtk1\"> (</span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">y</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">2</span><span class=\"mtk1\">; </span><span class=\"mtk12\">y</span><span class=\"mtk1\"> &lt; </span><span class=\"mtk12\">i</span><span class=\"mtk1\">; ++</span><span class=\"mtk12\">y</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">i</span><span class=\"mtk1\"> % </span><span class=\"mtk12\">y</span><span class=\"mtk1\"> === </span><span class=\"mtk7\">0</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">isPrime</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">false</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">break</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">isPrime</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">primes</span><span class=\"mtk1\">.</span><span class=\"mtk11\">push</span><span class=\"mtk1\">(</span><span class=\"mtk12\">i</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;prime numbers found&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">primes</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}  </span></span></code></pre>\n<p>The <code>onmessage</code> handler receives an event with the message itself contained in the event's <code>data</code> attribute. Here we execute the <code>findPrimeNumbers()</code> function again, and use <code>postMessage()</code> function to send the result back to the main thread.</p>\n<p>Over in your main script, we'll create a worker object using the constructor <code>new Worker()</code>, which runs the named JavaScript file containing the code that we just wrote, which will run in the worker thread.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">primeNumberWorker</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Worker</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;./find-prime-numbers.js&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">primeNumberWorker</span><span class=\"mtk1\">.</span><span class=\"mtk11\">onmessage</span><span class=\"mtk1\"> = (</span><span class=\"mtk12\">event</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;b&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;a&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">primeNumberWorker</span><span class=\"mtk1\">.</span><span class=\"mtk11\">postMessage</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;100000&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;c&quot;</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>Running this script will print the following:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">a</span>\n<span class=\"grvsc-line\">c</span>\n<span class=\"grvsc-line\">starting findPrimeNumbers</span>\n<span class=\"grvsc-line\">prime numbers found</span>\n<span class=\"grvsc-line\">b</span></code></pre>\n<p>You can see that this time, the prime numbers function is actually running on a thread separate from our main one, which allows the main thread to continue printing the statement <code>c</code> while the worker thread works out its own response.</p>\n<h3 id=\"when-should-you-use-javascript-web-worker\" style=\"position:relative;\"><a href=\"#when-should-you-use-javascript-web-worker\" aria-label=\"when should you use javascript web worker 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>When should you use JavaScript Web Worker</h3>\n<p>To reiterate, Web Workers allow you to run your own <a href=\"https://www.loginradius.com/blog/engineering/adding-multi-threading-to-javascript-using-web-workers/\">code on a separate thread</a>, which allows your main thread to continue rendering the UI, receive user input, etc., while your worker thread processes a response. </p>\n<p>For most web applications, the most expensive operations in your code will often be I/O, interacting with resources in your network. Thanks to <a href=\"https://www.loginradius.com/blog/engineering/understanding-event-loop/\">JavaScript's Event Loop</a>, these are already offloaded from your main thread to your system's operating system. As such, there is no need for Web Workers when making these kinds of operations. </p>\n<p>If you need to process large sets of data, there is a decent chance that you will be able to perform this on your server-side before sending it to your front end client for display to the user. This will allow you to rely on JavaScript's event loop to prevent these expensive operations from blocking your main thread.</p>\n<p>However, if your scenario must have these long-running tasks running on your client end, Web Workers would be an ideal solution for your needs. Some examples of these could be:</p>\n<ul>\n<li>As-you-type string validation, in situations where your validation logic is complex, such as a spell checker.</li>\n<li>Encrypting and decrypting data within your client, especially in cases where data is being exchanged frequently and cannot be exposed to your server.</li>\n<li>Client-side workspaces to allow your users to process and manipulate data before sending it to your server.</li>\n</ul>\n<h3 id=\"javascripty-web-worker-limitations\" style=\"position:relative;\"><a href=\"#javascripty-web-worker-limitations\" aria-label=\"javascripty web worker limitations 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>Javascripty Web Worker Limitations</h3>\n<p>As Web Workers work on a separate thread, it has no access to the parent page, which calls it. This means that the worker itself cannot manipulate the DOM nor access any data stored within it. It is not able to access the browser's localStorage and sessionStorage either. You are limited to the data sent directly via <code>postMessage</code> or IndexedDB for accessing stored client data.</p>\n<p>As with anything multithreaded, adding Web Workers into your application will add complexity to your application. Natively, <code>postMessage</code> is the only direct line of communication between threads. You will need to define how more complex workflows will be managed between your main thread and worker thread (such as error handling).</p>\n<p>If your worker can be triggered multiple times, each request will simply be queued and will run when the previous has been completed. For more complex queuing mechanisms, you would have to define this yourself.</p>\n<h3 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</h3>\n<p>With discussions dating back a decade, Web Workers are not a new feature. Despite their powerful potential, they haven't been widely adopted. Client side applications, for the most part, just haven't needed to perform intensive tasks where Web Workers would have been a solution. In addition, with a lack of widespread use, finding relatable examples to reference when implementing them is an extra barrier for adoption. </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 .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n</style>","frontmatter":{"date":"December 28, 2020","updated_date":null,"description":"Learn how to use JavaScript web workers to create parallel programming and execute multiple operations concurrently rather than interconnecting them.","title":"Web Workers in JS - An Introductory Guide","tags":["Web Workers"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/a17120a4316c8564d40dee1e652c0641/ee604/unsplash.png","srcSet":"/static/a17120a4316c8564d40dee1e652c0641/69585/unsplash.png 200w,\n/static/a17120a4316c8564d40dee1e652c0641/497c6/unsplash.png 400w,\n/static/a17120a4316c8564d40dee1e652c0641/ee604/unsplash.png 800w,\n/static/a17120a4316c8564d40dee1e652c0641/f3583/unsplash.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Nick Chim","github":"nickc95","avatar":null}}}},{"node":{"excerpt":"Enum is a typed constant that is specified for the new data form of Enumeration. An effective way to describe a set of named integral…","fields":{"slug":"/engineering/enum-csharp/"},"html":"<p>Enum is a typed constant that is specified for the new data form of Enumeration. An effective way to describe a set of named integral constants assigned to a variable is to include a Typesafe enumeration. Enums make the code more readable and less vulnerable to mistakes. If you have a set of functionally important and unchanged values, Enums are useful for developers.</p>\n<p>Enums' key benefit is to make it possible in the future to adjust values. Enums are a robust alternative to the short String or Int constants used to describe sets of similar objects in far older APIs.</p>\n<p>Sometimes we must use the constant variable in our application to not be changed throughout the application. One of the methods to declare the continuous variables are <code>Enum.</code> Let's discuss it.</p>\n<h2 id=\"using-enum-in-c-sharp\" style=\"position:relative;\"><a href=\"#using-enum-in-c-sharp\" aria-label=\"using enum in c sharp 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>Using Enum in C Sharp</h2>\n<p>Enum is the short form of Enumeration. Enum consumes less memory and space because they are value types, which means they store memory value. Also, Enums are strongly typed named constants. </p>\n<p>Enums written by developers are used in the <a href=\"https://en.wikipedia.org/wiki/.NET_Framework\">.NET system</a> to develop numeric constants. A numeric value must be allocated to all the members of an enum. Here are the main points about Enums:</p>\n<ul>\n<li>In C#, Keyword Enums build enumerated types of data</li>\n<li>Enums are made for developers</li>\n<li>Enums are strongly typed constants, as described above.</li>\n<li>An enum of one form cannot be allocated automatically to another type of enum.</li>\n<li>Enum values are fixed</li>\n</ul>\n<p><strong>Enums are of two types in C#</strong></p>\n<p><strong>Simple Enum</strong> - The members of this enum contain a single value.</p>\n<p><strong>Flags Enum</strong> - The members of this enum contain multiple values or multiple values combined using a bitwise OR operator. These enums are often used for bitwise operators.</p>\n<p>Here we will talk about the Simple Enum only.</p>\n<h2 id=\"how-to-declare-an-enum\" style=\"position:relative;\"><a href=\"#how-to-declare-an-enum\" aria-label=\"how to declare an enum 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>How to declare an Enum</h2>\n<p>Enum is declared by the <strong>enum</strong> keyword followed by the enum name and then its enum members. Like an example below</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">enum</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Vehicle</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">Car</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">Bike</span><span class=\"mtk1\">=</span><span class=\"mtk7\">3</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">Truck</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">Taxi</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>In the above code, an enum for the Vehicle is created. The enum values are started from <code>0</code> by default if we do not assign them the values and incremented by 1 for the next enum member. </p>\n<p>That means the <code>Car</code> enum has the value <code>0</code> and the <code>Bike</code> enum assigned the value <code>3</code> that means the <code>Bike</code> enum now has the value <code>3</code> and the next enums are incremented by 1 means <code>Truck</code> and <code>Taxi</code> enum have the value <code>4</code> and <code>5</code> respectively.</p>\n<p>By default, the type for enum elements is <strong>int</strong>. We can set different type by adding a colon like an example below. </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">public</span><span class=\"mtk1\"> </span><span class=\"mtk4\">enum</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Vehicle</span><span class=\"mtk1\">: </span><span class=\"mtk4\">byte</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">Car</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">Bike</span><span class=\"mtk1\">=</span><span class=\"mtk7\">3</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">Truck</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">Taxi</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The different types which can be set are sbyte, byte, short, ushort, uint, ulong, and long.</p>\n<h2 id=\"get-the-value-of-an-enum\" style=\"position:relative;\"><a href=\"#get-the-value-of-an-enum\" aria-label=\"get the value of an enum 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>Get the value of an Enum</h2>\n<p>To get the value of enum we can simply typecast it to its type. In the first example, the default type is int so we have to typecast it to int. Also, we can get the string value of that enum by using the <code>ToString()</code> method as below.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">Console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">WriteLine</span><span class=\"mtk1\">((</span><span class=\"mtk4\">int</span><span class=\"mtk1\">)</span><span class=\"mtk12\">VehicleEnum</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Car</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">string</span><span class=\"mtk1\"> </span><span class=\"mtk12\">vehicle</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">Vehicle</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Bike</span><span class=\"mtk1\">.</span><span class=\"mtk11\">ToString</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">Console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">WriteLine</span><span class=\"mtk1\">(</span><span class=\"mtk12\">vehicle</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>Output: </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">0</span>\n<span class=\"grvsc-line\">Bike</span></code></pre>\n<h2 id=\"parse-the-string-value-into-an-enum\" style=\"position:relative;\"><a href=\"#parse-the-string-value-into-an-enum\" aria-label=\"parse the string value into an enum 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>Parse the string value into an Enum</h2>\n<p>For parsing the string value into enum we have 2 methods</p>\n<ol>\n<li><em>Enum.Parse(Type enumType,string value)</em> - This method directly parses the string representation of the name or numeric value of enum member into enumType object. If the string representation of the name is not found, then it will give the exception.</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">Console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">WriteLine</span><span class=\"mtk1\">(</span><span class=\"mtk12\">Enum</span><span class=\"mtk1\">.</span><span class=\"mtk11\">Parse</span><span class=\"mtk1\">(</span><span class=\"mtk4\">typeof</span><span class=\"mtk1\">(</span><span class=\"mtk10\">Vehicle</span><span class=\"mtk1\">),</span><span class=\"mtk8\">&quot;Car&quot;</span><span class=\"mtk1\">));</span></span></code></pre>\n<p>Output:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">Car</span></code></pre>\n<ol start=\"2\">\n<li><em>Enum.TryParse(string? value,out enumType result)</em> - This method gives the result in bool value. if the string representation of the name or numeric value of enum member into enumType object is parsed, then the result will be true, and the parsed value will be in the <code>out</code> variable. If the string value is not parsed, then the result will be false.</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">Enum</span><span class=\"mtk1\">.</span><span class=\"mtk11\">TryParse</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;0&quot;</span><span class=\"mtk1\">,</span><span class=\"mtk4\">out</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Vehicle</span><span class=\"mtk1\"> </span><span class=\"mtk12\">value</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">Console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">WriteLine</span><span class=\"mtk1\">(</span><span class=\"mtk12\">value</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>Output:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">Car</span></code></pre>\n<p><strong>Note</strong> - Both the methods also have overload methods.</p>\n<h2 id=\"check-if-a-string-value-is-defined-in-the-enum\" style=\"position:relative;\"><a href=\"#check-if-a-string-value-is-defined-in-the-enum\" aria-label=\"check if a string value is defined in the enum 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>Check if a string value is defined in the Enum</h2>\n<p>We can check if a given integral value, or its name as a string, exists in a specified enum.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">Console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">WriteLine</span><span class=\"mtk1\">(</span><span class=\"mtk12\">Enum</span><span class=\"mtk1\">.</span><span class=\"mtk11\">IsDefined</span><span class=\"mtk1\">(</span><span class=\"mtk4\">typeof</span><span class=\"mtk1\">(</span><span class=\"mtk10\">Vehicle</span><span class=\"mtk1\">), </span><span class=\"mtk7\">0</span><span class=\"mtk1\">));</span></span></code></pre>\n<p>OR</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">Console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">WriteLine</span><span class=\"mtk1\">(</span><span class=\"mtk12\">Enum</span><span class=\"mtk1\">.</span><span class=\"mtk11\">IsDefined</span><span class=\"mtk1\">(</span><span class=\"mtk4\">typeof</span><span class=\"mtk1\">(</span><span class=\"mtk10\">Vehicle</span><span class=\"mtk1\">), </span><span class=\"mtk8\">&quot;car&quot;</span><span class=\"mtk1\">));</span></span></code></pre>\n<p>Output:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">True</span></code></pre>\n<h2 id=\"loop-through-all-the-enum\" style=\"position:relative;\"><a href=\"#loop-through-all-the-enum\" aria-label=\"loop through all the enum 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>Loop through all the Enum</h2>\n<p>For looping through the enums you can write the below code -</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">foreach</span><span class=\"mtk1\"> (</span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">data</span><span class=\"mtk1\"> </span><span class=\"mtk15\">in</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Enum</span><span class=\"mtk1\">.</span><span class=\"mtk11\">GetNames</span><span class=\"mtk1\">(</span><span class=\"mtk4\">typeof</span><span class=\"mtk1\">(</span><span class=\"mtk10\">Vehicle</span><span class=\"mtk1\">)))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">Console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">WriteLine</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">+</span><span class=\"mtk8\">&quot; - &quot;</span><span class=\"mtk1\">+ (</span><span class=\"mtk4\">int</span><span class=\"mtk1\">)</span><span class=\"mtk12\">Enum</span><span class=\"mtk1\">.</span><span class=\"mtk11\">Parse</span><span class=\"mtk1\">(</span><span class=\"mtk4\">typeof</span><span class=\"mtk1\">(</span><span class=\"mtk10\">Vehicle</span><span class=\"mtk1\">), </span><span class=\"mtk12\">data</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Here <em>Enum.GetNames(Type enumType)</em> method is used, which retrieves an array of the names from the specified enum.</p>\n<p>Output:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">Car - 0</span>\n<span class=\"grvsc-line\">Bike - 3</span>\n<span class=\"grvsc-line\">Truck - 4</span>\n<span class=\"grvsc-line\">Taxi - 5</span></code></pre>\n<h2 id=\"call-an-enum-by-the-integral-value\" style=\"position:relative;\"><a href=\"#call-an-enum-by-the-integral-value\" aria-label=\"call an enum by the integral value 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>Call an enum by the integral value</h2>\n<p>We can call the enum member by its integral value. If there is no corresponding value related to that integral value, then it will print that integral value.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"c#\" data-index=\"13\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk12\">Console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">WriteLine</span><span class=\"mtk1\">((</span><span class=\"mtk10\">Vehicle</span><span class=\"mtk1\">)</span><span class=\"mtk7\">3</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>Output</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"14\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">Bike</span></code></pre>\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>The advantages of using enums are that they are very easy to use and represented as strings but processed as integers. Enums are easy to maintain and improve code readability because they provide symbolic named constants, which means you need to remember the names, not the integer values.</p>\n<p>If you want to learn more about C programming, here is another article written on C# <a href=\"https://www.loginradius.com/blog/engineering/exception-handling-in-csharp/\">Exceptions and Exception Handling in C#</a> I hope you learn something new today and will going to try it out, if you have any questions feel free to drop a comment below.</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 .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n</style>","frontmatter":{"date":"December 18, 2020","updated_date":null,"description":"Would you like to become more proficient in your C# programming in the use of enums? To learn the basics and use cases for Enum in C#, read this post.","title":"How to Use Enum in C#","tags":["C#","Enum"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/438545712e629112915b48eb3d068821/14b42/coverimage.jpg","srcSet":"/static/438545712e629112915b48eb3d068821/f836f/coverimage.jpg 200w,\n/static/438545712e629112915b48eb3d068821/2244e/coverimage.jpg 400w,\n/static/438545712e629112915b48eb3d068821/14b42/coverimage.jpg 800w,\n/static/438545712e629112915b48eb3d068821/9842e/coverimage.jpg 900w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Hemant Manwani","github":"hemant404","avatar":null}}}},{"node":{"excerpt":"The goal of this post is to learn about the various ways of data migration in MongoDB that can help us to write scripts that change your…","fields":{"slug":"/engineering/live-data-migration-mongodb/"},"html":"<p>The goal of this post is to learn about the various ways of data migration in MongoDB that can help us to write scripts that change your database by adding new documents, modifying existing ones.</p>\n<p>If you're coming here for the first time, please take a look at the prequel <a href=\"https://www.loginradius.com/blog/engineering/self-hosted-mongo/\">Self-Hosted MongoDB</a>.</p>\n<p>Alright then, picking from where we left off, let's get started with the data migration in MongoDB.</p>\n<p>Now, the basic steps to migrate data from one MongoDB to another would be:</p>\n<ol>\n<li>Create a zipped backup of the existing data</li>\n<li>Dump the data in a new DB</li>\n</ol>\n<p>This is very straight forward when the source database is not online because we know that there won't be any new documents created/updated during the migration process.\nLet's look at simple migration first before diving into the live scenario.</p>\n<hr />\n<h1 id=\"migrating-from-an-offline-database-in-mongodb\" style=\"position:relative;\"><a href=\"#migrating-from-an-offline-database-in-mongodb\" aria-label=\"migrating from an offline database in mongodb 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>Migrating from an offline database in MongoDB</h1>\n<h2 id=\"creating-a-backup\" style=\"position:relative;\"><a href=\"#creating-a-backup\" aria-label=\"creating a backup 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>Creating a backup</h2>\n<p>We're going to use an existing utility program <a href=\"https://docs.mongodb.com/database-tools/mongodump/\">mongodump</a> for creating the database backup.</p>\n<p>Run this command in the source database server</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">mongodump --host=&quot;hostname:port&quot; \\</span>\n<span class=\"grvsc-line\">  --username=&quot;username&quot; --password=&quot;password&quot; \\</span>\n<span class=\"grvsc-line\">  --authenticationDatabase &quot;admin&quot; \\</span>\n<span class=\"grvsc-line\">  --db=&quot;db name&quot; --collection=&quot;collection name&quot; --query=&#39;json&#39; \\</span>\n<span class=\"grvsc-line\">  --forceTableScan -v --gzip --out ./dump</span></code></pre>\n<p><strong><code>--host</code></strong>: The source MongoDB hostname along with the port. It defaults to <code>localhost:27017</code>. If it is a connection string you can use this option <code>—-uri=\"mongodb://username:password@host1[:port1]...\"</code></p>\n<p><strong><code>--username</code></strong>: Specifies a username to authenticate to a MongoDB database that uses authentication.</p>\n<p><strong><code>--password</code></strong>: Specifies a password to authenticate to a MongoDB database that uses authentication.</p>\n<p><strong><code>--authenticationDatabase</code></strong>: Specifies the authentication database where the specified <code>--username</code> has been created.</p>\n<blockquote>\n<p>If you do not specify an authentication database or a database to export, mongodump assumes the admin database holds the user's credentials.</p>\n</blockquote>\n<p><strong><code>--db</code></strong>: Specifies the database to take a backup from. If you do not specify a database, mongodump collects from all databases in this instance.</p>\n<blockquote>\n<p>Alternatively, you can also specify the database directly in the <a href=\"https://docs.mongodb.com/database-tools/mongodump/#cmdoption-mongodump-uri\">URI connection string</a> i.e. <code>mongodb://username:password@uri/dbname</code>. <br /> Providing a connection string while also using <code>--db</code> and specifying conflicting information <strong>will result in an error</strong>.</p>\n</blockquote>\n<p><strong><code>--collection</code></strong>: Specifies a collection to backup. If you do not specify a collection, this option copies all collections in the specified database or instance to the dump files.</p>\n<p><strong><code>--query</code></strong> : Provides a <a href=\"https://docs.mongodb.com/manual/reference/glossary/#term-json-document\">JSON document</a> as a query that optionally limits the documents included in the output of mongodump. <br />\nYou must enclose the query document in single quotes <code>('{ ... }')</code> to ensure that it does not interact with your  environment.<br />\nThe query must be in <a href=\"https://docs.mongodb.com/manual/reference/mongodb-extended-json\">Extended JSON v2 format (either relaxed or canonical/strict mode)</a>, including enclosing the field names and operators in quotes e.g. <code>'{ \"created_at\": { \"\\$gte\": ISODate(...) } }'</code>.</p>\n<blockquote>\n<p>To use the <code>--query</code> option, you must also specify the <a href=\"https://docs.mongodb.com/database-tools/mongodump/#cmdoption-mongodump-collection\"><code>--collection</code></a> option.</p>\n</blockquote>\n<p><strong><code>--forceTableScan</code></strong>: Forces mongodump to scan the data store directly. Typically, mongodump saves entries as they appear in the index of the <code>_id</code> field. <br /></p>\n<blockquote>\n<p>If you specify a query <code>--query</code>, mongodump will use the most appropriate index to support that query. <br /><strong>Hence , you cannot use <a href=\"https://docs.mongodb.com/database-tools/mongodump/#cmdoption-mongodump-forcetablescan\"><code>--forceTableScan</code></a> with the <a href=\"https://docs.mongodb.com/database-tools/mongodump/#cmdoption-mongodump-query\"><code>--query</code></a> option</strong>.</p>\n</blockquote>\n<p><strong><code>--gzip</code></strong>: Compresses the output. If mongodump outputs to the dump directory, the new feature compresses the individual files. The files have the suffix <code>.gz</code>.</p>\n<p><strong><code>--out</code></strong>: Specifies the directory where mongodump will write <a href=\"https://docs.mongodb.com/manual/reference/glossary/#term-bson\"><code>BSON</code></a> files for the dumped databases. By default, mongodump saves output files in a directory named dump in the current working directory.</p>\n<h2 id=\"restoring-the-backup\" style=\"position:relative;\"><a href=\"#restoring-the-backup\" aria-label=\"restoring the backup 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>Restoring the backup</h2>\n<p>We will use a utility program called <a href=\"https://docs.mongodb.com/database-tools/mongorestore/\"><code>mongorestore</code></a> for restoring the database backup.</p>\n<p>Copy the backup directory dump to the new Database instance and run the following command:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">mongorestore --uri=&quot;mongodb://user:password@host:port/?authSource=admin&quot; \\</span>\n<span class=\"grvsc-line\">  --drop --noIndexRestore --gzip -v ./dump</span></code></pre>\n<p>Replace the credentials with the new database credentials. Unline in the previous step, the <code>--authenticationDatabase</code> option is specified in the URI string.</p>\n<p>Also, use <code>--gzip</code> if used while creating the backup.</p>\n<p><strong><code>--drop</code></strong>: Before restoring the collections from the dumped backup, drops the collections from the target database. It does not drop collections that are not in the backup.\n<strong><code>--noIndexRestore</code></strong>: Prevents mongorestore from restoring and building indexes as specified in the corresponding mongodump output.</p>\n<blockquote>\n<p>If you want to change name of the database while restoring, you can do so using <br /><code>--nsFrom=\"old_name.*\" --nsTo=\"new_name.*\"</code> options.<br /><br />However, it won’t work if you were to migrate with <code>oplogs</code> which is a requirement in migration from an online instance.</p>\n</blockquote>\n<hr />\n<h1 id=\"migrating-from-an-online-database-in-mongodb\" style=\"position:relative;\"><a href=\"#migrating-from-an-online-database-in-mongodb\" aria-label=\"migrating from an online database in mongodb 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>Migrating from an online database in MongoDB</h1>\n<p>The only challenge with migrating from an online database is not able to pause the updates during migration. So here is the overview of the steps,</p>\n<ol>\n<li>Run an initial bulk migration with <code>oplogs</code> capture</li>\n<li>Run a sync job to mitigate the database connection switch latency</li>\n</ol>\n<blockquote>\n<p>Now, to capture <code>oplogs</code>, a replica set must be initialized in the source and destination databases. This is because the <code>oplogs</code> are captured from <strong><code>local.oplog.rs</code></strong> namespace, which is created after initializing a replica set. <br /><br />You can follow <a href=\"https://medium.com/swlh/self-hosted-mongodb-deployment-7f1b6fb4973f#1cdf\">this guide</a> to configure a replica set.</p>\n</blockquote>\n<h2 id=\"initial-migration-with-oplog-capture\" style=\"position:relative;\"><a href=\"#initial-migration-with-oplog-capture\" aria-label=\"initial migration with oplog capture 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>Initial Migration with Oplog Capture</h2>\n<p>Oplogs, in simple words, are the operation logs created per operation in the database. They represent a partial document state or, in other words, the database state. So we are going to capture any updates in our old database during the migration process using these <code>oplogs</code>.</p>\n<p>Run the mongodump program with the following options,</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">mongodump --uri=&quot;.../?authSource=admin&quot; \\</span>\n<span class=\"grvsc-line\">  --forceTableScan --oplog \\</span>\n<span class=\"grvsc-line\">  --gzip -v --out ./dump</span></code></pre>\n<p><strong><code>--oplog</code></strong>: Creates a file named <code>oplog.bson</code> as part of the <code>mongodump</code> output. The <code>oplog.bson</code> file, located in the top level of the output directory, contains <code>oplog</code> entries that occur during the mongodump operation. This file provides an effective point-in-time snapshot of the state of our database instance.</p>\n<h2 id=\"restore-the-data-with-oplog-replay\" style=\"position:relative;\"><a href=\"#restore-the-data-with-oplog-replay\" aria-label=\"restore the data with oplog replay 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>Restore the data with oplog replay</h2>\n<p>In order to replay the oplogs, a special role is required. Let's create and assign the role to the database user being used for migration.</p>\n<h3 id=\"create-the-role\" style=\"position:relative;\"><a href=\"#create-the-role\" aria-label=\"create the role 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>Create the role</h3>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">db.createRole({</span>\n<span class=\"grvsc-line\">  role: &quot;interalUseOnlyOplogRestore&quot;,</span>\n<span class=\"grvsc-line\">  privileges: [</span>\n<span class=\"grvsc-line\">    {</span>\n<span class=\"grvsc-line\">      resource: { anyResource: true },</span>\n<span class=\"grvsc-line\">      actions: [ &quot;anyAction&quot; ] </span>\n<span class=\"grvsc-line\">    }</span>\n<span class=\"grvsc-line\">  ],</span>\n<span class=\"grvsc-line\">  roles: []</span>\n<span class=\"grvsc-line\">})</span></code></pre>\n<h3 id=\"assign-the-role\" style=\"position:relative;\"><a href=\"#assign-the-role\" aria-label=\"assign the role 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>Assign the role</h3>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">db.grantRolesToUser(</span>\n<span class=\"grvsc-line\">  &quot;admin&quot;,</span>\n<span class=\"grvsc-line\">  [{ role:&quot;interalUseOnlyOplogRestore&quot;, db:&quot;admin&quot; }]</span>\n<span class=\"grvsc-line\">);</span></code></pre>\n<p>Now you can restore using the mongorestore program with the following options,</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">mongorestore --uri=&quot;mongodb://admin:.../?authSource=admin&quot; \\</span>\n<span class=\"grvsc-line\">  --oplogReplay </span>\n<span class=\"grvsc-line\">  --gzip -v ./dump</span></code></pre>\n<p>In the above command, using the same user <strong><code>admin</code></strong> with whom the role was associated.</p>\n<p><strong><code>--oplogReplay</code></strong>: After restoring the database dump, replays the oplog entries from a bson file and restores the database to the point-in-time backup captured with the mongodump <code>--oplog</code> command.</p>\n<h2 id=\"mitigating-database-connection-switch-latency\" style=\"position:relative;\"><a href=\"#mitigating-database-connection-switch-latency\" aria-label=\"mitigating database connection switch latency 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>Mitigating database connection switch latency</h2>\n<p>Alright, so far we are done with most of the heavy lifting. The only thing that remains is maintaining consistency between the databases during the connection switch in our application servers.</p>\n<blockquote>\n<p>If you're running MongoDB version 3.6+, it's better to go for the Change Stream approach, which is a event-based mechanism introduced to capture changes in your database in an optimized way. Here is an article that covers it : <a href=\"https://www.mongodb.com/blog/post/an-introduction-to-change-streams\">An Introduction to Change Streams</a></p>\n</blockquote>\n<p>Check out the <a href=\"https://gist.github.com/cnp96/7be1756f7eb76ea78c9b832966e84dbf#file-delta-sync-sh\">generic sync script</a>, which you can run as a CRON job every minute.</p>\n<p>Update the variables in this script and run as</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">$ ./delta-sync.sh from_epoch_in_milliseconds</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"># from_epoch_in_milliseconds is automatically picked with every iteration if not supplied</span></code></pre>\n<p>Or you can set up a cron job to run this every minute.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">* * * * * ~/delta-sync.sh</span></code></pre>\n<p>The output can be monitored with the following command (I'm running RHEL 8, refer to your OS guide for cron output)</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">$ tail -f /var/log/cron | grep CRON</span></code></pre>\n<p>This is a sample sync log.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">CMD (~/cron/dsync.sh)</span>\n<span class=\"grvsc-line\">CMDOUT (INFO: Updated log registry to use new timestamp on next run.)</span>\n<span class=\"grvsc-line\">CMDOUT (INFO: Created sync directory: /home/ec2-user/cron/dump/2020-11-03T19:01:01Z)</span>\n<span class=\"grvsc-line\">CMDOUT (Fetching oplog in range [2020-11-03T19:00:01Z - 2020-11-03T19:01:01Z])</span>\n<span class=\"grvsc-line\">CMDOUT (2020-11-03T19:01:02.319+0000#011dumping up to 1 collections in parallel)</span>\n<span class=\"grvsc-line\">CMDOUT (2020-11-03T19:01:02.334+0000#011writing local.oplog.rs to /home/ec2-user/cron/dump/2020-11-03T19:01:01Z/local/oplog.rs.bson.gz)</span>\n<span class=\"grvsc-line\">CMDOUT (2020-11-03T19:01:04.943+0000#011local.oplog.rs  0)</span>\n<span class=\"grvsc-line\">CMDOUT (2020-11-03T19:01:04.964+0000#011local.oplog.rs  0)</span>\n<span class=\"grvsc-line\">CMDOUT (2020-11-03T19:01:04.964+0000#011done dumping local.oplog.rs (0 documents))</span>\n<span class=\"grvsc-line\">CMDOUT (INFO: Dump success!)</span>\n<span class=\"grvsc-line\">CMDOUT (INFO: Replaying oplogs...)</span>\n<span class=\"grvsc-line\">CMDOUT (2020-11-03T19:01:05.030+0000#011using write concern: &{majority false 0})</span>\n<span class=\"grvsc-line\">CMDOUT (2020-11-03T19:01:05.054+0000#011will listen for SIGTERM, SIGINT, and SIGKILL)</span>\n<span class=\"grvsc-line\">CMDOUT (2020-11-03T19:01:05.055+0000#011connected to node type: standalone)</span>\n<span class=\"grvsc-line\">CMDOUT (2020-11-03T19:01:05.055+0000#011mongorestore target is a directory, not a file)</span>\n<span class=\"grvsc-line\">CMDOUT (2020-11-03T19:01:05.055+0000#011preparing collections to restore from)</span>\n<span class=\"grvsc-line\">CMDOUT (2020-11-03T19:01:05.055+0000#011found collection local.oplog.rs bson to restore to local.oplog.rs)</span>\n<span class=\"grvsc-line\">CMDOUT (2020-11-03T19:01:05.055+0000#011found collection metadata from local.oplog.rs to restore to local.oplog.rs)</span>\n<span class=\"grvsc-line\">CMDOUT (2020-11-03T19:01:05.055+0000#011restoring up to 4 collections in parallel)</span>\n<span class=\"grvsc-line\">CMDOUT (2020-11-03T19:01:05.055+0000#011replaying oplog)</span>\n<span class=\"grvsc-line\">CMDOUT (2020-11-03T19:01:05.055+0000#011applied 0 oplog entries)</span>\n<span class=\"grvsc-line\">CMDOUT (2020-11-03T19:01:05.055+0000#0110 document(s) restored successfully. 0 document(s) failed to restore.)</span>\n<span class=\"grvsc-line\">CMDOUT (INFO: Restore success!)</span></code></pre>\n<p>You can stop this script after verifying that no more <code>oplogs</code> are being created, i.e., when source DB went offline.</p>\n<p>This concludes the complete self-hosted MongoDB data migration guide. If you want to learn more about MongoDB here is a useful resource on <a href=\"https://www.loginradius.com/blog/engineering/mongodb-as-datasource-in-golang/\">how to use MongoDB as datasource in goLang</a>.</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":"December 14, 2020","updated_date":null,"description":"This article covers the guide to migrate data from offline or live MongoDB instance using oplog replay alongside mitigate connection switch latency with existing utilities.","title":"How to Migrate Data In MongoDB","tags":["MongoDB"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.4184397163120568,"src":"/static/90f92104129cbc152fa1d9a64c58d7be/ee604/index.png","srcSet":"/static/90f92104129cbc152fa1d9a64c58d7be/69585/index.png 200w,\n/static/90f92104129cbc152fa1d9a64c58d7be/497c6/index.png 400w,\n/static/90f92104129cbc152fa1d9a64c58d7be/ee604/index.png 800w,\n/static/90f92104129cbc152fa1d9a64c58d7be/31987/index.png 1000w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Chinmaya Pati","github":"cnp96","avatar":null}}}},{"node":{"excerpt":"This guide uses LoginRadius API for authenticating React apps. It provides React developers with a more straightforward way to add user…","fields":{"slug":"/engineering/user-authentication-react-application/"},"html":"<p>This guide uses LoginRadius API for authenticating React apps. It provides React developers with a more straightforward way to add user authentication to react apps. To handle a lot of authentication implementation information, LoginRadius offers a high-level API. Using security best practices, now you can protect your response apps while writing less code.</p>\n<p>This article <a href=\"/react-hooks-guide/\">focuses on helping developers</a> learn how to integrate user authentication in the React application. Practice the following security principles to improve authentication on React applications:</p>\n<ul>\n<li>Add user login and user login.</li>\n<li>User information retrieval.</li>\n<li>Attach a tab for sign-up.</li>\n</ul>\n<p>In the React application, we can <a href=\"/react-context-api/\">easily and quickly</a> add authentication by using LoginRadius. If you already have a customized login/registration page ready, then I'll guide you to the next step of adding authentication in react apps.</p>\n<h2 id=\"configure-loginradius-for-react-application\" style=\"position:relative;\"><a href=\"#configure-loginradius-for-react-application\" aria-label=\"configure loginradius for react application 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>Configure LoginRadius for React Application</h2>\n<p>A new application was created for you when you <a href=\"https://accounts.loginradius.com/auth.aspx?action=register&#x26;return_url=https://dashboard.loginradius.com/login\">signed up</a> for LoginRadius. From here, you get some essential information.</p>\n<ol>\n<li>API Key  <a href=\"https://www.loginradius.com/developers/\">How to get API Key?</a></li>\n<li>Sott  <a href=\"https://www.loginradius.com/developers/\">Work with Sott</a></li>\n</ol>\n<h2 id=\"add-following-loginradius-js-library-into-your-application\" style=\"position:relative;\"><a href=\"#add-following-loginradius-js-library-into-your-application\" aria-label=\"add following loginradius js library into your application 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>Add following LoginRadius JS library into your application</h2>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&lt;script type=&quot;text/javascript&quot; src=&quot;https://auth.lrcontent.com/v2/LoginRadiusV2.js&quot;&gt;&lt;/script&gt;</span></code></pre>\n<h2 id=\"add-authentication-when-you-have-customized-login-page\" style=\"position:relative;\"><a href=\"#add-authentication-when-you-have-customized-login-page\" aria-label=\"add authentication when you have customized login page 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>Add Authentication when you have customized Login Page</h2>\n<h3 id=\"add-login-to-your-react-application\" style=\"position:relative;\"><a href=\"#add-login-to-your-react-application\" aria-label=\"add login to your react application 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>Add Login to your react application</h3>\n<p>We will use an API framework to call LoginRadius APIs for authentication.  Create a new file <strong>LoginPage.js</strong>, and add the following code.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\">  </span><span class=\"mtk12\">React</span><span class=\"mtk1\">, { </span><span class=\"mtk12\">useState</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\">  </span><span class=\"mtk8\">&quot;react&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\">  </span><span class=\"mtk12\">lrconfig</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">apiKey:</span><span class=\"mtk1\">  </span><span class=\"mtk8\">&quot;*************************&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk3\">//LoginRadius API key</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\">  </span><span class=\"mtk12\">loginradius</span><span class=\"mtk1\"> = {};</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">window</span><span class=\"mtk1\">.</span><span class=\"mtk12\">LoginRadiusV2</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">loginradius</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\">  </span><span class=\"mtk10\">window</span><span class=\"mtk1\">.</span><span class=\"mtk10\">LoginRadiusV2</span><span class=\"mtk1\">(</span><span class=\"mtk12\">lrconfig</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">loginradius</span><span class=\"mtk1\">.</span><span class=\"mtk12\">api</span><span class=\"mtk1\">.</span><span class=\"mtk11\">init</span><span class=\"mtk1\">(</span><span class=\"mtk12\">lrconfig</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\">  </span><span class=\"mtk11\">LoginButton</span><span class=\"mtk1\"> = () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\">  </span><span class=\"mtk11\">loginButtonHandler</span><span class=\"mtk1\"> = () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">loginradius</span><span class=\"mtk1\">.</span><span class=\"mtk12\">api</span><span class=\"mtk1\">.</span><span class=\"mtk11\">login</span><span class=\"mtk1\">({</span><span class=\"mtk12\">emailid:</span><span class=\"mtk1\">  </span><span class=\"mtk12\">emailValue</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">password:</span><span class=\"mtk1\">  </span><span class=\"mtk12\">passwordValue</span><span class=\"mtk1\">},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      (</span><span class=\"mtk12\">successResponse</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk3\">//Here you will get the access Token of </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">successResponse</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      (</span><span class=\"mtk12\">errors</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">errors</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">emailValue</span><span class=\"mtk1\">, </span><span class=\"mtk12\">updateEmailValue</span><span class=\"mtk1\">] = </span><span class=\"mtk11\">useState</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">passwordValue</span><span class=\"mtk1\">, </span><span class=\"mtk12\">updatePasswordValue</span><span class=\"mtk1\">] = </span><span class=\"mtk11\">useState</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">React.Fragment</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\">  </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;text&quot;</span><span class=\"mtk1\">  </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">emailValue</span><span class=\"mtk4\">}</span><span class=\"mtk1\">  </span><span class=\"mtk12\">onChange</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span><span class=\"mtk11\">updateEmailValue</span><span class=\"mtk1\">(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">.</span><span class=\"mtk12\">target</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\">)}</span><span class=\"mtk4\">}</span><span class=\"mtk1\">  </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk8\">&quot;email&quot;</span><span class=\"mtk4\">}</span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\">  </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\">  </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">passwordValue</span><span class=\"mtk4\">}</span><span class=\"mtk1\">  </span><span class=\"mtk12\">onChange</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span><span class=\"mtk11\">updatePasswordValue</span><span class=\"mtk1\">(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">.</span><span class=\"mtk12\">target</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\">)}</span><span class=\"mtk4\">}</span><span class=\"mtk1\">  </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk8\">&quot;Password&quot;</span><span class=\"mtk4\">}</span><span class=\"mtk1\">  </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\">  </span><span class=\"mtk12\">onClick</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">  </span><span class=\"mtk11\">loginButtonHandler</span><span class=\"mtk1\">()</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Log In</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">React.Fragment</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">export</span><span class=\"mtk1\">  </span><span class=\"mtk15\">default</span><span class=\"mtk1\">  </span><span class=\"mtk12\">LoginButton</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>In the above code, you will see the <code>lrConfig</code> object, which has apikey that you will get from the LoginRadius account. After calling <code>loginradius.api.login</code>, you will get the response in which you will get the access Token. Through this access token, you can get the user profile.</p>\n<h3 id=\"add-logout-to-your-react-application\" style=\"position:relative;\"><a href=\"#add-logout-to-your-react-application\" aria-label=\"add logout to your react application 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>Add Logout to your react application</h3>\n<p>Create <strong>LogoutPage.js</strong> file and add following code:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">React</span><span class=\"mtk1\">, { </span><span class=\"mtk12\">useState</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;react&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lrconfig</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">apiKey:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;*************************&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk3\">//LoginRadius API key</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">loginradius</span><span class=\"mtk1\"> = {};</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">window</span><span class=\"mtk1\">.</span><span class=\"mtk12\">LoginRadiusV2</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">loginradius</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">window</span><span class=\"mtk1\">.</span><span class=\"mtk10\">LoginRadiusV2</span><span class=\"mtk1\">(</span><span class=\"mtk12\">lrconfig</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">loginradius</span><span class=\"mtk1\">.</span><span class=\"mtk12\">api</span><span class=\"mtk1\">.</span><span class=\"mtk11\">init</span><span class=\"mtk1\">(</span><span class=\"mtk12\">lrconfig</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">LogoutButton</span><span class=\"mtk1\"> = () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">token</span><span class=\"mtk1\">  = </span><span class=\"mtk8\">&#39;************&#39;</span><span class=\"mtk1\">; </span><span class=\"mtk3\">// Access Token that you got after login</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">logoutButtonHandler</span><span class=\"mtk1\"> = () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\">//Note: Call invalidate token api to invalidate the token.**</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">loginradius</span><span class=\"mtk1\">.</span><span class=\"mtk12\">api</span><span class=\"mtk1\">.</span><span class=\"mtk11\">invalidateToken</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">               </span><span class=\"mtk12\">token</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">               (</span><span class=\"mtk12\">successResponse</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">           </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">successResponse</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">           },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">               (</span><span class=\"mtk12\">errors</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                 </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">errors</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">               }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">             );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">React.Fragment</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">onClick</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk11\">logoutButtonHandler</span><span class=\"mtk1\">()</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Logout</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">React.Fragment</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">LogoutButton</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>In the above code, we have called invalidated token api, which expires your access token.</p>\n<h3 id=\"add-signup-to-your-react-application\" style=\"position:relative;\"><a href=\"#add-signup-to-your-react-application\" aria-label=\"add signup to your react application 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>Add Signup to your react application</h3>\n<p>Create <strong>SignupPage.js</strong> file and add the following code:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">import</span><span class=\"mtk1\">  </span><span class=\"mtk12\">React</span><span class=\"mtk1\">, { </span><span class=\"mtk12\">useState</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\">  </span><span class=\"mtk8\">&quot;react&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\">  </span><span class=\"mtk12\">lrconfig</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">apiKey:</span><span class=\"mtk1\">  </span><span class=\"mtk8\">&quot;*************************&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk3\">//LoginRadius API key</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">sott:</span><span class=\"mtk1\">  </span><span class=\"mtk8\">&quot;***************************&quot;</span><span class=\"mtk1\">  </span><span class=\"mtk3\">//Secure Token for signup functionality</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\">  </span><span class=\"mtk12\">loginradius</span><span class=\"mtk1\"> = {};</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">window</span><span class=\"mtk1\">.</span><span class=\"mtk12\">LoginRadiusV2</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">loginradius</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\">  </span><span class=\"mtk10\">window</span><span class=\"mtk1\">.</span><span class=\"mtk10\">LoginRadiusV2</span><span class=\"mtk1\">(</span><span class=\"mtk12\">lrconfig</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">loginradius</span><span class=\"mtk1\">.</span><span class=\"mtk12\">api</span><span class=\"mtk1\">.</span><span class=\"mtk11\">init</span><span class=\"mtk1\">(</span><span class=\"mtk12\">lrconfig</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\">  </span><span class=\"mtk11\">SignupButton</span><span class=\"mtk1\"> = () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\">  </span><span class=\"mtk11\">signupButtonHandler</span><span class=\"mtk1\"> = () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">loginradius</span><span class=\"mtk1\">.</span><span class=\"mtk12\">api</span><span class=\"mtk1\">.</span><span class=\"mtk11\">registration</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">email:</span><span class=\"mtk1\"> [{ </span><span class=\"mtk12\">type:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Primary&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">value:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">emailValue</span><span class=\"mtk1\"> }],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">password:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">passwordValue</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      (</span><span class=\"mtk12\">successResponse</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk3\">//Here you will get the response after registration</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">successResponse</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      (</span><span class=\"mtk12\">errors</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">errors</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">emailValue</span><span class=\"mtk1\">, </span><span class=\"mtk12\">updateEmailValue</span><span class=\"mtk1\">] = </span><span class=\"mtk11\">useState</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">passwordValue</span><span class=\"mtk1\">, </span><span class=\"mtk12\">updatePasswordValue</span><span class=\"mtk1\">] = </span><span class=\"mtk11\">useState</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">React.Fragment</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\">  </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;text&quot;</span><span class=\"mtk1\">  </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">emailValue</span><span class=\"mtk4\">}</span><span class=\"mtk1\">  </span><span class=\"mtk12\">onChange</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span><span class=\"mtk11\">updateEmailValue</span><span class=\"mtk1\">(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">.</span><span class=\"mtk12\">target</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\">)}</span><span class=\"mtk4\">}</span><span class=\"mtk1\">  </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk8\">&quot;email&quot;</span><span class=\"mtk4\">}</span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\">  </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\">  </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">passwordValue</span><span class=\"mtk4\">}</span><span class=\"mtk1\">  </span><span class=\"mtk12\">onChange</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span><span class=\"mtk11\">updatePasswordValue</span><span class=\"mtk1\">(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">.</span><span class=\"mtk12\">target</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\">)}</span><span class=\"mtk4\">}</span><span class=\"mtk1\">  </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk8\">&quot;Password&quot;</span><span class=\"mtk4\">}</span><span class=\"mtk1\">  </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\">  </span><span class=\"mtk12\">onClick</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">  </span><span class=\"mtk11\">signupButtonHandler</span><span class=\"mtk1\">()</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Log In</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">React.Fragment</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      };</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk15\">export</span><span class=\"mtk1\">  </span><span class=\"mtk15\">default</span><span class=\"mtk1\">  </span><span class=\"mtk12\">SignupButton</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>In the above code, You will get a success/error response after calling the registration api.</p>\n<h2 id=\"wrap-up\" style=\"position:relative;\"><a href=\"#wrap-up\" aria-label=\"wrap up 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>Wrap up</h2>\n<p>The most common authentication use case for a React application gets covered in this tutorial: quick login and logout. However, LoginRadius is an expandable and versatile platform that can help you accomplish much more. In this guide, We have used the LoginRadius API Framework. If you want to incorporate our hosted page into your application, follow this <a href=\"https://www.loginradius.com/developers/\">documentation</a>.</p>\n<p>Let me know what you think of this tutorial in the comments below. Thanks for reading :)</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 .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk17 { color: #808080; }\n</style>","frontmatter":{"date":"December 10, 2020","updated_date":null,"description":"This article focuses on helping developers learn how to integrate user authentication in React applications and determine the basic principles of authentication with React.","title":"A Guide To React User Authentication with LoginRadius","tags":["Authentication","LoginRadius","React"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/1d36656dce223836227b1b52270427a8/ee604/authentication-main.png","srcSet":"/static/1d36656dce223836227b1b52270427a8/69585/authentication-main.png 200w,\n/static/1d36656dce223836227b1b52270427a8/497c6/authentication-main.png 400w,\n/static/1d36656dce223836227b1b52270427a8/ee604/authentication-main.png 800w,\n/static/1d36656dce223836227b1b52270427a8/f3583/authentication-main.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Versha Gupta","github":"vershagupta","avatar":null}}}}]},"markdownRemark":{"excerpt":"Google has prepared a roadmap to restrict third-party cookies in Chrome. Since 04 January 2024, Chrome has rolled out third-party cookie…","fields":{"slug":"/engineering/identity-impact-of-google-chrome-thirdparty-cookie-restrictions/"},"html":"<p>Google has prepared a roadmap to restrict third-party cookies in Chrome. Since 04 January 2024, Chrome has rolled out third-party cookie restrictions for 1% of stable clients and 20% of Canary, Dev, and Beta clients.</p>\n<p><strong>What does it mean for user authentication?</strong></p>\n<p>On one hand, Google believes third-party cookies are widely used for cross-site tracking, greatly affecting user privacy. Hence, Google wants to phase out (or restrict) supporting third-party cookies in Chrome by early Q2 2025 (subject to regulatory processes).</p>\n<p>On the other hand, Google introduced Privacy Sandbox to support the use cases (other than cross-site tracking and advertising) previously implemented using third-party cookies.</p>\n<p>In this article, we’ll discuss:</p>\n<ul>\n<li>How is user authentication (identity) affected?</li>\n<li>What is Google offering as part of Privacy Sandbox to support various identity use cases when third-party cookies are phased out?</li>\n</ul>\n<h2 id=\"how-is-user-authentication-affected\" style=\"position:relative;\"><a href=\"#how-is-user-authentication-affected\" aria-label=\"how is user authentication affected 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>How is User Authentication Affected?</h2>\n<p>Third-party cookie restrictions affect user authentication in three ways, as follows.</p>\n<h3 id=\"external-identity-providers\" style=\"position:relative;\"><a href=\"#external-identity-providers\" aria-label=\"external identity providers 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>External Identity Providers</h3>\n<p>If your website or app uses an external Identity Provider (IdP) — like LoginRadius, the IdP sets a third-party cookie when the user authenticates on your app.</p>\n<h3 id=\"web-sso\" style=\"position:relative;\"><a href=\"#web-sso\" aria-label=\"web sso 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>Web SSO</h3>\n<p>If you have multiple apps across domains within your organization and authentication is handled using an IdP (internal or external) with web SSO, you already use third-party cookies to facilitate seamless access for each user using a single set of credentials.</p>\n<p>If you have implemented web SSO with one primary domain and multiple sub-domains of the primary domain, third-party cookie restrictions may not apply. For now, Google doesn’t consider the cookies set by sub-domains as third-party cookies, although this stance may change in the future.</p>\n<p>For example, you have apps at <code>example.com</code>, <code>travel.example.com</code>, <code>stay.example.com</code>, and web SSO is handled by <code>auth.example.com</code>. In this case, third-party cookie restrictions don’t apply.</p>\n<h3 id=\"federated-sso\" style=\"position:relative;\"><a href=\"#federated-sso\" aria-label=\"federated sso 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>Federated SSO</h3>\n<p>Federated SSO is similar to, albeit different from, web SSO. It can handle multiple IdPs and applications—aka., Service Providers (SPs)—spanning multiple organizations. It can also implement authentication scenarios that are usually implemented through web SSO.</p>\n<p>Usually, authentication is handled on a separate pop-up or page when the user wants to authenticate rather than on the application or website a user visits. </p>\n<p>For example, you already use federated SSO if you facilitate authentication for a set of apps through multiple social identity providers as well as traditional usernames and passwords.</p>\n<blockquote>\n<p><strong>Note</strong>: It is also possible to store tokens locally, not within cookies. In this case, third-party cookie restrictions won’t affect token-based authentication. However, the restrictions still affect authentication where tokens are stored within third-party cookies (a common and secure method).</p>\n</blockquote>\n<h2 id=\"chromes-alternatives-for-third-party-cookies\" style=\"position:relative;\"><a href=\"#chromes-alternatives-for-third-party-cookies\" aria-label=\"chromes alternatives for third party cookies 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>Chrome’s Alternatives for Third-Party Cookies</h2>\n<p>Google has been developing alternative features and capabilities for Chrome to replace third-party cookies as part of its Privacy Sandbox for Web initiative.</p>\n<p>Specific to authentication, Google recommends the following:</p>\n<ol>\n<li>Cookies Having Independent Partitioned State (CHIPS)</li>\n<li>Storage Access API</li>\n<li>Related Website Sets</li>\n<li>Federated Credential Management (FedCM) API</li>\n</ol>\n<h3 id=\"cookies-having-independent-partitioned-state-chips\" style=\"position:relative;\"><a href=\"#cookies-having-independent-partitioned-state-chips\" aria-label=\"cookies having independent partitioned state chips 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>Cookies Having Independent Partitioned State (CHIPS)</h3>\n<p><a href=\"https://developers.google.com/privacy-sandbox/3pcd/chips\">CHIPS</a> are a restricted way of setting third-party cookies on a top-level site without making them accessible on other top-level sites. Thus, they limit cross-site tracking and enable specific cross-site functionalities, such as maps, chat, and payment embeds.</p>\n<p>For example, a user visits <code>a.com</code> with a map embed from <code>map-example.com</code>, which can set a partitioned cookie that is only accessible on a.com. </p>\n<p>If the user visits <code>b.com</code> with a map embed from <code>map-example.com</code>, it cannot access the partitioned cookie set on <code>a.com</code>. It has to create a separate partitioned cookie specific to <code>b.com</code>, thus blocking cross-site tracking yet allowing limited cross-site functionality.</p>\n<p>You should specifically opt for partitioned cookies (CHIPS), which are set with partitioned and secure cookie attributes.</p>\n<p>If you’re using an external identity provider for your application, CHIPS is a good option to supplant third-party cookie restrictions. </p>\n<p>However, CHIPS may not be ideal if you have a web SSO or federated SSO implementation. It creates separate partitioned cookies for each application with a separate domain, which can increase complexity and create compatibility issues.</p>\n<h3 id=\"storage-access-api\" style=\"position:relative;\"><a href=\"#storage-access-api\" aria-label=\"storage access api 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>Storage Access API</h3>\n<p>With <a href=\"https://developers.google.com/privacy-sandbox/3pcd/storage-access-api\">Storage Access API</a>, you can access the local storage in a third-party context through iframes, similar to when users visit it as a top-level site in a first-party context. That is, it gives access to unpartitioned cookies and storage.</p>\n<p>Storage Access API requires explicit user approval to grant access, similar to locations, camera, and microphone permissions. If the user denies access, unpartitioned cookies and storage won’t be accessible in a third-party context.</p>\n<p>It is most suitable when loading cross-site resources and interactions, such as:</p>\n<p>Verifying user sessions when allowing interactions on an embedded social post or providing personalization for an embedded video.\nEmbedded documents requiring user verification status to be accessible.</p>\n<p>As it requires explicit user approval, it is advisable to use Storage Access API when you can’t implement an identity use case with the other options.</p>\n<h3 id=\"related-website-sets\" style=\"position:relative;\"><a href=\"#related-website-sets\" aria-label=\"related website sets 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>Related Website Sets</h3>\n<p>With <a href=\"https://developers.google.com/privacy-sandbox/3pcd/related-website-sets\">Related Website Sets</a>, you can declare a <code>primary</code> website and <code>associatedSites</code> for limited purposes to grant third-party cookie access and local storage for a limited number of sites.</p>\n<p>Chrome automatically recognizes related website sets declared, accepted, and maintained in this open-source GitHub repository: <a href=\"https://github.com/GoogleChrome/related-website-sets\">Related Website Sets</a></p>\n<p>It provides access through Storage Access API directly without prompting for user approval, but only after the user interacts with the relevant iframe.</p>\n<p>It is important to declare a limited number of domains in related website sets that are meaningful and used for specific purposes. Google may block or suspend any exploitative use of this feature.</p>\n<p>The top-level site can also request approval for specific cross-site resources and scripts to Storage Access API using <code>resuestStorageAccessFor()</code> API.</p>\n<p>If you’re using an external identity provider for your web application, you can declare the domain of the identity provider in the related set to ensure limited third-party cookies and storage access to the identity provider, thus ensuring seamless user authentication.</p>\n<p>Related Website Sets can also work to supplement third-party cookie restrictions in web SSO and federated SSO if the number of web applications (or domains) is limited.</p>\n<h3 id=\"federated-credential-management-fedcm-api\" style=\"position:relative;\"><a href=\"#federated-credential-management-fedcm-api\" aria-label=\"federated credential management fedcm api 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>Federated Credential Management (FedCM) API</h3>\n<p>FedCM API enables federated SSO without third-party cookies.</p>\n<p>With FedCM API, a user follows these steps for authentication:</p>\n<ol>\n<li>The User navigates to a Service Provider (SP) — aka., Relying Party (RP)</li>\n<li>As the user requests to authenticate, the SP requests the browser through FedCM API to initiate authentication.</li>\n<li>The browser displays a list of available identity providers (supported by the RP), such as social IdPs like Google, Apple, LinkedIn, and Facebook, or other OAuth IdPs like LoginRadius.</li>\n<li>Once the user selects an IdP, the browser communicates with the IdP. Upon valid authentication, the IdP generates a secure token.\nThe browser delivers this secure token to the RP to facilitate user authorization.</li>\n</ol>\n<p>You can access a user demo of FedCM here: <a href=\"https://fedcm-rp-demo.glitch.me/\">FedCM</a>. </p>\n<p>For more information about implementing federated SSO with FedCM API, go through the <a href=\"https://developers.google.com/privacy-sandbox/3pcd/fedcm-developer-guide\">FedCM developer guide</a>.</p>\n<h2 id=\"how-is-loginradius-preparing-for-the-third-party-cookie-phase-out\" style=\"position:relative;\"><a href=\"#how-is-loginradius-preparing-for-the-third-party-cookie-phase-out\" aria-label=\"how is loginradius preparing for the third party cookie phase out 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>How is LoginRadius Preparing for the Third-party Cookie Phase-out?</h2>\n<p>Firstly, we’re committed to solving our customers' user identity pain points — and preparing for the third-party cookies phase-out is no different.</p>\n<p>We’ll implement the most relevant and widely useful solutions to facilitate a smooth transition for our customers.</p>\n<p>Please subscribe to our blog for more information. We’ll update you on how we help with the third-party cookie phase-out.</p>\n<h2 id=\"in-conclusion\" style=\"position:relative;\"><a href=\"#in-conclusion\" aria-label=\"in 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>In Conclusion</h2>\n<p>The proposed changes to phase out third-party cookies and suggested alternatives are evolving as Google has been actively collaborating and discussing changes with the border community.</p>\n<p>Moreover, browsers like Firefox, Safari, and Edge may approach restricting third-party cookies differently than Google does.</p>\n<p>From LoginRadius, we’ll keep you updated on what we’re doing as a leading Customer Identity and Access Management (CIAM) vendor to prepare for the third-party cookie phase-out.</p>\n<h2 id=\"glossary\" style=\"position:relative;\"><a href=\"#glossary\" aria-label=\"glossary 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>Glossary</h2>\n<p><strong>Top-level site</strong>: It is the primary site a user has visited.</p>\n<p><strong>First-party cookie</strong>: A cookie set by the top-level site.</p>\n<p><strong>Third-party cookie</strong>: A cookie set by a domain other than the top-level site. For example, let’s assume that a user has visited <code>a.com</code>, which might use an embed from <code>loginradius.com</code> to facilitate authentication. If <code>loginradius.com</code> sets a cookie when the user visits <code>a.com</code>, it is called a third-party cookie as the user hasn’t directly visited <code>loginradius.com</code>.</p>\n<h2 id=\"references\" style=\"position:relative;\"><a href=\"#references\" aria-label=\"references 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>References</h2>\n<ul>\n<li><a href=\"https://developers.google.com/privacy-sandbox/3pcd/prepare/prepare-for-phaseout\">Changes to Chrome's treatment of third-party cookies</a></li>\n<li><a href=\"https://developers.google.com/privacy-sandbox/3pcd/guides/identity\">Check the impact of the third-party cookie changes on your sign-in workflows</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":"July 08, 2024","updated_date":null,"description":"Google Chrome has planned to phase out third-party cookies, which will affect different website functionalities depending on third-party cookies. This blog focuses on how this phase-out affects identity and user authentication and discusses alternatives for overcoming challenges.","title":"How Chrome’s Third-Party Cookie Restrictions Affect User Authentication?","tags":["Identity","Cookies","Chrome"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/eb7396060c0adc430dbed2d04b63d431/ee604/third-party-cookies-phaseout-chrome.png","srcSet":"/static/eb7396060c0adc430dbed2d04b63d431/69585/third-party-cookies-phaseout-chrome.png 200w,\n/static/eb7396060c0adc430dbed2d04b63d431/497c6/third-party-cookies-phaseout-chrome.png 400w,\n/static/eb7396060c0adc430dbed2d04b63d431/ee604/third-party-cookies-phaseout-chrome.png 800w,\n/static/eb7396060c0adc430dbed2d04b63d431/f3583/third-party-cookies-phaseout-chrome.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Raghunath Reddy","github":"raghunath-r-a","avatar":null}}}},"pageContext":{"limit":6,"skip":96,"currentPage":17,"type":"//engineering//","numPages":52,"pinned":"17fa0d7b-34c8-51c4-b047-df5e2bbaeedb"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}