{"componentChunkName":"component---src-templates-blog-list-template-js","path":"/123","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"excerpt":"Before You Get Started This tutorial assumes you have: A basic understanding of Go Language Latest GoLang version installed on your system…","fields":{"slug":"/engineering/mongodb-as-datasource-in-golang/"},"html":"<h2 id=\"before-you-get-started\" style=\"position:relative;\"><a href=\"#before-you-get-started\" aria-label=\"before you get started 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>Before You Get Started</h2>\n<p>This tutorial assumes you have:</p>\n<ul>\n<li>A basic understanding of Go Language</li>\n<li>Latest GoLang version installed on your system</li>\n<li>Latest MongoDB version installed on your system</li>\n</ul>\n<p>In this tutorial, we will use the official <strong><a href=\"https://github.com/mongodb/mongo-go-driver/\">MongoDB Go Driver</a></strong> to manage our MongoDB database. In the due process, we will write a program to learn how to install the MongoDB Go Driver and perform CRUD operations with it.</p>\n<h2 id=\"installation\" style=\"position:relative;\"><a href=\"#installation\" aria-label=\"installation 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>Installation</h2>\n<p>First in an empty folder run the below command</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">go mod init gomongo</span></code></pre>\n<p><code>go mod init</code> creates a new go.mod file and automatically imports dependencies when you will run go program. Then create the file main.go and write the below code, We will explain what this code will do in a min.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">package</span><span class=\"mtk1\"> main</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">import</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&quot;context&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&quot;fmt&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&quot;log&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&quot;go.mongodb.org/mongo-driver/bson&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&quot;go.mongodb.org/mongo-driver/mongo&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&quot;go.mongodb.org/mongo-driver/mongo/options&quot;</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=\"mtk3\">// Book - We will be using this Book type to perform crud operations</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">type</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Book</span><span class=\"mtk1\"> </span><span class=\"mtk4\">struct</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  Title     </span><span class=\"mtk10\">string</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  Author    </span><span class=\"mtk10\">string</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ISBN      </span><span class=\"mtk10\">string</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  Publisher </span><span class=\"mtk10\">string</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  Copies     </span><span class=\"mtk10\">int</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\">func</span><span class=\"mtk1\"> </span><span class=\"mtk11\">main</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=\"mtk3\">// Set client options</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">clientOptions</span><span class=\"mtk1\"> := options.</span><span class=\"mtk11\">Client</span><span class=\"mtk1\">().</span><span class=\"mtk11\">ApplyURI</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;mongodb://localhost:27017&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk3\">// Connect to MongoDB</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">client</span><span class=\"mtk1\">, </span><span class=\"mtk12\">err</span><span class=\"mtk1\"> := mongo.</span><span class=\"mtk11\">Connect</span><span class=\"mtk1\">(context.</span><span class=\"mtk11\">TODO</span><span class=\"mtk1\">(), clientOptions)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> err != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    log.</span><span class=\"mtk11\">Fatal</span><span class=\"mtk1\">(err)</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=\"mtk3\">// Check the connection</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">err</span><span class=\"mtk1\"> = client.</span><span class=\"mtk11\">Ping</span><span class=\"mtk1\">(context.</span><span class=\"mtk11\">TODO</span><span class=\"mtk1\">(), </span><span class=\"mtk4\">nil</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> err != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    log.</span><span class=\"mtk11\">Fatal</span><span class=\"mtk1\">(err)</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\">  fmt.</span><span class=\"mtk11\">Println</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Connected to MongoDB!&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">booksCollection</span><span class=\"mtk1\"> := client.</span><span class=\"mtk11\">Database</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;testdb&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">Collection</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;books&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>In the above code, we have imported the bson, mongo, and mongo/options packages of mongo-driver and defined a <code>Book</code> type which will be used in this tutorial</p>\n<p>In the main function first, we created clientOptions with MongoDB URL and credentials and pass it to <code>mongo.Connect</code> function, Once connected we can check our connection by <code>client.Ping</code> function.</p>\n<p>The following code will use <code>booksCollection</code> variable to query the <code>books</code> collection from testdb.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">booksCollection</span><span class=\"mtk1\"> := client.</span><span class=\"mtk11\">Database</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;testdb&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">Collection</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;books&quot;</span><span class=\"mtk1\">)</span></span></code></pre>\n<h2 id=\"insert-documents\" style=\"position:relative;\"><a href=\"#insert-documents\" aria-label=\"insert documents 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>Insert Documents</h2>\n<p>First Let's create a Book struct to insert into the collection, in below code we are using <code>collection.InsertOne</code> function to insert a single document in the collection</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">// Insert One document</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">book1</span><span class=\"mtk1\"> := Book{</span><span class=\"mtk8\">&quot;Animal Farm&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;George Orwell&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;0451526341&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;Signet Classics&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk7\">100</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">insertResult</span><span class=\"mtk1\">, </span><span class=\"mtk12\">err</span><span class=\"mtk1\"> := booksCollection.</span><span class=\"mtk11\">InsertOne</span><span class=\"mtk1\">(context.</span><span class=\"mtk11\">TODO</span><span class=\"mtk1\">(), book1)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> err != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    log.</span><span class=\"mtk11\">Fatal</span><span class=\"mtk1\">(err)</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\">fmt.</span><span class=\"mtk11\">Println</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Inserted a single document: &quot;</span><span class=\"mtk1\">, insertResult.InsertedID)</span></span></code></pre>\n<p>To insert multiple documents at once we need to create a slice of <code>Book</code> object and pass it to <code>collection.InsertMany</code></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">// Insert multiple documents</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">book2</span><span class=\"mtk1\"> := Book{</span><span class=\"mtk8\">&quot;Super Freakonomics&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;Steven D. Levitt&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;0062312871&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;HARPER COLLINS USA&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk7\">100</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">book3</span><span class=\"mtk1\"> := Book{</span><span class=\"mtk8\">&quot;The Alchemist&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;Paulo Coelho&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;0062315005&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;HarperOne&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk7\">100</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">multipleBooks</span><span class=\"mtk1\"> := []</span><span class=\"mtk4\">interface</span><span class=\"mtk1\">{}{book2, book3}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">insertManyResult</span><span class=\"mtk1\">, </span><span class=\"mtk12\">err</span><span class=\"mtk1\"> := booksCollection.</span><span class=\"mtk11\">InsertMany</span><span class=\"mtk1\">(context.</span><span class=\"mtk11\">TODO</span><span class=\"mtk1\">(), multipleBooks)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> err != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    log.</span><span class=\"mtk11\">Fatal</span><span class=\"mtk1\">(err)</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\">fmt.</span><span class=\"mtk11\">Println</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Inserted multiple documents: &quot;</span><span class=\"mtk1\">, insertManyResult.InsertedIDs)</span></span></code></pre>\n<h2 id=\"update-documents\" style=\"position:relative;\"><a href=\"#update-documents\" aria-label=\"update documents 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>Update Documents</h2>\n<p>We can update a single document by function  <code>collection.UpdateOne</code>. It requires a filter document to match documents in the collection and an updated document to describe the update operation. You can build these using bson.D types. The below code will match the book with <em>ISBN</em> <em>0451526341</em> and increment the copies field by <em>10</em></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">//Update one document</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">filter</span><span class=\"mtk1\"> := bson.D{{</span><span class=\"mtk8\">&quot;isbn&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;0451526341&quot;</span><span class=\"mtk1\">}}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">update</span><span class=\"mtk1\"> := bson.D{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span><span class=\"mtk8\">&quot;$inc&quot;</span><span class=\"mtk1\">, bson.D{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        {</span><span class=\"mtk8\">&quot;copies&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk7\">10</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=\"mtk12\">updateResult</span><span class=\"mtk1\">, </span><span class=\"mtk12\">err</span><span class=\"mtk1\"> := booksCollection.</span><span class=\"mtk11\">UpdateOne</span><span class=\"mtk1\">(context.</span><span class=\"mtk11\">TODO</span><span class=\"mtk1\">(), filter, update)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> err != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    log.</span><span class=\"mtk11\">Fatal</span><span class=\"mtk1\">(err)</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\">fmt.</span><span class=\"mtk11\">Printf</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Matched %v documents and updated %v documents.</span><span class=\"mtk6\">\\n</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\">, updateResult.MatchedCount, updateResult.ModifiedCount)</span></span></code></pre>\n<blockquote>\n<p>You can also update more than one documents at once in a single collection by function <code>collection.UpdateMany</code>, In it, we need to pass filter document and update document same as <code>collection.UpdateOne</code></p>\n</blockquote>\n<h2 id=\"find-documents\" style=\"position:relative;\"><a href=\"#find-documents\" aria-label=\"find documents 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>Find Documents</h2>\n<p>To find a single document, we can use function <code>collection.FindOne()</code>, we will pass a filter document and decode the result in the <code>Book</code> type variable</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">// A variable in which result will be decoded</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">result</span><span class=\"mtk1\"> Book</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">err</span><span class=\"mtk1\"> = booksCollection.</span><span class=\"mtk11\">FindOne</span><span class=\"mtk1\">(context.</span><span class=\"mtk11\">TODO</span><span class=\"mtk1\">(), filter).</span><span class=\"mtk11\">Decode</span><span class=\"mtk1\">(&result)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> err != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    log.</span><span class=\"mtk11\">Fatal</span><span class=\"mtk1\">(err)</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\">fmt.</span><span class=\"mtk11\">Printf</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Found a single document: %+v</span><span class=\"mtk6\">\\n</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\">, result)</span></span></code></pre>\n<p>To find multiple documents, we use function <code>collection.Find()</code>. This method returns a Cursor, It provides a stream of documents on which we can iterate or we can get all the docs by function <code>cursor.All()</code> in a slice of <code>Book</code> type. </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">cursor</span><span class=\"mtk1\">, </span><span class=\"mtk12\">err</span><span class=\"mtk1\"> := booksCollection.</span><span class=\"mtk11\">Find</span><span class=\"mtk1\">(context.</span><span class=\"mtk11\">TODO</span><span class=\"mtk1\">(), bson.D{{}})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> err != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  log.</span><span class=\"mtk11\">Fatal</span><span class=\"mtk1\">(err)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">books</span><span class=\"mtk1\"> []Book</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk12\">err</span><span class=\"mtk1\"> = cursor.</span><span class=\"mtk11\">All</span><span class=\"mtk1\">(context.</span><span class=\"mtk11\">TODO</span><span class=\"mtk1\">(), &books); err != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  log.</span><span class=\"mtk11\">Fatal</span><span class=\"mtk1\">(err)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">fmt.</span><span class=\"mtk11\">Printf</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Found multiple documents: %+v</span><span class=\"mtk6\">\\n</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\">, books)</span></span></code></pre>\n<h2 id=\"delete-documents\" style=\"position:relative;\"><a href=\"#delete-documents\" aria-label=\"delete documents 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>Delete Documents</h2>\n<p>We can delete documents from a collection using functions <code>collection.DeleteOne()</code> or <code>collection.DeleteMany()</code>. Here you pass bson.D{{}} as the filter argument, which will match all documents in the collection.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">deleteCollection</span><span class=\"mtk1\">, </span><span class=\"mtk12\">err</span><span class=\"mtk1\"> := booksCollection.</span><span class=\"mtk11\">DeleteMany</span><span class=\"mtk1\">(context.</span><span class=\"mtk11\">TODO</span><span class=\"mtk1\">(), bson.D{{}})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> err != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    log.</span><span class=\"mtk11\">Fatal</span><span class=\"mtk1\">(err)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">fmt.</span><span class=\"mtk11\">Printf</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Deleted %v documents in the books collection</span><span class=\"mtk6\">\\n</span><span class=\"mtk8\">&quot;</span><span class=\"mtk1\">, deleteCollection.DeletedCount)</span></span></code></pre>\n<blockquote>\n<p>Entire collection can be dropped using the collection.Drop() function, it will remove all documents and metadata, such as indexes from the collection</p>\n</blockquote>\n<p>Once you have done all the operation, don't forget to close the MongoDB connection</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"go\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">err</span><span class=\"mtk1\"> = client.</span><span class=\"mtk11\">Disconnect</span><span class=\"mtk1\">(context.</span><span class=\"mtk11\">TODO</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">if</span><span class=\"mtk1\"> err != </span><span class=\"mtk4\">nil</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    log.</span><span class=\"mtk11\">Fatal</span><span class=\"mtk1\">(err)</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\">fmt.</span><span class=\"mtk11\">Println</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Connection to MongoDB closed.&quot;</span><span class=\"mtk1\">)</span></span></code></pre>\n<p>Now you can easily use MongoDB as Datasource in your go application, You can found the complete code used in this tutorial on our <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/GoLang/MongoDriverForGolang\">Github Repo</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  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\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 .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk6 { color: #D7BA7D; }\n</style>","frontmatter":{"date":"September 21, 2020","updated_date":null,"description":"Learn how to use MongoDB as a data source for your Go application using the mongo-go driver","title":"Using MongoDB as Datasource in GoLang","tags":["Go","MongoDB"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/c46c9414b00b97863489d5b361d13210/58556/gomongo.webp","srcSet":"/static/c46c9414b00b97863489d5b361d13210/61e93/gomongo.webp 200w,\n/static/c46c9414b00b97863489d5b361d13210/1f5c5/gomongo.webp 400w,\n/static/c46c9414b00b97863489d5b361d13210/58556/gomongo.webp 800w,\n/static/c46c9414b00b97863489d5b361d13210/99238/gomongo.webp 1200w,\n/static/c46c9414b00b97863489d5b361d13210/7c22d/gomongo.webp 1600w,\n/static/c46c9414b00b97863489d5b361d13210/25f09/gomongo.webp 1920w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Puneet Singh","github":"puneetsingh24","avatar":null}}}},{"node":{"excerpt":"We often hear that JavaScript is a single-threaded programming language, which means it executes all of the instructions line by line in a…","fields":{"slug":"/engineering/understanding-event-loop/"},"html":"<p>We often hear that JavaScript is a single-threaded programming language, which means it executes all of the instructions line by line in a synchronous manner. Thus since everything works on the main thread, there seems to be no possibility of executing parallel processes in JavaScript.</p>\n<p>But now let's assume that we have a function which is taking some time to execute, for example in the below function which is having a loop over 10k times, the <code>console.log()</code> would be executed once the loop is over and in the meantime, our UI interaction with the browser would be interrupted.</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\">someTimeTakingFunc</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\">var</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=\"mtk7\">10000</span><span class=\"mtk1\">; </span><span class=\"mtk12\">i</span><span class=\"mtk1\">++) {</span></span>\n<span class=\"grvsc-line\"></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;Loop has been executed&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>The above scenario seems to be impractical, but there might be cases where any function can take an indeterminate amount of time and our main thread would be blocked, for example calling an API for fetching data from the server-side. And this is the practical use case we are dealing with in development every day. So how JavaScript handles this and where does the event loop come into the picture? We will surely get to know this, but before moving further, let's understand the basic memory architecture in JavaScript.</p>\n<h3 id=\"memory-organization-of-javascript\" style=\"position:relative;\"><a href=\"#memory-organization-of-javascript\" aria-label=\"memory organization of javascript 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>Memory Organization of JavaScript:</h3>\n<p>The Javascript Engine consists of two main components:</p>\n<ul>\n<li><strong>Memory Heap</strong> — this is where the memory allocation happens, all of our object variables are assigned here in a random manner.</li>\n<li><strong>Call Stack</strong> — this is where your function calls are stored.</li>\n</ul>\n<h3 id=\"understanding-the-call-stack\" style=\"position:relative;\"><a href=\"#understanding-the-call-stack\" aria-label=\"understanding the call stack 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>Understanding the Call Stack</h3>\n<p>Call stack is a LIFO (last in first out) data structure. All of the function calls are pushed into this call stack and are said to be a frame. In short function, a stack is nothing but the simple stack data structure which keeps track of the function currently being executed.</p>\n<p>Let's understand the above concept with the example of the following code snippet:</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=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">square</span><span class=\"mtk1\">(</span><span class=\"mtk12\">b</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\">b</span><span class=\"mtk1\"> * </span><span class=\"mtk12\">b</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\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">cube</span><span class=\"mtk1\">(</span><span class=\"mtk12\">x</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\">x</span><span class=\"mtk1\"> * </span><span class=\"mtk11\">square</span><span class=\"mtk1\">(</span><span class=\"mtk12\">x</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=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk11\">cube</span><span class=\"mtk1\">(</span><span class=\"mtk7\">8</span><span class=\"mtk1\">));</span></span></code></pre>\n<p>The above snippet is an example of defining a <code>cube</code>  function, which is calling a <code>square</code> function, to find the cube of a number passed in the argument. But how does this work in call stack? Let's understand step by step: </p>\n<ol>\n<li>When we call the <code>console.log()</code> line, this <code>code/function</code> is pushed into the call stack. </li>\n<li>Now the above <code>console.log()</code> function is called the <code>cube</code> function, hence this function is pushed into the stack. </li>\n<li>After this the <code>cube</code> function is calling the <code>square</code> function, and now this would be pushed into the stack. </li>\n<li>Now once the <code>square</code> function is executed, and the result is returned, then the <code>square</code> function is popped out of the stack. </li>\n<li>Since at this step, we have got the <code>square</code> function result, so <code>cube</code> function would be executed and popped out of the call stack. </li>\n<li>At last, the <code>console.log()</code> would be executed and this function would be popped out of the stack and the stack would now be empty.</li>\n</ol>\n<p><img src=\"/504d2520aed0a4833e4f7642bd8b5ccd/call_stack.webp\" alt=\"Call Stack Execution\"></p>\n<p>Now since we have understood that call stacks are possible to execute the function in a step by step manner, there seems to be no possibility of keeping something into parallel. But there is something called <strong>\"WEB APIs\"</strong> in the browser environment, which is some additional capabilities provided by browsers in addition to JavaScript Engine.</p>\n<h3 id=\"javascript-web-apis\" style=\"position:relative;\"><a href=\"#javascript-web-apis\" aria-label=\"javascript web apis 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>Javascript Web APIs</h3>\n<p>These are the additional functionality, that helps us perform some additional tasks which cannot be run using the main thread. However, since our JavaScript runtime is single-threaded, it can export some tasks to the WEB APIs which helps us to respond to multiple threads. Example of some web APIs are:</p>\n<ul>\n<li>DOM </li>\n<li>Ajax (Network requests)</li>\n<li>setTimeout()</li>\n</ul>\n<p>For instance, <code>setTimeout()</code> is called, the browser delegates the task to a different thread to calculate the time interval specified in the argument of the <code>setTimeout()</code> method, and once done this tread would then call the desired function in callback stack.</p>\n<p>Since JavaScript is single-threaded, the browser has the capability of delegating the task in multiple threads. But how does the event loop help in these executions? But now we are good to go ahead with Event Loop. </p>\n<h3 id=\"event-loop--event-queue\" style=\"position:relative;\"><a href=\"#event-loop--event-queue\" aria-label=\"event loop  event queue 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>Event Loop &#x26;&#x26; Event Queue</h3>\n<p>Since we know that Web APIs delegate some of the tasks to different threads, on completion of these tasks, how the main or desired functions are sent to the call stack. </p>\n<p>Event Queue is a special queue, which keeps track of all the functions queues, which are needed to be pushed into the call stack.\nThe event queue is responsible for sending new functions to the track for processing. The queue data structure is required to maintain the correct sequence in which all operations should be sent for execution.</p>\n<p>Let's take an example, in the following example, we are using a <code>setTimeout</code> function, which will log the \"executed\" string after 2000 milliseconds. </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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">setTimeout</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=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Executed&quot;</span><span class=\"mtk1\">;)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }, </span><span class=\"mtk7\">2000</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>Now when a setTimeout operation is processed in the call stack. On its execution, it calls a web API which fires a timer for 2000 milliseconds. After 2000 milliseconds has been elapsed, the web API, place the callback function of <code>setTimeout</code> in the event queue. </p>\n<p>Here need to mention that, just placing our function does not necessarily imply that the function will get executed. This function has to be pushed into the call stack for execution and here the event loop comes into the picture. The event loop waits for the function stack to be empty, once the call stack is empty this will push the first function from the event queue to the call stack, and in this way, the desired function will be called.</p>\n<p><img src=\"/fedd28728cea8794363a7aa0efaafb58/event_loop_illustration.webp\" alt=\"Event Loop\"></p>\n<p>Thus event loop works in a cyclic manner, where it continually checks whether or not the call stack is empty. If it is empty, new functions are added from the event queue. If it is not, then the current function call is processed.</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 .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n</style>","frontmatter":{"date":"September 19, 2020","updated_date":null,"description":"Learn the basic concepts about the JavaScript Event Loop.","title":"Understanding event loop in JavaScript","tags":["JavaScript","event-loop","call stack","event queue","multi-threaded"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/a6f240c6e67891e816aa9b6541eeb62b/58556/index.webp","srcSet":"/static/a6f240c6e67891e816aa9b6541eeb62b/61e93/index.webp 200w,\n/static/a6f240c6e67891e816aa9b6541eeb62b/1f5c5/index.webp 400w,\n/static/a6f240c6e67891e816aa9b6541eeb62b/58556/index.webp 800w,\n/static/a6f240c6e67891e816aa9b6541eeb62b/99238/index.webp 1200w,\n/static/a6f240c6e67891e816aa9b6541eeb62b/135cd/index.webp 1280w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Aman Agrawal","github":"aman-agrwl","avatar":null}}}},{"node":{"excerpt":"Have you ever thought about what the world would be like if open-source didn't exist? It's hard to imagine a world without open source these…","fields":{"slug":"/engineering/loginradius-supports-hacktoberfest-2020/"},"html":"<h2 id=\"have-you-ever-thought-about-what-the-world-would-be-like-if-open-source-didnt-exist\" style=\"position:relative;\"><a href=\"#have-you-ever-thought-about-what-the-world-would-be-like-if-open-source-didnt-exist\" aria-label=\"have you ever thought about what the world would be like if open source didnt exist 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>Have you ever thought about what the world would be like if open-source didn't exist?</h2>\n<p>It's hard to imagine a world without open source these days. Open source powers the biggest organizations of today's world. Open-source software like <a href=\"https://en.wikipedia.org/wiki/Linux\">Linux</a> runs most of today's servers and also powers the <a href=\"https://en.wikipedia.org/wiki/Android_(operating_system)\">Android Operating System</a>.</p>\n<h2 id=\"introducing-hacktoberfest-2020\" style=\"position:relative;\"><a href=\"#introducing-hacktoberfest-2020\" aria-label=\"introducing hacktoberfest 2020 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>Introducing Hacktoberfest 2020</h2>\n<h4 id=\"in-a-gist-hacktoberfest-is-a-festival-of-giving-back-to-the-community\" style=\"position:relative;\"><a href=\"#in-a-gist-hacktoberfest-is-a-festival-of-giving-back-to-the-community\" aria-label=\"in a gist hacktoberfest is a festival of giving back to the community 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 a gist hacktoberfest is a festival of \"giving back to the community\".</h4>\n<p>Hacktoberfest is a month-long celebration of open-source software in October month run by DigitalOcean in partnership with GitHub and DEV. Hacktoberfest is open to everyone in our global community!</p>\n<p><strong>From Official Website:</strong></p>\n<blockquote>\n<p>Hacktoberfest is open to everyone in our global community. Whether you’re new to development, a student, long-time contributor, event host, or company of any size, you can help drive the growth of open source and make positive contributions to an ever-growing community. All backgrounds and skill levels are encouraged to complete the challenge.</p>\n</blockquote>\n<p>The purpose of this month-long celebration is to get people started in open source and give back to the open-source community.</p>\n<p>It is the easiest way to get into open source for people who have never contributed to open-source community or find it difficult to contribute.</p>\n<h3 id=\"how-to-contribute-to-hacktoberfest\" style=\"position:relative;\"><a href=\"#how-to-contribute-to-hacktoberfest\" aria-label=\"how to contribute to hacktoberfest 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 contribute to Hacktoberfest?</h3>\n<p>Anyone can contribute to hacktoberfest by registering at <a href=\"https://hacktoberfest.digitalocean.com/\">hacktoberfest website</a> anytime between 1st October to 31st October.</p>\n<p>During this time, anyone who wishes to be part of this month-long fest needs to open four quality pull requests on any of the open-source projects on Github.</p>\n<h3 id=\"how-to-find-projects\" style=\"position:relative;\"><a href=\"#how-to-find-projects\" aria-label=\"how to find projects 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 find Projects?</h3>\n<p>Finding projects can be a bit challenging. It can be the tools you are already using, or different tools can be used to find the issues based on various labels. Tools like <a href=\"http://issuehub.io/\">issuehub</a> are really helpful for the same.</p>\n<p>This year <a href=\"https://www.loginradius.com/\">LoginRadius</a> is going to be part of Hacktoberfest by open-sourcing a lot of its projects and accepting contributions on them including its <a href=\"https://www.loginradius.com/blog/engineering/\">Engineering Blog</a>.</p>\n<h3 id=\"getting-loginradius-branded-swags\" style=\"position:relative;\"><a href=\"#getting-loginradius-branded-swags\" aria-label=\"getting loginradius branded swags 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>Getting LoginRadius branded swags</h3>\n<p>Like I said, this year <strong>LoginRadius</strong> will be part of hacktoberfest and yes, we are here with some <strong>cool swags.</strong> We have got around <strong>500 t-shirts</strong> for people contributing to our open source repositories. We will soon share details on how to get LoginRadius swags as well as our open source repositories on our <a href=\"https://www.loginradius.com/blog/async\">Blog</a>.</p>\n<p>Stay tuned and <strong>don’t forget to mention your open-source projects for us to contribute.</strong></p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"September 18, 2020","updated_date":null,"description":"Open Source is changing the world, One Pull Request at a time. Join LoginRadius this year in supporting hacktoerbest 2020 by contributing to open source and get cool swags from LoginRadius","title":"LoginRadius Supports Hacktoberfest 2020","tags":["hacktoberfest","open-source","LoginRadius"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5873015873015872,"src":"/static/9a2056972f92077b2af8b32ecc2fcbdd/58556/hacktober-fest-banner.webp","srcSet":"/static/9a2056972f92077b2af8b32ecc2fcbdd/61e93/hacktober-fest-banner.webp 200w,\n/static/9a2056972f92077b2af8b32ecc2fcbdd/1f5c5/hacktober-fest-banner.webp 400w,\n/static/9a2056972f92077b2af8b32ecc2fcbdd/58556/hacktober-fest-banner.webp 800w,\n/static/9a2056972f92077b2af8b32ecc2fcbdd/e30b5/hacktober-fest-banner.webp 1000w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Hridayesh Sharma","github":"vyasriday","avatar":null}}}},{"node":{"excerpt":"Businesses need to keep their consumers loyal to their products, services, and the brands, at large—which is why an efficient consumer…","fields":{"slug":"/identity/loginradius-identity-experience-framework/"},"html":"<p>Businesses need to keep their consumers loyal to their products, services, and the brands, at large—which is why an efficient consumer interface is the need of the hour. It can deliver consumer experiences that are most conducive to the success of any business.</p>\n<p>Our recently launched <a href=\"https://www.loginradius.com/identity-experience-framework/\">Identity Experience Framework</a> is a powerful orchestration feature that can be used to quickly implement any customization required on your identity page. It also meets the critical customization, formatting, design, and authentication demands of all businesses.</p>\n<h2 id=\"intent-behind-the-launch\" style=\"position:relative;\"><a href=\"#intent-behind-the-launch\" aria-label=\"intent behind the launch 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>Intent Behind the Launch</h2>\n<p>We wanted businesses to enjoy a hassle-free authentication and customization of identity pages, alongside <a href=\"https://www.loginradius.com/customer-experience-solutions/\">delivering consumer experiences</a> at its best.</p>\n<p>Hence, our LoginRadius Identity Experience Framework  benefits businesses in the following ways: </p>\n<ul>\n<li><strong>Increase consumer interaction</strong>: When implemented correctly, the feature offers a better consumer interface and experience. It also increases consumer satisfaction and interaction coherently. </li>\n<li><strong>Boost reputation and revenues</strong>: It offers collaborated designing and technical skills to deliver exceptional consumer experiences. Consequently, it boosts business reputation and amplifies the scope of revenue. </li>\n<li><strong>Builds trust and loyalty</strong>: By customizing the consumer interface to the business needs and as per consumers' demand, it is more likely to build loyalty and trust for consumers, and attract more traffic.</li>\n<li><strong>Centralized implementation</strong>: In the case of multiple applications, the Identity Experience Framework facilitates centralized <a href=\"https://www.loginradius.com/authentication/\">authentication too</a>. </li>\n</ul>\n<h2 id=\"key-capabilities-of-loginradius-identity-experience-framework\" style=\"position:relative;\"><a href=\"#key-capabilities-of-loginradius-identity-experience-framework\" aria-label=\"key capabilities of loginradius identity experience framework 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>Key Capabilities of LoginRadius Identity Experience Framework</h2>\n<p><a href=\"https://www.loginradius.com/resource/loginradius-identity-experience-framework-datasheet\"><img src=\"/0eed22bce7145afabda1464bcdb1672c/IDX-Product.webp\"></a></p>\n<p><strong>Predefined themes</strong>: It offers predefined themes designed to fit all business requirements as per industry standards. </p>\n<p><strong>Ready-to-use scripts</strong>: It offers complete customization, formatting, design for all authentication-related pages, along with quick replaceable scripts for pages like login, registration, forgot password, etc.</p>\n<p><strong>Customizable solution</strong>: While the Basic Editor allows the customization of the background image, logo color, content customization for sign up page, etc., Advanced Editor allows prompt changes via \"Replace\" options like complete customization, design via HTML, CSS, Javascript for login, registration pages, etc. </p>\n<p><strong>Branding preview</strong>: It offers real-time preview for the customization made to logos, images, etc. to visualize the change before implementing it.</p>\n<p><strong>Quick implementation</strong>: It handles and manages implementation in a very efficient and smooth manner.</p>\n<h2 id=\"a-final-word\" style=\"position:relative;\"><a href=\"#a-final-word\" aria-label=\"a final word 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>A Final Word</h2>\n<p>With the LoginRadius Identity Experience Framework, businesses can enjoy a complete set of customizable solutions and provide consumers with seamless experiences. Be it, tweaking the authentication flow or changing the interface designs—this feature can do them all. </p>\n<p><a href=\"https://www.loginradius.com/contact-us?utm_source=blog&#x26;utm_medium=web&#x26;utm_campaign=loginradius-identity-experience-framework\"><img src=\"/788a6a84e389edac18728007099fdc1d/Book-a-free-demo-request.webp\" alt=\"book-a-free-demo-loginradius\"></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</style>","frontmatter":{"date":"September 18, 2020","updated_date":null,"description":"Overall, companies need to keep their customers loyal to their goods, services , and brands — which is why the need for the hour is an effective user interface. It can have customer interactions that are most conducive to any company's success.","title":"Announcement - LoginRadius Delivers Exceptional Authentication With The Launch Of Identity Experience Framework","tags":["authentication","identity management","cx"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.408450704225352,"src":"/static/93283d4127ab6cd9e3f3d5c33cd47707/c0524/IDx.webp","srcSet":"/static/93283d4127ab6cd9e3f3d5c33cd47707/61e93/IDx.webp 200w,\n/static/93283d4127ab6cd9e3f3d5c33cd47707/1f5c5/IDx.webp 400w,\n/static/93283d4127ab6cd9e3f3d5c33cd47707/c0524/IDx.webp 769w","sizes":"(max-width: 769px) 100vw, 769px"}}},"author":{"id":"Karl Wittig","github":null,"avatar":null}}}},{"node":{"excerpt":"There are more than 1 million websites or apps are using \"SignIn with Facebook\" or \"Login with Facebook\". Do you know why they are using…","fields":{"slug":"/engineering/login-with-facebook/"},"html":"<p>There are more than 1 million websites or apps are using <strong>\"SignIn with Facebook\"</strong> or <strong>\"Login with Facebook\"</strong>. Do you know why they are using Facebook login and how it is beneficial in conversion?</p>\n<p>According to multiple surveys, there are more than 3 billion users worldwide are using social media and it is around 50% of the world's population. </p>\n<p><img src=\"/6df490f8885582a5f30d79095d46e5de/facebook-login-wow.webp\" alt=\"login-with-facebook\"></p>\n<p>The biggest challenge and most important things are to make user registration and login quick and easy while developing our application. The registration forms required a lot of data that need to be filled by users manually and it causes lost, potential users. Additionally, users need to enter their usernames/emails and passwords in the login forms to authenticate themselves and also need to remember more individual IDs and passwords. </p>\n<p>Social Login allows customers to bring their existing social identities and use them to register and log in without creating a new profile explicitly. </p>\n<p>Facebook is the most favorite social media provider in comparison to other social media providers and the number of active Facebook users growing day by day.</p>\n<p>In this article, I will explain how you can implement <strong>“Log in with Facebook”</strong>  on your website or mobile app in a very easy manner. </p>\n<p>Facebook work on the OAuth 2.0 protocol and most of the social providers like Facebook, Google, Microsoft, Linkedin are supporting OAuth 2.0. Refer to this article <a href=\"/oauth2/\">Getting Started with OAuth 2.0</a> to know about OAuth flow. </p>\n<h3 id=\"create-your-facebook-login-app\" style=\"position:relative;\"><a href=\"#create-your-facebook-login-app\" aria-label=\"create your facebook login app 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 Your Facebook Login App</h3>\n<p>Here you can find the complete step by step guide to create your Facebook Login App.</p>\n<h4 id=\"step-1\" style=\"position:relative;\"><a href=\"#step-1\" aria-label=\"step 1 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>Step 1</h4>\n<p>Go to <a href=\"https://developers.facebook.com\">Facebook Developer</a> and log in using your Facebook credentials.</p>\n<p><strong>NOTE</strong>: Please do not log in using a business account as Facebook will not allow you to create an app if you do so.</p>\n<p><img src=\"/e95a7be84484abf90d878b6d4702b8b3/loginadius-facebook-img1.webp\" alt=\"Facebook Login\"></p>\n<h4 id=\"step-2\" style=\"position:relative;\"><a href=\"#step-2\" aria-label=\"step 2 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>Step 2</h4>\n<p>Select the <strong>My Apps</strong> as displayed on the below screen.</p>\n<p><img src=\"/ba396b3223c249de8a434861d9d70b8c/loginadius-facebook-img2.webp\" alt=\"Facebook Login\"></p>\n<h4 id=\"step-3\" style=\"position:relative;\"><a href=\"#step-3\" aria-label=\"step 3 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>Step 3</h4>\n<p>Click on <strong>Add a New App</strong> as displayed in the below screen.</p>\n<p><img src=\"/a135659e8a2ad458e3d40a58a0503c57/loginadius-facebook-img3.webp\" alt=\"Facebook Login\"></p>\n<h4 id=\"step-4\" style=\"position:relative;\"><a href=\"#step-4\" aria-label=\"step 4 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>Step 4</h4>\n<p>Input display name and contact email. Once you have done so, click on <strong>Create App ID</strong></p>\n<p><img src=\"/76488dc008c92b31560355074b9e8e57/loginadius-facebook-img4.webp\" alt=\"Facebook Login\"></p>\n<h4 id=\"step-5\" style=\"position:relative;\"><a href=\"#step-5\" aria-label=\"step 5 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>Step 5</h4>\n<p>In the security check, Complete the security steps and click on the <strong>submit</strong> button.</p>\n<p><img src=\"/7eee909de66ac55acd1b149241ded179/loginadius-facebook-img5.webp\" alt=\"Facebook Login\"></p>\n<h4 id=\"step-6\" style=\"position:relative;\"><a href=\"#step-6\" aria-label=\"step 6 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>Step 6</h4>\n<p>Once you land on the App dashboard, Select Facebook Login, and click <strong>Set Up</strong>.</p>\n<p><img src=\"/977b5c1dc415d9afff25149ae760706d/loginadius-facebook-img6.webp\" alt=\"Facebook Login\"></p>\n<h4 id=\"step-7\" style=\"position:relative;\"><a href=\"#step-7\" aria-label=\"step 7 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>Step 7</h4>\n<p>Click on Settings in the sidebar under Facebook Login. Turn on Client OAuth Login. Turn on Web OAuth Login. Put the valid redirect URL on <strong>\"Valid OAuth redirect URIs\"</strong>. Click on the Save button.</p>\n<p><img src=\"/6a83a418aad05a3d898f7702b0f59d3b/loginadius-facebook-img7.webp\" alt=\"Facebook Login\"></p>\n<h4 id=\"step-8\" style=\"position:relative;\"><a href=\"#step-8\" aria-label=\"step 8 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>Step 8</h4>\n<p>Click on Basic under settings in the sidebar. Under App, Domains include your website Url. Enter all the required details. Change the status of the app from Development to Live from the top-right corner. Click on the <strong>Save Changes</strong> button.</p>\n<p>Now your Facebook app is ready. You can start implementing Facebook login\n<img src=\"/870b799fd61f5a1ceb86db30e3a830e7/loginadius-facebook-img8.webp\" alt=\"Facebook Login\"></p>\n<h3 id=\"data-selection\" style=\"position:relative;\"><a href=\"#data-selection\" aria-label=\"data selection 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>Data Selection</h3>\n<p>When a user logs into your website or app via Facebook Login, you can access the user's data stored on Facebook. Facebook only allows the basic profile data permissions for a new Facebook app.  To get more data according to your business requirement,  you need to enable additional permissions on your Facebook app. Facebook is supporting around <a href=\"https://developers.facebook.com/docs/permissions/reference\">42 permissions</a>. You need to choose user data that you want to collect from Facebook. </p>\n<h3 id=\"submit-your-facebook-login-app-for-review\" style=\"position:relative;\"><a href=\"#submit-your-facebook-login-app-for-review\" aria-label=\"submit your facebook login app for review 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>Submit Your Facebook Login App For Review</h3>\n<p>To grab more than basic profile data points or asking for additional permissions from your users, your Facebook apps go through the review process. Sometimes businesses require some additional permissions on the Facebook app and for that, you need to submit your Facebook app for approval before starting to ask for additional information. </p>\n<p>The Facebook app review process is pretty much simple, Please refer to this document <a href=\"https://www.loginradius.com/docs/api/v2/admin-console/social-provider/app-reviews/facebook-app-review/\">here</a> for the Facebook App Review Process. </p>\n<h3 id=\"add-login-with-the-facebook-button-on-your-site\" style=\"position:relative;\"><a href=\"#add-login-with-the-facebook-button-on-your-site\" aria-label=\"add login with the facebook button on your site 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 with the Facebook button on Your Site</h3>\n<p>Implement Facebook login to a web page is very easy using Facebook’s JavaScript SDK. Facebook is providing <a href=\"https://developers.facebook.com/docs/facebook-login/web\">documentation and instructions</a> along with code examples to implement the login system. </p>\n<p>Let's see how we can add the Facebook login interface. For this, we just need to copy and paste the code provided to us by Facebook. Here I have added some customization to the existing code </p>\n<p>Place this code in the body section of your HTML code. </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=\"mtk1\">&lt;!-- </span><span class=\"mtk12\">The</span><span class=\"mtk1\"> </span><span class=\"mtk12\">JS</span><span class=\"mtk1\"> </span><span class=\"mtk12\">SDK</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Login</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Button</span><span class=\"mtk1\"> --&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">fb</span><span class=\"mtk1\">:</span><span class=\"mtk10\">login-button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">scope</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;public_profile,email&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">onlogin</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;checkLoginState();&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">fb</span><span class=\"mtk1\">:</span><span class=\"mtk10\">login-button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!-- </span><span class=\"mtk12\">The</span><span class=\"mtk1\"> </span><span class=\"mtk12\">JS</span><span class=\"mtk1\"> </span><span class=\"mtk12\">SDK</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Login</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Button</span><span class=\"mtk1\"> --&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;status&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>Now you need to include the JavaScript section. It'll loads the Facebook SDK JavaScript asynchronously.</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\">&lt;!-- </span><span class=\"mtk12\">Load</span><span class=\"mtk1\"> </span><span class=\"mtk12\">the</span><span class=\"mtk1\"> </span><span class=\"mtk12\">JS</span><span class=\"mtk1\"> </span><span class=\"mtk12\">SDK</span><span class=\"mtk1\"> </span><span class=\"mtk12\">asynchronously</span><span class=\"mtk1\"> --&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk1\"> </span><span class=\"mtk12\">async</span><span class=\"mtk1\"> </span><span class=\"mtk12\">defer</span><span class=\"mtk1\"> </span><span class=\"mtk12\">crossorigin</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;anonymous&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">src</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;https://connect.facebook.net/en_US/sdk.js&quot;</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>Next, we'll add the Facebook init function. We just need to replace the app id placeholder with the app id of your app you created in the beginning. You’ll find the placeholder in this line appId: '{your-app-id}'. </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=\"mtk12\">window</span><span class=\"mtk1\">.</span><span class=\"mtk11\">fbAsyncInit</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=\"mtk12\">FB</span><span class=\"mtk1\">.</span><span class=\"mtk11\">init</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">appId      :</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;{your-app-id}&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">cookie     :</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,                     </span><span class=\"mtk3\">// Enable cookies to allow the server to access the session.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">xfbml      :</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,                     </span><span class=\"mtk3\">// Parse social plugins on this webpage.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">version    :</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;v7.0&#39;</span><span class=\"mtk1\">           </span><span class=\"mtk3\">// Use this Graph API version for this call.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    });</span></span></code></pre>\n<p>Next, we need to add the function that handles the response and alters the page contents based on the type of response. I have added this function at the very top of the scripts section.</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\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">checkFacebookLoginStatusCallback</span><span class=\"mtk1\">(</span><span class=\"mtk12\">response</span><span class=\"mtk1\">) {  </span><span class=\"mtk3\">// Called with the results from FB.getLoginStatus().</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\">&#39; Checking Facebook Login Status&#39;</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\">response</span><span class=\"mtk1\">);                   </span><span class=\"mtk3\">// The current login status of the person.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">status</span><span class=\"mtk1\"> === </span><span class=\"mtk8\">&#39;connected&#39;</span><span class=\"mtk1\">) {   </span><span class=\"mtk3\">// Logged into your webpage and Facebook.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">getUserProfile</span><span class=\"mtk1\">();  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    } </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> {                                 </span><span class=\"mtk3\">// Not logged into your webpage or we are unable to tell.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getElementById</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;status&#39;</span><span class=\"mtk1\">).</span><span class=\"mtk12\">innerHTML</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&#39;Please login with Facebook into this webpage.&#39;</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>As you can see, the above function receives a response variable and checks it's status. If it is connected it fetches the logged in users info and outputs this information in the console of your browser, that area is where you could build more onto this script to handle the data. When the login is not authorized, this function changed the HTML on your page to ask you to log in.</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\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">checkLoginState</span><span class=\"mtk1\">() {               </span><span class=\"mtk3\">// Called when a person is finished with the Login Button.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">FB</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getLoginStatus</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">response</span><span class=\"mtk1\">) {   </span><span class=\"mtk3\">// See the onlogin handler</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">checkFacebookLoginStatusCallback</span><span class=\"mtk1\">(</span><span class=\"mtk12\">response</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=\"mtk1\">    </span><span class=\"mtk12\">FB</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getLoginStatus</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">response</span><span class=\"mtk1\">) {   </span><span class=\"mtk3\">// Called after the JS SDK has been initialized.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">checkFacebookLoginStatusCallback</span><span class=\"mtk1\">(</span><span class=\"mtk12\">response</span><span class=\"mtk1\">);        </span><span class=\"mtk3\">// Returns the login status.</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\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getUserProfile</span><span class=\"mtk1\">() {                      </span><span class=\"mtk3\">// Get User Profile using Facebook Graph API after login.</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\">&#39;Welcome!  Fetching your profile information.... &#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">FB</span><span class=\"mtk1\">.</span><span class=\"mtk11\">api</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/me&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">response</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\">&#39;Successful login for: &#39;</span><span class=\"mtk1\"> + </span><span class=\"mtk12\">response</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 class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getElementById</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;status&#39;</span><span class=\"mtk1\">).</span><span class=\"mtk12\">innerHTML</span><span class=\"mtk1\"> =</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&#39;Thanks for logging in, &#39;</span><span class=\"mtk1\"> + </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span><span class=\"mtk1\"> + </span><span class=\"mtk8\">&#39;!&#39;</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>Now if you save this page as login.html and open it in a browser you should see the Facebook Login button. You can also download this code from my <a href=\"https://github.com/VijayShekhawat/login-with-facebook\">GitHub Repo</a> and I have customized it to make it a bit shorter for an explanation.</p>\n<p>Now just Log In and check the console output. You’ll now see some basic info including id, email, first<em>name, gender, last</em>name.</p>\n<p>This is all there is to it. Of course, there are many more options and features available in Facebook documentation to discover.</p>\n<h3 id=\"closing-thoughts\" style=\"position:relative;\"><a href=\"#closing-thoughts\" aria-label=\"closing thoughts 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>Closing Thoughts</h3>\n<p>Social Media platforms are growing day-by-day and simplifying the registration and login process. Consumers can use their existing social identities to register and log in. They don't need to create a separate username/password combination so it is simplifying the Sign in/Signup process.</p>\n<p>LoginRadius supports Sign with Facebook with more than 40 other popular social networks google, twitter, Linkedin, etc. You can implement all the popular social media providers on your website or mobile app in less than 60 seconds.</p>\n<h3 id=\"source\" style=\"position:relative;\"><a href=\"#source\" aria-label=\"source 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>Source</h3>\n<p><a href=\"https://www.statista.com/statistics/278414/number-of-worldwide-social-network-users/\">statista</a> </p>\n<p><a href=\"https://news.netcraft.com/archives/2020/01/21/january-2020-web-server-survey.html\">netcraft</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  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk17 { color: #808080; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n</style>","frontmatter":{"date":"September 16, 2020","updated_date":null,"description":"This article will explain about social login benefits and how we can implement Sign In using Facebook on our website or mobile app.","title":"How to implement Facebook Login","tags":["Login With Facebook","Facebook","Facebook Login","Login","Oauth"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.6666666666666667,"src":"/static/d16e503b9517b5df8496efd994380504/25338/index.webp","srcSet":"/static/d16e503b9517b5df8496efd994380504/61e93/index.webp 200w,\n/static/d16e503b9517b5df8496efd994380504/1f5c5/index.webp 400w,\n/static/d16e503b9517b5df8496efd994380504/25338/index.webp 550w","sizes":"(max-width: 550px) 100vw, 550px"}}},"author":{"id":"Vijay Singh Shekhawat","github":"code-vj","avatar":null}}}},{"node":{"excerpt":"Assuming that the reader of this blog has a fair idea of the docker ecosystem! Docker has changed the world of software development! Since…","fields":{"slug":"/engineering/production-grade-development-using-docker-compose/"},"html":"<blockquote>\n<p>Assuming that the reader of this blog has a fair idea of the docker ecosystem!</p>\n</blockquote>\n<p>Docker has changed the world of software development! Since the last few years, docker has helped the developer community, enterprises, and startups to create solutions quickly and effectively. Also, deployment is relatively hassle-free with docker (conditions apply). And worth mentioning is, it resolves the “Works fine on my system” problem.  </p>\n<p>Well, just not docker, there are many container ecosystems available as an alternative to Docker. For example, Mesos by Apache and Vagrant by Hashicorp. Docker is more loved for what it is <strong>not</strong>, and that is Bulky! Docker is otherwise lightweight, works mostly with Linux and eventually was identified by Kubernetes in 2015. But, that story... some other time!!</p>\n<p>Straight to the context, Docker Compose! Docker compose is a powerful utility that is bundled with Docker installation. Docker-Compose can be used for production and development, to make things virtually seamless.</p>\n<h3 id=\"microservices-and-docker\" style=\"position:relative;\"><a href=\"#microservices-and-docker\" aria-label=\"microservices and docker 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>Microservices and Docker</h3>\n<p>Docker is doing a great job when it comes to describing and developing microservices.</p>\n<p>While working on microservices where quite a few ( <em>being reasonably complicated, in our example 6</em> ) containers talk to each other to complete a task and since it is an end to end task, the whole thing looks very complicated. To rectify :</p>\n<ul>\n<li>the troubles of developing end to end feature</li>\n<li>how it works in integration</li>\n<li>containerizing the application</li>\n</ul>\n<p>the developer has two choices, create a script in a scripting language of choice, or choose docker-compose. Well, docker-compose is an easier option.</p>\n<p>Here in this <em>kind of</em> practical example, we are going to demonstrate a similar situation, where multiple containers talk to each other. We are going to use docker-compose as our primary tool to build and deploy images.</p>\n<p><img src=\"/5f12748a159002c8da296cb7ef6dfb64/example-arch.webp\" alt=\"title\"></p>\n<p>The picture above depicts the architecture of a hypothetical portal of flash sale.</p>\n<p><em>Flash Sale is an e-commerce concept, where an item is made available for sale to the public on a portal at a specific time and in a limited quantity.</em></p>\n<p>The components of the application are</p>\n<ul>\n<li>Gateway</li>\n<li>Frontend (react)</li>\n<li>API server ( node.js)</li>\n<li>SQS ( In this example SQS Emulator)</li>\n<li>Listener (node.js)</li>\n<li>DataStore (mongo-db)</li>\n</ul>\n<p>The application is otherwise fairly simple. Go to the portal, hit the green button which calls an API, the API drops a message to the queue, the listener picks the messages, grabs the item from the database reduces the quantity and updates the datastore again.</p>\n<p>So far so good!</p>\n<h3 id=\"code\" style=\"position:relative;\"><a href=\"#code\" aria-label=\"code 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>Code</h3>\n<p>You may fork a copy from here.</p>\n<p><code>git clone https://github.com/LoginRadius/engineering-blog-samples/tree/master/Docker/docker-compose-dev-sample</code></p>\n<p><img src=\"/22c87d5dce6c5bece2fe6ac24d268451/what-is-the-problem.webp\" alt=\"So what is the problem\"></p>\n<h3 id=\"the-use-of-docker-compose-and-why\" style=\"position:relative;\"><a href=\"#the-use-of-docker-compose-and-why\" aria-label=\"the use of docker compose and why 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>The use of docker-compose and why?</h3>\n<p>Exactly! What is the problem? As such, there is no problem, but it may arise if we do not program or develop it well in an integrated manner. Programming a component and managing it well reduces the time-to-production to a greater degree.</p>\n<blockquote>\n<p><em>I am not a great programmer; I am just a good programmer with great habits.</em></p>\n<ul>\n<li>Martin Fowler</li>\n</ul>\n</blockquote>\n<p>While designing and developing complicated systems where microservices are involved, integration and debugging become cumbersome.</p>\n<p>To ease it up docker-compose acts a friend.</p>\n<p>For the example above we are going to write a docker-compose. Docker-Compose has got <em>powers</em> to</p>\n<ul>\n<li>Build images</li>\n<li>Bring up the whole application ecosystem</li>\n<li>Wipe it up from the memory in one command</li>\n</ul>\n<p>First things first, the Dockerfile.</p>\n<p>Starting from the API. The API needs a docker image to build. The following is the Dockerfile for the same.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">FROM node:alpine</span>\n<span class=\"grvsc-line\">WORKDIR &#39;/app&#39;</span>\n<span class=\"grvsc-line\">COPY ./package.json ./</span>\n<span class=\"grvsc-line\">RUN npm install </span>\n<span class=\"grvsc-line\">COPY . .</span>\n<span class=\"grvsc-line\">CMD [&quot;npm&quot;, &quot;run&quot;, &quot;start&quot;]</span></code></pre>\n<p>Since the other two components, listener and frontend are also written in JavaScript the Dockerfile does not change at all for them too, for this particular example.</p>\n<p>The following is a two-liner Dockerfile for gateway. The conf file targets apiserver and frontend. Please have a look at the configuration file in the repository itself.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">FROM nginx</span>\n<span class=\"grvsc-line\">COPY ./nginx.conf /etc/nginx/conf.d/default.conf</span></code></pre>\n<p>The other 2 components :</p>\n<ul>\n<li>Mongodb has its image. We will leverage that while writing the docker-compose.</li>\n<li>SQS is emulated using softwaremill/elasticmq image.</li>\n</ul>\n<h3 id=\"action\" style=\"position:relative;\"><a href=\"#action\" aria-label=\"action 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>Action!</h3>\n<p>First things first, file version. Since it is all yaml out there, the file <code>version</code> tells docker-compose about the data structure. The data structure which is expected by docker \"compose\".</p>\n<p>so we start the docker-compose as</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">version: &#39;3&#39;</span></code></pre>\n<p>All the components in the docker-compose are known as <code>services</code>. Next, we are going to write some services. Yes, the services we have written for our business.</p>\n<p>Message Queue :</p>\n<p>The message queue shall use <code>softwaremill/elasticmq</code> image out of the box and the applications will access that on port 9324. The service description in docker-compose shall look like this.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">mqserver:</span>\n<span class=\"grvsc-line\">        image: softwaremill/elasticmq</span>\n<span class=\"grvsc-line\">        ports:</span>\n<span class=\"grvsc-line\">            - &#39;9324:9324&#39;</span></code></pre>\n<p>That is analogous to <code>docker run -it -p '9324:9324' softwaremill/elasticmq</code>.</p>\n<p>A bit more complicated service next, mongodb.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">mongodbdb: </span>\n<span class=\"grvsc-line\">        depends_on: </span>\n<span class=\"grvsc-line\">            - mqserver</span>\n<span class=\"grvsc-line\">        image: mongo</span>\n<span class=\"grvsc-line\">        container_name: mongo</span>\n<span class=\"grvsc-line\">        volumes:</span>\n<span class=\"grvsc-line\">            - /data/db:/mongodata</span>\n<span class=\"grvsc-line\">        ports:</span>\n<span class=\"grvsc-line\">            - &#39;27017:27017&#39;</span></code></pre>\n<p>There are a couple of things one may notice more here.</p>\n<p><code>depends_on</code> shall wait for the container of mqserver service to come up, before mongodbdb service goes on air.</p>\n<blockquote>\n<p>Docker is only liable to check the containers when we use depends_on, if you want to check whether your service (which you have embedded) is ready to use or not, use <code>healthcheck</code>and <code>link</code>.</p>\n</blockquote>\n<p>Apart from this, we are mounting a volume and exposing ports for an image mongo which gets pulled directly from the docker container registry. <code>container_name</code> will give the service a name, so that it can be discovered *in the network. *Kind of a domain name in the internal docker-compose network.</p>\n<p>Now the developer's proprietary API service:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">apiserver:</span>\n<span class=\"grvsc-line\">        restart: always</span>\n<span class=\"grvsc-line\">        depends_on: </span>\n<span class=\"grvsc-line\">            - mqserver</span>\n<span class=\"grvsc-line\">            - mongodbdb</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">        build:</span>\n<span class=\"grvsc-line\">            dockerfile: Dockerfile</span>\n<span class=\"grvsc-line\">            context: ../fs-express-api/.</span>\n<span class=\"grvsc-line\">        volumes:</span>\n<span class=\"grvsc-line\">            - /app/node_modules</span>\n<span class=\"grvsc-line\">        environment: </span>\n<span class=\"grvsc-line\">            - NODE_ENV=production</span>\n<span class=\"grvsc-line\">            - AWS_SQS_URL=http://mqserver:9324/</span>\n<span class=\"grvsc-line\">            - AWS_SQS_FQ_URL=http://mqserver:9324/queue/fsqueue</span>\n<span class=\"grvsc-line\">            - AWS_ACCESS_KEY=na</span>\n<span class=\"grvsc-line\">            - AWS_SECRET_ACCESS_KEY=na</span>\n<span class=\"grvsc-line\">            - AWS_REGION=REGION</span>\n<span class=\"grvsc-line\">            - QUEUE_NAME=fsqueue</span>\n<span class=\"grvsc-line\">            - MONGODB_CONNECTION=mongodb://mongo:27017/fsorder</span>\n<span class=\"grvsc-line\">            - API_APP_PORT=5000</span>\n<span class=\"grvsc-line\">        ports:</span>\n<span class=\"grvsc-line\">            - &#39;5000:5000&#39;</span></code></pre>\n<p>The <code>build</code>tag will be used by the <code>docker-compose build</code> command to build an image. The build is defined as Dockerfile and the context is docker context, the directory which you want to use as context. Equivalent to:  <code>docker build -f filename.</code></p>\n<p>The more you are seeing here is <em>environment</em> and <em>restart</em> options. Environment variables are used to set environment variables while running the image. This is another part where docker-compose comes handy. Think about setting all nine environment variables with <code>docker run</code>.</p>\n<p><code>restart</code> is a bit interesting. One may specify a restart policy if the application crashes, which leads to stopping the docker image itself. always specifies to restart the container if it exit.</p>\n<p>In the environment section, one can see mqserver and mongo, instead of the regular localhost and loopback address. This is because when we run docker-compose, it creates a DNS recordset of all the <code>services</code> mentioned. The services can be referred to by their names. A slight deviation here may happen when the container is explicitly named. Here, container_name = mongo is used for service mongodbdb. Hence, the other containers in the environment shall refer to it by mongo and not mongodbdb.</p>\n<p>The pollingmod and frontend services are quite the same.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">    pollingmod:</span>\n<span class=\"grvsc-line\">        restart: always</span>\n<span class=\"grvsc-line\">        depends_on: </span>\n<span class=\"grvsc-line\">            - mqserver</span>\n<span class=\"grvsc-line\">            - mongodbdb</span>\n<span class=\"grvsc-line\">        build:</span>\n<span class=\"grvsc-line\">            dockerfile: Dockerfile</span>\n<span class=\"grvsc-line\">            context: ../polling-mod/</span>\n<span class=\"grvsc-line\">        volumes:</span>\n<span class=\"grvsc-line\">            - /app/node_modules</span>\n<span class=\"grvsc-line\">        environment: </span>\n<span class=\"grvsc-line\">            - AWS_QUEUE_URL=http://mqserver:9324/queue/fsqueue</span>\n<span class=\"grvsc-line\">            - AWS_ACCESS_KEY=na</span>\n<span class=\"grvsc-line\">            - AWS_SECRET_ACCESS_KEY=na</span>\n<span class=\"grvsc-line\">            - AWS_REGION=REGION</span>\n<span class=\"grvsc-line\">            - MONGODB_CONNECTION=mongodb://mongo:27017/fsorder   </span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">    frontend:</span>\n<span class=\"grvsc-line\">        build:</span>\n<span class=\"grvsc-line\">            dockerfile: Dockerfile</span>\n<span class=\"grvsc-line\">            context: ../fs-frontend</span>\n<span class=\"grvsc-line\">        volumes:</span>\n<span class=\"grvsc-line\">            - /app/node_modules</span>\n<span class=\"grvsc-line\">            - ../fs-frontend:/app</span>\n<span class=\"grvsc-line\">        stdin_open: true</span>\n<span class=\"grvsc-line\">        ports:</span>\n<span class=\"grvsc-line\">            - &#39;3000:3000&#39;</span></code></pre>\n<p>Finally, the gateway. So, a gateway is created on the front using Nginx to make the development production-grade. If you go through the gateway code you will find that the services are accessed by their name <code>frontend</code> and <code>apiserver</code>.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">upstream frontend{</span>\n<span class=\"grvsc-line\">    server frontend:3000;</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">upstream apiserver{</span>\n<span class=\"grvsc-line\">    server apiserver:5000;</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>The Nginx container opens port 80 to an external port 5500. The Nginx container keeps configuration where the user can see just one port 5500 from out of the system, everything else is gray.</p>\n<p><img src=\"/97c99257db69f509d0840de4d8250c6f/UserToSystem.webp\" alt=\"User to System\"></p>\n<p>And this is, how it happens in the real world as well!</p>\n<p>Finally, we have docker-compose.yml. And following are simple commands which make life even simpler when we need to build and run &#x26; stop the entire ecosystem.</p>\n<p>To build</p>\n<p><code>docker-compose build</code></p>\n<p>To start</p>\n<p><code>docker-compose up</code></p>\n<p>To stop</p>\n<p><code>docker-compose down</code></p>\n<p>This scratches the surface of using docker-compose for a production-grade development environment.</p>\n<p><img src=\"/bd9b2747c7cf2952dd56ff0ad21d35fa/noanimalsharmed.webp\" alt=\"No Animals Harmed\"></p>\n<p>Thanks for reading the blog. For detailed information and execution example of this blog, please refer to the video below:</p>\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/G-s2GXGAjTk\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>\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":"September 11, 2020","updated_date":null,"description":null,"title":"Production Grade Development using Docker-Compose","tags":["Docker","Docker-compose"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/e913b33dfd194b83cdd0b013f0871d4d/58556/index.webp","srcSet":"/static/e913b33dfd194b83cdd0b013f0871d4d/61e93/index.webp 200w,\n/static/e913b33dfd194b83cdd0b013f0871d4d/1f5c5/index.webp 400w,\n/static/e913b33dfd194b83cdd0b013f0871d4d/58556/index.webp 800w,\n/static/e913b33dfd194b83cdd0b013f0871d4d/99238/index.webp 1200w,\n/static/e913b33dfd194b83cdd0b013f0871d4d/7c22d/index.webp 1600w,\n/static/e913b33dfd194b83cdd0b013f0871d4d/25f09/index.webp 1920w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Anurag Choudhary","github":"choudharyanurag","avatar":null}}}}]},"markdownRemark":{"excerpt":"Identity is evolving, and developers are at the forefront of this transformation. Every day brings a new learning—adapting to new standards…","fields":{"slug":"/identity/developer-first-identity-provider-loginradius/"},"html":"<p>Identity is evolving, and developers are at the forefront of this transformation. Every day brings a new learning—adapting to new standards and refining approaches to building secure, seamless experiences.</p>\n<p>We’re here to support developers on that journey. We know how important simplicity, efficiency, and well-structured documentation are when working with identity and access management solutions. That’s why we’ve redesigned the <a href=\"https://www.loginradius.com/\">LoginRadius website</a>—to be faster, more intuitive, and developer-first in every way.</p>\n<p>The goal? Having them spend less time searching and more time building.</p>\n<h2 id=\"whats-new-and-improved-on-the-loginradius-website\" style=\"position:relative;\"><a href=\"#whats-new-and-improved-on-the-loginradius-website\" aria-label=\"whats new and improved on the loginradius website 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>What’s New and Improved on the LoginRadius Website?</h2>\n<p>LoginRadius’ vision is to give developers a product that simplifies identity management so they can focus on building, deploying, and scaling their applications. To enhance this experience, we’ve spent the last few months redesigning our interface— making navigation more intuitive and reassuring that essential resources are easily accessible.</p>\n<p>Here’s a closer look at what’s new and why it’s important:</p>\n<h3 id=\"a-developer-friendly-dark-theme\" style=\"position:relative;\"><a href=\"#a-developer-friendly-dark-theme\" aria-label=\"a developer friendly dark theme 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>A Developer-Friendly Dark Theme</h3>\n<p><img src=\"/f46881583c7518a93bb24e94c32320de/a-developer-friendly-dark-theme.webp\" alt=\"This image shows how LoginRadius offers several authentication methods like traditional login, social login, passwordless login, passkeys and more in a dark mode.\">    </p>\n<p>Developers spend long hours working in dark-themed IDEs and terminals, so we’ve designed the LoginRadius experience to be developer-friendly and align with that preference.</p>\n<p>The new dark mode reduces eye strain, enhances readability, and provides a seamless transition between a coding environment and our platform. Our new design features a clean, modern aesthetic with a consistent color scheme and Barlow typography, ensuring better readability. High-quality graphics and icons are thoughtfully placed to enhance the content without adding visual clutter.</p>\n<p>So, whether you’re navigating our API docs or configuring authentication into your system, our improved interface will make those extended development hours more comfortable and efficient.</p>\n<h3 id=\"clear-categorization-for-loginradius-capabilities\" style=\"position:relative;\"><a href=\"#clear-categorization-for-loginradius-capabilities\" aria-label=\"clear categorization for loginradius capabilities 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>Clear Categorization for LoginRadius Capabilities</h3>\n<p><img src=\"/e5358b82be414940f3fb146013845933/capabilities.webp\" alt=\"This image shows a breakdown of all the LoginRadius CIAM capabilities, including authentication, security, UX, scalability and multi-brand management.\"></p>\n<p>We’ve restructured our website to provide a straightforward breakdown of our customer identity and access management platform capabilities, helping you quickly find what you need:</p>\n<ul>\n<li>Authentication: Easily understand <a href=\"https://www.loginradius.com/blog/identity/authentication-option-for-your-product/\">how to choose the right login method</a>, from traditional passwords and OTPs to social login, federated SSO, and passkeys with few lines of code.</li>\n<li>Security: Implement no-code security features like bot detection, IP throttling, breached password alerts, DDoS protection, and adaptive MFA to safeguard user accounts.</li>\n<li>User Experience: Leverage AI builder, hosted pages, and drag-and-drop workflows to create smooth, branded sign-up and login experiences.</li>\n<li>High Performance &#x26; Scalability: Confidently scale with sub-100ms API response times, 100% uptime, 240K+ RPS, and 28+ global data center regions.</li>\n<li>Multi-Brand Management: Efficiently manage multiple identity apps, choosing isolated or shared data stores based on your brand’s unique needs.</li>\n</ul>\n<p>This structured layout ensures you can quickly understand each capability and how it integrates into your identity ecosystem.</p>\n<h3 id=\"developer-first-navigation\" style=\"position:relative;\"><a href=\"#developer-first-navigation\" aria-label=\"developer first navigation 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>Developer-First Navigation</h3>\n<p><img src=\"/a8c155c2b6faf3d5f4b4de4e2b14d763/developers-menu.webp\" alt=\"This image shows the LoginRadius menu bar, highlighting the developer dropdown.\">   </p>\n<p>We’ve been analyzing developer workflows to identify how you access key resources. That’s why we redesigned our navigation with one goal in mind: to reduce clicks and make essential resources readily available.</p>\n<p>The new LoginRadius structure puts APIs, SDKs, and integration guides right at the menu bar under the Developers dropdown so you can get started faster. Our Products, Solutions, and Customer Services are also clearly categorized, helping development teams quickly find the right tools and make informed decisions.</p>\n<h3 id=\"quick-understanding-of-integration-benefits\" style=\"position:relative;\"><a href=\"#quick-understanding-of-integration-benefits\" aria-label=\"quick understanding of integration benefits 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>Quick Understanding of Integration Benefits</h3>\n<p><img src=\"/b2f9a964a2da0ea83e2f8596b833bba7/we-support-your-tech-stack.webp\" alt=\"This image shows a list of popular programming languages and frameworks offered by LoginRadius.\"></p>\n<p>Developers now have a clear view of the tech stack available with LoginRadius, designed to support diverse business needs.</p>\n<p>Our platform offers pre-built SDKs for Node.js, Python, Java, and more, making CIAM integration seamless across popular programming languages and frameworks.</p>\n<h2 id=\"over-to-you-now\" style=\"position:relative;\"><a href=\"#over-to-you-now\" aria-label=\"over to you now 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>Over to You Now!</h2>\n<p>Check out our <a href=\"https://www.loginradius.com/\">revamped LoginRadius website</a> and see how the improved experience makes it easier to build, scale, and secure your applications.</p>\n<p>Do not forget to explore the improved navigation and API documentation, and get started with our free trial today. We’re excited to see what you’ll build with LoginRadius!</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n</style>","frontmatter":{"date":"February 21, 2025","updated_date":null,"description":"LoginRadius’ vision is to give developers a product that simplifies identity management so they can focus on building, deploying, and scaling their applications. To enhance this experience, we’ve redesigned our website interface, making navigation more intuitive and reassuring that essential resources are easily accessible.","title":"Revamped & Ready: Introducing the New Developer-First LoginRadius Website","tags":["Developer tools","API","Identity Management","User Authentication"],"pinned":true,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7857142857142858,"src":"/static/80b4e4fbe176a10a327d273504607f32/58556/hero-section.webp","srcSet":"/static/80b4e4fbe176a10a327d273504607f32/61e93/hero-section.webp 200w,\n/static/80b4e4fbe176a10a327d273504607f32/1f5c5/hero-section.webp 400w,\n/static/80b4e4fbe176a10a327d273504607f32/58556/hero-section.webp 800w,\n/static/80b4e4fbe176a10a327d273504607f32/99238/hero-section.webp 1200w,\n/static/80b4e4fbe176a10a327d273504607f32/7c22d/hero-section.webp 1600w,\n/static/80b4e4fbe176a10a327d273504607f32/1258b/hero-section.webp 2732w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Rakesh Soni","github":"oyesoni","avatar":"rakesh-soni.webp"}}}},"pageContext":{"limit":6,"skip":732,"currentPage":123,"type":"///","numPages":164,"pinned":"ee8a4479-3471-53b1-bf62-d0d8dc3faaeb"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}