{"componentChunkName":"component---src-templates-blog-list-template-js","path":"/engineering/17","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"excerpt":"An infrastructure layer that allows you to manage communication between the microservices of your application is a service mesh. As more…","fields":{"slug":"/engineering/istio-installation-and-service-configuration/"},"html":"<p>An infrastructure layer that allows you to manage communication between the microservices of your application is a service mesh. As more developers work with microservices, by consolidating common management and administrative tasks in a distributed setup, service meshes have developed to make the job easier and more effective.</p>\n<p>To know more about Istio, you can read this article on <a href=\"https://www.loginradius.com/blog/engineering/istio-service-mesh\">Istio service mesh</a> to understand the basic terminology, In this tutorial, will explain how to install and configure Istio. Let's get started.</p>\n<h2 id=\"installing-istio\" style=\"position:relative;\"><a href=\"#installing-istio\" aria-label=\"installing istio 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>Installing Istio</h2>\n<p>Get the latest Istio release:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">curl -L https://istio.io/downloadIstio | sh -</span></code></pre>\n<p>Extract the archive and export the bin directory in the environment path.</p>\n<p>This will also install istioctl, a command-line tool to manage Istio service mesh.</p>\n<h3 id=\"configuration-profiles\" style=\"position:relative;\"><a href=\"#configuration-profiles\" aria-label=\"configuration profiles 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>Configuration Profiles</h3>\n<p>Istio provides various built-in configuration profiles, a set of pre-defined configs related to data and control plane. We can customize the configs according to our needs.</p>\n<p>For testing locally or trying it ou, you can use a demo profile. For dev and other environments, we will be using the default configuration profile.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">istioctl install --set profile=demo</span></code></pre>\n<h3 id=\"customizing-configs\" style=\"position:relative;\"><a href=\"#customizing-configs\" aria-label=\"customizing configs 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>Customizing configs</h3>\n<p>Run:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">istioctl profile dump default</span></code></pre>\n<p>to see the various configurations. We can change those flag using istioctl commands and --set flag.</p>\n<p>For development purpose, we can enabled/changes following flags:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">istioctl install --set addonComponents.kiali.enabled=true \\ </span>\n<span class=\"grvsc-line\">--set components.telemetry.enabled=true \\ </span>\n<span class=\"grvsc-line\">--set components.citadel.enabled=true \\ </span>\n<span class=\"grvsc-line\">--set values.global.proxy.privileged=true \\ </span>\n<span class=\"grvsc-line\">--set addonComponents.tracing.enabled=true \\ </span>\n<span class=\"grvsc-line\">--set values.pilot.traceSampling=100.0 \\ </span>\n<span class=\"grvsc-line\">--set values.global.proxy.tracer=datadog</span></code></pre>\n<p>The path value of <code>--set</code> flag is the YAML path, which you can see in the profile dump command.</p>\n<blockquote>\n<p>While changing any config, make sure to pass all the previous flags with the new ones. For example, if first time, you enabled istioctl install --set addonComponents.kiali.enabled=true and now let’s say, you want to enable citadel, then you have to pass both flags like this: istioctl install --set addonComponents.kiali.enabled=true --set components.telemetry.enabled=true.\nFailing to add any previously enabled variable will revert the config to its default values.\nOne way to store the dump in a file and do istioctl apply or use helm charts for Istio.</p>\n</blockquote>\n<h3 id=\"sidecar-injection\" style=\"position:relative;\"><a href=\"#sidecar-injection\" aria-label=\"sidecar injection 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>Sidecar injection</h3>\n<p>For Istio to work properly, a sidecar Envoy proxy needs to be enabled for the services. By default, the Istio control plane will not enable any sidecar to any services. To enable sidecar, we have to add labels at the namespace level.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">kubectl label namespace dsl-test istio-injection=enabled</span></code></pre>\n<p>You need to have this label even if you do not want to add a sidecar to all your services.</p>\n<p>You need to restart the pods.</p>\n<p>For services, which do not require sidecar, we need to add the following annotation in the deployment template:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"># Pod Annotations </span>\n<span class=\"grvsc-line\">podAnnotations: </span>\n<span class=\"grvsc-line\">\tsidecar.istio.io/inject: &quot;false&quot;</span></code></pre>\n<h2 id=\"configuring-services\" style=\"position:relative;\"><a href=\"#configuring-services\" aria-label=\"configuring services 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>Configuring Services</h2>\n<p>For demonstration, we will take two demo services demo-1 and demo-2, and configure both services with Istio, and will try to call demo-2 service from demo-1. Make sure there is an env variable in demo-1, which we will configure with demo-2 internal DNS url. The programming language for the two services does not matter here.</p>\n<p>A service configuration requires a VirtualService, DestinationRule, PeerAuthentication, and optionally a Gateway configuration.</p>\n<h3 id=\"gateway\" style=\"position:relative;\"><a href=\"#gateway\" aria-label=\"gateway 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>Gateway</h3>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">apiVersion: networking.istio.io/v1alpha3 </span>\n<span class=\"grvsc-line\">kind: Gateway </span>\n<span class=\"grvsc-line\">metadata: </span>\n<span class=\"grvsc-line\">\tname: demo-1</span>\n<span class=\"grvsc-line\">spec: </span>\n<span class=\"grvsc-line\">\tselector: </span>\n<span class=\"grvsc-line\">\t\tistio: ingressgateway </span>\n<span class=\"grvsc-line\">\tservers: </span>\n<span class=\"grvsc-line\">\t- port: </span>\n<span class=\"grvsc-line\">\t\tnumber: 80 </span>\n<span class=\"grvsc-line\">\t\tname: http </span>\n<span class=\"grvsc-line\">\t\tprotocol: HTTP </span>\n<span class=\"grvsc-line\">\t- hosts: </span>\n<span class=\"grvsc-line\">\t\t- &quot;demo-1.example.com&quot;</span></code></pre>\n<p>Gateway is used when we want to access the services from the public network.</p>\n<p>Here we are using the default gateway provided by the Istio. We can also create multiple gateways and assign the proper name here.</p>\n<p>The above gateway configuration enables both HTTP and HTTPS communication. In the case of HTTPS, we have to supply the secret containing the CA certs and key.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">spec:</span>\n<span class=\"grvsc-line\">\tservers: </span>\n<span class=\"grvsc-line\">\t- port: </span>\n<span class=\"grvsc-line\">\t\tnumber: 443</span>\n<span class=\"grvsc-line\">\t\tname: http </span>\n<span class=\"grvsc-line\">\t\tprotocol: HTTP</span>\n<span class=\"grvsc-line\">\t  tls: </span>\n<span class=\"grvsc-line\">\t\tmode: SIMPLE </span>\n<span class=\"grvsc-line\">\t\tcredentialName: div4-dev-certs</span>\n<span class=\"grvsc-line\">\t  hosts: </span>\n<span class=\"grvsc-line\">\t\t- &quot;demo-1.example.com&quot;</span></code></pre>\n<p>We can apply the same gateway for demo-2. We just have to update the hosts and metadata name. Since we will demo-2 internally from demo-1, there is no need for an external gateway for demo-2 here.</p>\n<h3 id=\"virtualservices\" style=\"position:relative;\"><a href=\"#virtualservices\" aria-label=\"virtualservices 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>VirtualServices</h3>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">---</span>\n<span class=\"grvsc-line\">apiVersion: networking.istio.io/v1alpha3</span>\n<span class=\"grvsc-line\">kind: VirtualService</span>\n<span class=\"grvsc-line\">metadata:</span>\n<span class=\"grvsc-line\">  name: demo-1</span>\n<span class=\"grvsc-line\">spec:</span>\n<span class=\"grvsc-line\">  hosts:</span>\n<span class=\"grvsc-line\">  - &quot;demo-1.test.svc.cluster.local&quot;</span>\n<span class=\"grvsc-line\">  - &quot;demo-1.example.com&quot;</span>\n<span class=\"grvsc-line\">  gateways:</span>\n<span class=\"grvsc-line\">    - demo-1</span>\n<span class=\"grvsc-line\">  http:</span>\n<span class=\"grvsc-line\">  - route:</span>\n<span class=\"grvsc-line\">    - destination:</span>\n<span class=\"grvsc-line\">        host: demo-1.test.svc.cluster.local</span>\n<span class=\"grvsc-line\">        port:</span>\n<span class=\"grvsc-line\">          number: 80</span></code></pre>\n<p><strong>spec.hosts:</strong> Specifies the URL which the caller of the service will use. Here, dsl-es.pbdp.svc.cluster.local will be used by the services calling internally. The endpoint demo-1.example.com will be exposed publicly, and it should match the <strong>spec.servers.hosts</strong> value in Gateway config.</p>\n<p><strong>spec.gateways:</strong> In order for the gateways configured above to reach the service, we need to define the gateway metadata name here.</p>\n<p><strong>http.route.destination.host:</strong> This value should be the actual service FQDN.</p>\n<h3 id=\"destinationrule\" style=\"position:relative;\"><a href=\"#destinationrule\" aria-label=\"destinationrule 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>DestinationRule</h3>\n<p>After the virtualservice decides the destination hosts, DestinationRule defines the configuration on the actual service. DestinationRule is optional and is needed only in case we want to override the default behavior.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">---</span>\n<span class=\"grvsc-line\">apiVersion: networking.istio.io/v1alpha3</span>\n<span class=\"grvsc-line\">kind: DestinationRule</span>\n<span class=\"grvsc-line\">metadata:</span>\n<span class=\"grvsc-line\">  name: demo-1</span>\n<span class=\"grvsc-line\">spec:</span>\n<span class=\"grvsc-line\">  host: &quot;demo-1.test.svc.cluster.local&quot;</span>\n<span class=\"grvsc-line\">  trafficPolicy:</span>\n<span class=\"grvsc-line\">    loadBalancer:</span>\n<span class=\"grvsc-line\">      simple: ROUND_ROBIN</span>\n<span class=\"grvsc-line\">    tls:</span>\n<span class=\"grvsc-line\">      mode: ISTIO_MUTUAL</span></code></pre>\n<p><strong>spec.host:</strong> specifies service FQDN</p>\n<p><strong>spec.trafficPolicy:</strong> Specifies policy on the traffic. Here we can specify load balancing algorithms, TLS mode, circuit breaking policies.</p>\n<p><strong>spec.trafficPolicy.tls.mode:</strong> ISTIO_MUTUAL mode is a TLS mode where we will use the certificates generated by the Istio.</p>\n<p>A configuration like circuit breakers, outlier detection comes under the Destination Rule.</p>\n<h3 id=\"peerauthentication\" style=\"position:relative;\"><a href=\"#peerauthentication\" aria-label=\"peerauthentication 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>PeerAuthentication</h3>\n<p>This configuration defines how the other services will connect.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">---</span>\n<span class=\"grvsc-line\">apiVersion: security.istio.io/v1beta1</span>\n<span class=\"grvsc-line\">kind: PeerAuthentication</span>\n<span class=\"grvsc-line\">metadata:</span>\n<span class=\"grvsc-line\">  name: demo-1</span>\n<span class=\"grvsc-line\">spec:</span>\n<span class=\"grvsc-line\">  selector:</span>\n<span class=\"grvsc-line\">    matchLabels:</span>\n<span class=\"grvsc-line\">      app: demo-1</span>\n<span class=\"grvsc-line\">  mtls:</span>\n<span class=\"grvsc-line\">    mode: STRICT</span></code></pre>\n<p><strong>spec.selector.matchLabels.app:</strong> Specify the deployment label on which this configuration will be applied.</p>\n<p><strong>spec.mtls.mode:</strong> TLS mode. STRICT being the connection will always be mutual tls.</p>\n<p>PeerAuthentication can be applied to a whole namespace. This is useful when all the services in the namespace are part of the mesh.</p>\n<blockquote>\n<p>Apply the same configuration for virutalservice, destination, and peerauthentication by replacing demo-1 with demo-2 assuming both services are in the same namespace.</p>\n</blockquote>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">kubectl apply -f &lt;file&gt;.yaml -n test</span></code></pre>\n<p>Access the objects:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">kubectl get virtualservices -n pbdp</span>\n<span class=\"grvsc-line\">kubectl get gateways -n pbdp</span>\n<span class=\"grvsc-line\">kubectl get destinationrule -n pbdp</span>\n<span class=\"grvsc-line\">kubectl get peerauthentication -n pbdp</span></code></pre>\n<p>Now update the env for demo-2 with <code>demo-2.test.svc.cluster.local</code> in demo-1 service.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n</style>","frontmatter":{"date":"January 22, 2021","updated_date":null,"description":"This article will provide a step by step process on how to install and configure services using Istio.","title":"How to Install and Configure Istio","tags":["Istio","Service Mesh"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/d8ff8c7b29395837a840c4013f351290/58556/Istio.webp","srcSet":"/static/d8ff8c7b29395837a840c4013f351290/61e93/Istio.webp 200w,\n/static/d8ff8c7b29395837a840c4013f351290/1f5c5/Istio.webp 400w,\n/static/d8ff8c7b29395837a840c4013f351290/58556/Istio.webp 800w,\n/static/d8ff8c7b29395837a840c4013f351290/210c1/Istio.webp 900w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Piyush Kumar","github":"kpiyush17","avatar":null}}}},{"node":{"excerpt":"In this article, we will address how to perform basic query operations in MongoDB. We are producing data at an unparalleled pace now…","fields":{"slug":"/engineering/basic-query-operations-in-mongodb/"},"html":"<p>In this article, we will address how to perform basic query operations in MongoDB. We are producing data at an unparalleled pace now following the global spread of the internet. Since it will require us to collect/request the required data from the database to conduct some kind of analysis, it is of utmost importance that we choose the right tool to query the data.</p>\n<p>This is where MongoDB comes in, specifically. MongoDB is an unstructured database which, in the form of documents, stores data. In addition, MongoDB is very effective in <a href=\"https://www.loginradius.com/blog/engineering/live-data-migration-mongodb/\">handling enormous amounts of data</a> and is the most commonly used NoSQL database as it provides rich query language and versatile and easy data access.</p>\n<h2 id=\"create-a-sample-database\" style=\"position:relative;\"><a href=\"#create-a-sample-database\" aria-label=\"create a sample database 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 a Sample Database</h2>\n<p>Before the start, we will create a sample DB with some sample data to perform all operations.</p>\n<p>We will create a database with name <em>myDB</em> and will create a collection with name <em>orders</em>. For this, the statement would be as follows.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt; use myDB</span>\n<span class=\"grvsc-line\">&gt; db.createCollection(&quot;orders&quot;)</span>\n<span class=\"grvsc-line\">&gt;</span></code></pre>\n<p><em>MongoDB doesn't use the rows and columns. It stores the data in a document format. A collection is a group of documents.</em></p>\n<p>You can check all collections in a database by using the following statement.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt; use myDB</span>\n<span class=\"grvsc-line\">&gt;show collections</span>\n<span class=\"grvsc-line\">orders</span>\n<span class=\"grvsc-line\">system.indexes</span>\n<span class=\"grvsc-line\">&gt;</span></code></pre>\n<p>Let's insert some documents by using the following statement.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt; db.orders.insert([</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;abc&quot;,</span>\n<span class=\"grvsc-line\">\t\tAddress:{&quot;City&quot;:&quot;Jaipur&quot;,&quot;Country&quot;:&quot;India&quot;},</span>\n<span class=\"grvsc-line\">\t\tPaymentMode&quot;:&quot;Card&quot;,</span>\n<span class=\"grvsc-line\">\t\tEmail:&quot;abc@mail.in&quot;,</span>\n<span class=\"grvsc-line\">\t\tOrderTotal: 1000.00,</span>\n<span class=\"grvsc-line\">\t\tOrderItems:[</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;notebook&quot;,&quot;Price&quot;:&quot;150.00&quot;,&quot;Qty&quot;:10},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;paper&quot;,&quot;Price&quot;:&quot;10.00&quot;,&quot;Qty&quot;:5},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;journal&quot;,&quot;Price&quot;:&quot;200.00&quot;,&quot;Qty&quot;:2},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;postcard&quot;,&quot;Price&quot;:&quot;10.00&quot;,&quot;Qty&quot;:500}</span>\n<span class=\"grvsc-line\">\t\t]\t\t</span>\n<span class=\"grvsc-line\">\t},</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;xyz&quot;,</span>\n<span class=\"grvsc-line\">\t\tAddress:{&quot;City&quot;:&quot;Delhi&quot;,&quot;Country&quot;:&quot;India&quot;},</span>\n<span class=\"grvsc-line\">\t\tPaymentMode&quot;:&quot;Cash&quot;,</span>\n<span class=\"grvsc-line\">\t\tOrderTotal: 800.00,</span>\n<span class=\"grvsc-line\">\t\tOrderItems:[</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;notebook&quot;,&quot;Price&quot;:&quot;150.00&quot;,&quot;Qty&quot;:5},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;paper&quot;,&quot;Price&quot;:&quot;10.00&quot;,&quot;Qty&quot;:5},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;postcard&quot;,&quot;Price&quot;:&quot;10.00&quot;,&quot;Qty&quot;:500}</span>\n<span class=\"grvsc-line\">\t\t]\t\t</span>\n<span class=\"grvsc-line\">\t},</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;ron&quot;,</span>\n<span class=\"grvsc-line\">\t\tAddress:{&quot;City&quot;:&quot;New York&quot;,&quot;Country&quot;:&quot;USA&quot;},</span>\n<span class=\"grvsc-line\">\t\tPaymentMode&quot;:&quot;Card&quot;,</span>\n<span class=\"grvsc-line\">\t\tEmail:&quot;ron@mail.com&quot;,</span>\n<span class=\"grvsc-line\">\t\tOrderTotal: 800.00,</span>\n<span class=\"grvsc-line\">\t\tOrderItems:[</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;notebook&quot;,&quot;Price&quot;:&quot;150.00&quot;,&quot;Qty&quot;:5},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;postcard&quot;,&quot;Price&quot;:&quot;10.00&quot;,&quot;Qty&quot;:00}</span>\n<span class=\"grvsc-line\">\t\t]\t\t</span>\n<span class=\"grvsc-line\">\t}</span>\n<span class=\"grvsc-line\">])</span></code></pre>\n<p><em>A document is the equivalent of an RDBMS row. It doesn't need to have the same schema in each document. It means a document might not have any field that doesn't have any value.</em></p>\n<h2 id=\"query-documents\" style=\"position:relative;\"><a href=\"#query-documents\" aria-label=\"query 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>Query Documents</h2>\n<h3 id=\"find-method\" style=\"position:relative;\"><a href=\"#find-method\" aria-label=\"find method 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() method</h3>\n<p>You need to use the find() method to query documents from MongoDB collections. The following statement will retrieve all documents from the collection.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt; db.orders.find()</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607534c&quot;)</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;abc&quot;,</span>\n<span class=\"grvsc-line\">\t\tAddress:{&quot;City&quot;:&quot;Jaipur&quot;,&quot;Country&quot;:&quot;India&quot;},</span>\n<span class=\"grvsc-line\">\t\tPaymentMode&quot;:&quot;Card&quot;,</span>\n<span class=\"grvsc-line\">\t\tEmail:&quot;abc@mail.com&quot;,</span>\n<span class=\"grvsc-line\">\t\tOrderTotal: 1000.00,</span>\n<span class=\"grvsc-line\">\t\tOrderItems:[</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;notebook&quot;,&quot;Price&quot;:&quot;150.00&quot;,&quot;Qty&quot;:10},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;paper&quot;,&quot;Price&quot;:&quot;10.00&quot;,&quot;Qty&quot;:5},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;journal&quot;,&quot;Price&quot;:&quot;200.00&quot;,&quot;Qty&quot;:2},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;postcard&quot;,&quot;Price&quot;:&quot;10.00&quot;,&quot;Qty&quot;:500}</span>\n<span class=\"grvsc-line\">\t\t]\t\t</span>\n<span class=\"grvsc-line\">\t},</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607544c&quot;),</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;xyz&quot;,</span>\n<span class=\"grvsc-line\">\t\tAddress:{&quot;City&quot;:&quot;Delhi&quot;,&quot;Country&quot;:&quot;India&quot;},</span>\n<span class=\"grvsc-line\">\t\tPaymentMode&quot;:&quot;Cash&quot;,</span>\n<span class=\"grvsc-line\">\t\tOrderTotal: 800.00,</span>\n<span class=\"grvsc-line\">\t\tOrderItems:[</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;notebook&quot;,&quot;Price&quot;:&quot;150.00&quot;,&quot;Qty&quot;:5},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;paper&quot;,&quot;Price&quot;:&quot;10.00&quot;,&quot;Qty&quot;:5},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;postcard&quot;,&quot;Price&quot;:&quot;10.00&quot;,&quot;Qty&quot;:500}</span>\n<span class=\"grvsc-line\">\t\t]</span>\n<span class=\"grvsc-line\">\t},</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607644c&quot;),</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;ron&quot;,</span>\n<span class=\"grvsc-line\">\t\tAddress:{&quot;City&quot;:&quot;New York&quot;,&quot;Country&quot;:&quot;USA&quot;},</span>\n<span class=\"grvsc-line\">\t\tPaymentMode&quot;:&quot;Card&quot;,</span>\n<span class=\"grvsc-line\">\t\tEmail:&quot;ron@mail.com&quot;,</span>\n<span class=\"grvsc-line\">\t\tOrderTotal: 600.00,</span>\n<span class=\"grvsc-line\">\t\tOrderItems:[</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;notebook&quot;,&quot;Price&quot;:&quot;150.00&quot;,&quot;Qty&quot;:5},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;postcard&quot;,&quot;Price&quot;:&quot;10.00&quot;,&quot;Qty&quot;:00}</span>\n<span class=\"grvsc-line\">\t\t]</span>\n<span class=\"grvsc-line\">\t}</span>\n<span class=\"grvsc-line\">&gt;</span></code></pre>\n<h3 id=\"projection\" style=\"position:relative;\"><a href=\"#projection\" aria-label=\"projection 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>Projection</h3>\n<p>If you want to fetch only selected fields then you can use the projection. Following statement will fetch only <em>Customer</em> and <em>Email</em> field.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt; db.orders.find( { }, { Customer: 1, Email: 1 })</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607534c&quot;)</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;abc&quot;,</span>\n<span class=\"grvsc-line\">\t\tEmail:&quot;abc@mail.com&quot;</span>\n<span class=\"grvsc-line\">\t},</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607544c&quot;),</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;xyz&quot;\t\t</span>\n<span class=\"grvsc-line\">\t},</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607644c&quot;),</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;ron&quot;,</span>\n<span class=\"grvsc-line\">\t\tEmail:&quot;ron@mail.com&quot;\t\t</span>\n<span class=\"grvsc-line\">\t}</span>\n<span class=\"grvsc-line\">&gt;</span></code></pre>\n<h3 id=\"filter-the-documents-by-specifying-a-condition\" style=\"position:relative;\"><a href=\"#filter-the-documents-by-specifying-a-condition\" aria-label=\"filter the documents by specifying a condition 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>Filter the Documents by Specifying a Condition</h3>\n<p>Now we will learn how we can fetch the documents that match a specified condition. MongoDB provides many comparison operators for this.</p>\n<h4 id=\"1-eq-operator\" style=\"position:relative;\"><a href=\"#1-eq-operator\" aria-label=\"1 eq operator 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>1. $eq Operator</h4>\n<p>The $eq operator checks the equality of the field value with the specified value. To fetch the order where <em>PaymentMode</em> is 'Card' you can use the following statement</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.orders.find( { PaymentMode: { $eq: &quot;Card&quot; } } )</span></code></pre>\n<p><em>This query can be written also like below</em></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.orders.find( { PaymentMode: &quot;Card&quot; } )</span></code></pre>\n<p><em>A similar SQL statement would be as follows</em></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">SELECT * FROM orders WHERE PaymentMode=&quot;Card&quot;</span></code></pre>\n<p><strong>Example</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.orders.find( { PaymentMode: &quot;Card&quot; }, { Customer: 1, PaymentMode: 1 } )</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607534c&quot;)</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;abc&quot;,</span>\n<span class=\"grvsc-line\">\t\tPaymentMode&quot;:&quot;Card&quot;\t\t\t\t</span>\n<span class=\"grvsc-line\">\t},</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607644c&quot;),</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;ron&quot;,</span>\n<span class=\"grvsc-line\">\t\tPaymentMode&quot;:&quot;Card&quot;</span>\n<span class=\"grvsc-line\">\t}</span>\n<span class=\"grvsc-line\">&gt;</span></code></pre>\n<p><strong>$eq Operator with embedded document</strong></p>\n<p>You may have noticed that we inserted an embedded document <em>Address</em> in the <em>Orders</em> collection. If you want to fetch the order where <em>Country</em> is 'India' you can use a dot notation like the following statement.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.Orders.find( { &quot;Address.Country&quot;: { $eq: &quot;India&quot; } } )</span></code></pre>\n<p><em>This query can be written also like below</em></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.Orders.find( { &quot;Address.Country&quot;:&quot;India&quot; } )</span></code></pre>\n<p><strong>Example</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.Orders.find( { &quot;Address.Country&quot;: { $eq: &quot;India&quot; } } , { Customer: 1, Address: 1 })</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607534c&quot;)</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;abc&quot;,</span>\n<span class=\"grvsc-line\">\t\tAddress:{&quot;City&quot;:&quot;Jaipur&quot;,&quot;Country&quot;:&quot;India&quot;}</span>\n<span class=\"grvsc-line\">\t},</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607544c&quot;),</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;xyz&quot;,</span>\n<span class=\"grvsc-line\">\t\tAddress:{&quot;City&quot;:&quot;Delhi&quot;,&quot;Country&quot;:&quot;India&quot;}</span>\n<span class=\"grvsc-line\">\t}</span>\n<span class=\"grvsc-line\">&gt;</span></code></pre>\n<p><strong>$eq Operator with array</strong></p>\n<p>$eq operator will retrieve all the documents if the specified condition is true for any item in an array. We have an <em>OrderItems</em> array in the document. If you want to filter the documents where 'paper' were also ordered then the statement would be as follows.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.Orders.find( { &quot;OrderItems.ItemName&quot;: { $eq: &quot;paper&quot; } } )</span></code></pre>\n<p><em>This query can be written also like below</em></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"13\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.Orders.find( { &quot;OrderItems.ItemName&quot;: &quot;paper&quot;  } )</span></code></pre>\n<p><strong>Example</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"14\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.Orders.find( { &quot;OrderItems.ItemName&quot;: { $eq: &quot;paper&quot; } } , { Customer: 1, OrderItems: 1 })</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607534c&quot;)</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;abc&quot;,</span>\n<span class=\"grvsc-line\">\t\tOrderItems:[</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;notebook&quot;,&quot;Price&quot;:&quot;150.00&quot;,&quot;Qty&quot;:10},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;paper&quot;,&quot;Price&quot;:&quot;10.00&quot;,&quot;Qty&quot;:5},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;journal&quot;,&quot;Price&quot;:&quot;200.00&quot;,&quot;Qty&quot;:2},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;postcard&quot;,&quot;Price&quot;:&quot;10.00&quot;,&quot;Qty&quot;:500}</span>\n<span class=\"grvsc-line\">\t\t]\t\t</span>\n<span class=\"grvsc-line\">\t},</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607544c&quot;),</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;xyz&quot;,</span>\n<span class=\"grvsc-line\">\t\tOrderItems:[</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;notebook&quot;,&quot;Price&quot;:&quot;150.00&quot;,&quot;Qty&quot;:5},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;paper&quot;,&quot;Price&quot;:&quot;10.00&quot;,&quot;Qty&quot;:5},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;postcard&quot;,&quot;Price&quot;:&quot;10.00&quot;,&quot;Qty&quot;:500}</span>\n<span class=\"grvsc-line\">\t\t]</span>\n<span class=\"grvsc-line\">\t}</span>\n<span class=\"grvsc-line\">&gt;</span></code></pre>\n<h4 id=\"2-gt-operator\" style=\"position:relative;\"><a href=\"#2-gt-operator\" aria-label=\"2 gt operator 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>2. $gt Operator</h4>\n<p>You can use the $gt operator to retrieve the documents where a field’s value is greater than the specified value. The following statement will fetch the documents where <em>OrderTotal</em> is greater than 800.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"15\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.orders.find( { OrderTotal: { $gt: 800.00 } } )</span></code></pre>\n<p><em>A similar SQL statement would be as follows</em></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"16\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">SELECT * FROM orders WHERE OrderTotal&gt;800.00</span></code></pre>\n<p><strong>Example</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"17\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.Orders.find( { &quot;OrderTotal&quot;: { $gt: 800.00 } } , { Customer: 1, OrderTotal: 1 })</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607534c&quot;)</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;abc&quot;,</span>\n<span class=\"grvsc-line\">\t\tOrderTotal: 1000.00</span>\n<span class=\"grvsc-line\">\t}</span>\n<span class=\"grvsc-line\">&gt;</span></code></pre>\n<h4 id=\"3-gte-operator\" style=\"position:relative;\"><a href=\"#3-gte-operator\" aria-label=\"3 gte operator 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>3. $gte Operator</h4>\n<p>You can use the $gte operator to retrieve the documents where a field’s value is greater than or equal to the specified value. The following statement will fetch the documents where <em>OrderTotal</em> is greater than or equal to 800.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"18\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.orders.find( { OrderTotal: { $gte: 800.00 } } )</span></code></pre>\n<p><em>A similar SQL statement would be as follows</em></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"19\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">SELECT * FROM orders WHERE OrderTotal&gt;=800.00</span></code></pre>\n<p><strong>Example</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"20\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.Orders.find( { &quot;OrderTotal&quot;: { $gte: 800.00 } } , { Customer: 1, OrderTotal: 1 })</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607534c&quot;)</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;abc&quot;,</span>\n<span class=\"grvsc-line\">\t\tOrderTotal: 1000.00</span>\n<span class=\"grvsc-line\">\t},</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607544c&quot;),</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;xyz&quot;,</span>\n<span class=\"grvsc-line\">\t\tOrderTotal: 800.00</span>\n<span class=\"grvsc-line\">\t}</span>\n<span class=\"grvsc-line\">&gt;</span></code></pre>\n<h4 id=\"4-lt-operator\" style=\"position:relative;\"><a href=\"#4-lt-operator\" aria-label=\"4 lt operator 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>4. $lt Operator</h4>\n<p>You can use the $lt operator to retrieve the documents where a field’s value is less than the specified value. The following statement will fetch the documents where <em>OrderTotal</em> is less than 800.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"21\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.orders.find( { OrderTotal: { $lt: 800.00 } } )</span></code></pre>\n<p><em>A similar SQL statement would be as follows</em></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"22\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">SELECT * FROM orders WHERE OrderTotal&lt;800.00</span></code></pre>\n<p><strong>Example</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"23\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.Orders.find( { &quot;OrderTotal&quot;: { $lt: 800.00 } } , { Customer: 1, OrderTotal: 1 })</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607644c&quot;),</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;ron&quot;,</span>\n<span class=\"grvsc-line\">\t\tOrderTotal: 600.00</span>\n<span class=\"grvsc-line\">\t}</span>\n<span class=\"grvsc-line\">&gt;</span></code></pre>\n<h4 id=\"4-lte-operator\" style=\"position:relative;\"><a href=\"#4-lte-operator\" aria-label=\"4 lte operator 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>4. $lte Operator</h4>\n<p>You can use the $lte operator to retrieve the documents where a field’s value is less than or equal to the specified value. Following statement will fetch the documents where <em>OrderTotal</em> is less than or equal to 800.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"24\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.orders.find( { OrderTotal: { $lte: 800.00 } } )</span></code></pre>\n<p><em>A similar SQL statement would be as follows</em></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"25\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">SELECT * FROM orders WHERE OrderTotal&lt;=800.00</span></code></pre>\n<p><strong>Example</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"26\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.Orders.find( { &quot;OrderTotal&quot;: { $lte: 800.00 } } , { Customer: 1, OrderTotal: 1 })</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607544c&quot;),</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;xyz&quot;,</span>\n<span class=\"grvsc-line\">\t\tOrderTotal: 800.00</span>\n<span class=\"grvsc-line\">\t},</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607644c&quot;),</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;ron&quot;,</span>\n<span class=\"grvsc-line\">\t\tOrderTotal: 600.00</span>\n<span class=\"grvsc-line\">\t}</span>\n<span class=\"grvsc-line\">&gt;</span></code></pre>\n<h4 id=\"5-ne-operator\" style=\"position:relative;\"><a href=\"#5-ne-operator\" aria-label=\"5 ne operator 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>5. $ne Operator</h4>\n<p>You can use the $ne operator to retrieve the documents where a field’s value is not equal to the specified value.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"27\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.orders.find( { PaymentMode: { $ne: &quot;Card&quot; } } )</span></code></pre>\n<p><em>A similar SQL statement would be as follows</em></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"28\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">SELECT * FROM orders WHERE PaymentMode != &quot;Card&quot;</span></code></pre>\n<p><strong>Example</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"29\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.Orders.find( { &quot;PaymentMode&quot;: { $ne: &quot;Card&quot; } } , { Customer: 1, PaymentMode: 1 })</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607544c&quot;),</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;xyz&quot;,</span>\n<span class=\"grvsc-line\">\t\tPaymentMode&quot;:&quot;Cash&quot;</span>\n<span class=\"grvsc-line\">\t}</span>\n<span class=\"grvsc-line\">&gt;</span></code></pre>\n<h4 id=\"6-in-operator\" style=\"position:relative;\"><a href=\"#6-in-operator\" aria-label=\"6 in operator 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>6. $in Operator</h4>\n<p>You can use the $in operator to retrieve the documents where a field’s value is equal to any value in the specified array.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"30\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.orders.find( { OrderItems.ItemName: { $in: [&quot;journal&quot;,&quot;paper&quot;] } } )</span></code></pre>\n<p><strong>Example</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"31\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.Orders.find( { OrderItems.ItemName: { $in: [&quot;journal&quot;,&quot;paper&quot;] } } , { Customer: 1, OrderItems: 1 })</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607534c&quot;)</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;abc&quot;,</span>\n<span class=\"grvsc-line\">\t\tOrderItems:[</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;notebook&quot;,&quot;Price&quot;:&quot;150.00&quot;,&quot;Qty&quot;:10},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;paper&quot;,&quot;Price&quot;:&quot;10.00&quot;,&quot;Qty&quot;:5},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;journal&quot;,&quot;Price&quot;:&quot;200.00&quot;,&quot;Qty&quot;:2},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;postcard&quot;,&quot;Price&quot;:&quot;10.00&quot;,&quot;Qty&quot;:500}</span>\n<span class=\"grvsc-line\">\t\t]\t\t</span>\n<span class=\"grvsc-line\">\t},</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607544c&quot;),</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;xyz&quot;,</span>\n<span class=\"grvsc-line\">\t\tOrderItems:[</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;notebook&quot;,&quot;Price&quot;:&quot;150.00&quot;,&quot;Qty&quot;:5},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;paper&quot;,&quot;Price&quot;:&quot;10.00&quot;,&quot;Qty&quot;:5},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;postcard&quot;,&quot;Price&quot;:&quot;10.00&quot;,&quot;Qty&quot;:500}</span>\n<span class=\"grvsc-line\">\t\t]</span>\n<span class=\"grvsc-line\">\t}</span>\n<span class=\"grvsc-line\">&gt;</span></code></pre>\n<h4 id=\"7-nin-operator\" style=\"position:relative;\"><a href=\"#7-nin-operator\" aria-label=\"7 nin operator 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>7. $nin Operator</h4>\n<p>You can use the $nin operator to retrieve the documents where a field’s value is not equal to any value in the specified array. It will also select the documents where the field does not exist.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"32\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.orders.find( { OrderItems.ItemName: { $nin: [&quot;journal&quot;,&quot;paper&quot;] } } )</span></code></pre>\n<p><strong>Example</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"33\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.Orders.find( { OrderItems.ItemName: { $nin: [&quot;journal&quot;,&quot;paper&quot;] } } , { Customer: 1, OrderItems: 1 })</span>\n<span class=\"grvsc-line\">\t{</span>\n<span class=\"grvsc-line\">\t\t&quot;_id&quot; : ObjectId(&quot;5dd4e2cc0821d3b44607644c&quot;),</span>\n<span class=\"grvsc-line\">\t\tCustomer: &quot;ron&quot;,</span>\n<span class=\"grvsc-line\">\t\tOrderItems:[</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;notebook&quot;,&quot;Price&quot;:&quot;150.00&quot;,&quot;Qty&quot;:5},</span>\n<span class=\"grvsc-line\">\t\t\t{&quot;ItemName&quot;:&quot;postcard&quot;,&quot;Price&quot;:&quot;10.00&quot;,&quot;Qty&quot;:00}</span>\n<span class=\"grvsc-line\">\t\t]</span>\n<span class=\"grvsc-line\">\t}</span>\n<span class=\"grvsc-line\">&gt;</span></code></pre>\n<h3 id=\"indexing\" style=\"position:relative;\"><a href=\"#indexing\" aria-label=\"indexing 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>Indexing</h3>\n<p>We know that <a href=\"https://www.loginradius.com/blog/engineering/index-in-mongodb/\">indexing is very important</a> if we are performing the queries on a large database. Without indexing execution of a query can be expensive. We can add a simple ascending index on a single field by using the following statement.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"34\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&gt;db.Orders.createIndex({&quot;Customer&quot;:1})</span></code></pre>\n<p>MongoDB creates a unique index on ‘_id’ field by default. A unique index will prevent insertion of two documents with the same value for that field. If you want to create a unique index then the statement would be as follows.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"35\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">db.Orders.createIndex( { &quot;OrderId&quot;: 1 }, { unique: true } )</span></code></pre>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>I hope you learned something new today, If you want to learn few more stuff on MongoDB, here is an interesting article on <a href=\"https://www.loginradius.com/blog/engineering/self-hosted-mongo/\">Self-Hosted MongoDB</a> I also invite you to try stuff on your own and share your experience in the comment section. Furthermore, if you face any problems with any of the above definitions, please feel free to ask me in the comments below.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n</style>","frontmatter":{"date":"January 20, 2021","updated_date":null,"description":null,"title":"How to Perform Basic Query Operations in MongoDB","tags":["MongoDB"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/f4c86ce656fbbcd1cebd60b0c6606d53/58556/coverImage.webp","srcSet":"/static/f4c86ce656fbbcd1cebd60b0c6606d53/61e93/coverImage.webp 200w,\n/static/f4c86ce656fbbcd1cebd60b0c6606d53/1f5c5/coverImage.webp 400w,\n/static/f4c86ce656fbbcd1cebd60b0c6606d53/58556/coverImage.webp 800w,\n/static/f4c86ce656fbbcd1cebd60b0c6606d53/99238/coverImage.webp 1200w,\n/static/f4c86ce656fbbcd1cebd60b0c6606d53/7c22d/coverImage.webp 1600w,\n/static/f4c86ce656fbbcd1cebd60b0c6606d53/25f09/coverImage.webp 1920w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Anil Gupta","github":"anilswm","avatar":null}}}},{"node":{"excerpt":"As we all know, JSON Web Tokens are a way of sending information between parties in a way where the sender's authenticity can be verified…","fields":{"slug":"/engineering/invalidating-jwt/"},"html":"<p>As we all know, JSON Web Tokens are a way of sending information between parties in a way where the sender's authenticity can be verified. It is essentially a JSON object with a signature. Using this signature, services that issue these tokens can verify that they are the ones who issued this token and thus can trust the claims which are contained within. </p>\n<p>The trustworthiness of these tokens make them popular for use in authorization and authentication scenarios:</p>\n<ul>\n<li>In authorization workflows, JSON Web Tokens are distributed to users with claims containing the resources and services that are allowed for that user. The issuing service can perform its database lookups to determine the user's authorization levels when the token is being generated and issued. Since the signature can be used to verify that the token is authentic and issued by a trusted source, for subsequent transactions using the token, the service can safely take the token at its word. This saves the service from needing to check its database for the user's relevant permissions every time a transaction is performed.</li>\n<li>In authentication workflows such as OAuth2, JSON Web Tokens are often used as part of a larger workflow, where they are useful to securely transmit information between parties. Since the resource server and authenticating server are different, these tokens ensure that the information being received by these parties is valid and authentic.</li>\n</ul>\n<p>For this post, we'll be focusing on the former use case. So having a token with trustworthy claims is great; we can take the token at its word, and trust all of the information that it has contained within as gospel. Our server is unburdened from having to potentially make database calls to verify the user's role, their permissions, their existence, or even if they're logged in. Once the server has generated the token, as far as it is concerned, no state has to be maintained regarding the validity of the token. It will expire once its expiration time included in its claim has passed.</p>\n<p>But before we go ahead and use this for all of our authorization needs, we have to remember that while JSON Web Tokens themselves are stateless, to have a robust, feasible, and controllable authorization workflow, we'll have to maintain some state one way or another.</p>\n<p>You can think of an authorization token as an elementary school hall pass. The teacher (resource server) knows that it is a legitimate hall pass because it is green, 6 cm x 12 cm and has a signature from another member of the faculty. Now imagine that you've issued a hall pass, but now you need to take it back (you've changed your mind, or the kid did something bad). Your options are:</p>\n<ul>\n<li>Go to the kid and take the pass back (browser deletes the token from its storage). However, the kid made a photocopy, and can still roam the halls with relative ease.</li>\n<li>Wait till the hall pass expires (wait till the token expiry claim passes). Green hall passes are only valid on Mondays. He can still roam the halls freely for the remainder of Monday (the horror).</li>\n<li>Change the entire format of the hall pass (change the secret used to sign the token). The crisis has been averted, but now you'll need to handicraft another 5 whole hall passes for the class.</li>\n</ul>\n<p>Other than the 3rd option which may or may not be feasible depending on your use case (most likely not), we can see that it is not possible to reliably remove or revoke a token without maintaining state. The solutions that I've looked upon Stack Overflow for invalidating these tokens boil down to relying on some form of state, one way or another. Don't get me wrong however, this is not a bad thing in my opinion. Using JSON Web Tokens can and do allow us to minimize the state that we do have to maintain, with minimal added complexity.</p>\n<p>So let's look at some ways that we can couple state and JSON Web Tokens that allow us to invalidate these tokens effectively.</p>\n<h3 id=\"token-whitelist\" style=\"position:relative;\"><a href=\"#token-whitelist\" aria-label=\"token whitelist 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>Token Whitelist</h3>\n<p>We can maintain a database table containing all of the tokens issued by our server that we would like to accept as valid. This would be a 1:1 session store, with every transaction occurring requiring this table to be checked to prevent an invalidated token from being accepted. While we would not be able to reduce the amount of state being maintained on our server, JSON Web Tokens still provide us with the utility of its trusted claims (and the performance benefits of not needing to check those).</p>\n<h3 id=\"token-blacklist\" style=\"position:relative;\"><a href=\"#token-blacklist\" aria-label=\"token blacklist 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>Token Blacklist</h3>\n<p>We can maintain a database table containing all of the tokens issued by our server that we do NOT want to accept as valid. Every transaction that occurs will require this table to be checked, to prevent an invalidated token from being accepted. Each record would only have to be maintained until the token itself expires. I can't think of any use case where a table of invalidated tokens would regularly be larger than a table of active tokens, so I'd imagine that the table maintained would almost always be smaller than maintaining a table of active tokens.</p>\n<h3 id=\"using-a-dynamic-secret-to-sign\" style=\"position:relative;\"><a href=\"#using-a-dynamic-secret-to-sign\" aria-label=\"using a dynamic secret to sign permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Using a Dynamic Secret to Sign</h3>\n<p>This solution still needs a database lookup, but interestingly requires no state. For this, we can use the hash of a piece of data to sign the token itself. For example, by using the hash of a user's password, when the user changes their password, subsequent transactions involving an old token will fail, as the signature will fail to be verified. The effectiveness of this, however, would depend on your requirements, as this would be limited to invalidating tokens based on changing data (such as changing roles, passwords, etc.). It would not allow you to invalidate a token whenever you want.</p>\n<h3 id=\"concluding-remarks\" style=\"position:relative;\"><a href=\"#concluding-remarks\" aria-label=\"concluding remarks 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>Concluding Remarks</h3>\n<p>I think that JSON Web Tokens coupled with a token blacklist is a fantastic way to manage authorization in web applications. This allows you to leverage the benefits of these tokens in reducing the network calls needed to secure your application, reduce the amount of data you need to store to manage sessions, and do so in a reliable way without introducing too much complexity.</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":"January 18, 2021","updated_date":null,"description":"A discussion on invalidating JSON Web Tokens.","title":"Invalidating JSON Web Tokens","tags":["JSON Web Tokens","JWT"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/0c11b157497c5b54f5a0149f01ce15ac/58556/unsplash.webp","srcSet":"/static/0c11b157497c5b54f5a0149f01ce15ac/61e93/unsplash.webp 200w,\n/static/0c11b157497c5b54f5a0149f01ce15ac/1f5c5/unsplash.webp 400w,\n/static/0c11b157497c5b54f5a0149f01ce15ac/58556/unsplash.webp 800w,\n/static/0c11b157497c5b54f5a0149f01ce15ac/99238/unsplash.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Nick Chim","github":"nickc95","avatar":null}}}},{"node":{"excerpt":"HTTP (hypertext transfer protocol) is a communication protocol that transfers data between client and server. HTTP requests are very…","fields":{"slug":"/engineering/tune-the-go-http-client-for-high-performance/"},"html":"<p>HTTP (hypertext transfer protocol) is a communication protocol that transfers data between client and server. HTTP requests are very essential to access resources from the same or remote server. In Golang, the <code>net/http</code> package comes with the default settings that we need to adjust according to our high-performance requirement.</p>\n<p>For setting up HTTP clients for making requests, most programming languages have different frameworks in place. We will take a hands-on approach in the coming sections to explore how HTTP requests can be made in Golang or Go, as I will refer to the language for the rest of the post.</p>\n<p>While working on the <a href=\"https://www.loginradius.com/blog/engineering/golang-maps/\">Golang projects</a>, I realized that improper configuration of HTTP might crash your server anytime.</p>\n<p>In the time when I was working with HTTP Client, I Observed some problems and their solutions, listed below:</p>\n<h2 id=\"problem1-default-http-client\" style=\"position:relative;\"><a href=\"#problem1-default-http-client\" aria-label=\"problem1 default http client permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Problem:1 Default Http Client</h2>\n<p>The HTTP client does not contain the request timeout setting by default.\nIf you are using http.Get(URL) or &#x26;Client{} that uses the http.DefaultClient. DefaultClient has not timeout setting; it comes with <code>no timeout</code></p>\n<p>Suppose the Rest API where you are making the request is broken, not sending the response back that keeps the connection open. More requests came, and open connection count will increase, Increasing server resources utilization, resulting in crashing your server when resource limits are reached.</p>\n<h3 id=\"solution-dont-use-the-default-http-client-always-specify-the-timeout-in-httpclient-according-to-your-use-case\" style=\"position:relative;\"><a href=\"#solution-dont-use-the-default-http-client-always-specify-the-timeout-in-httpclient-according-to-your-use-case\" aria-label=\"solution dont use the default http client always specify the timeout in httpclient according to your use case permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Solution: Don't use the default HTTP client, always specify the timeout in http.Client according to your use case</h3>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">var httpClient = &http.Client{</span>\n<span class=\"grvsc-line\">  Timeout: time.Second * 10,</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>For the Rest API, it is recommended that timeout should not more than 10 seconds.\nIf the Requested resource is not responded to in 10 seconds, the HTTP connection will be canceled with net/http: request canceled (Client.Timeout exceeded ...) error.</p>\n<h2 id=\"problem2-default-http-transport\" style=\"position:relative;\"><a href=\"#problem2-default-http-transport\" aria-label=\"problem2 default http transport permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Problem:2 Default Http Transport</h2>\n<p>By default, the Golang Http client performs the connection pooling. When the request completes, that connection remains open until the idle connection timeout (default is 90 seconds). If another request came, that uses the same established connection instead of creating a new connection, after the idle connection time, the connection will return to the pool.</p>\n<p>Using the connection pooling will keep less connection open and more requests will be served with minimal server resources.</p>\n<p>When we not defined transport in the http.Client, it uses the default transport <a href=\"https://golang.org/src/net/http/transport.go\">Go HTTP Transport</a></p>\n<p>Default configuration of the HTTP Transport, </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">var DefaultTransport RoundTripper = &Transport{</span>\n<span class=\"grvsc-line\">\t...</span>\n<span class=\"grvsc-line\">\tMaxIdleConns:          100,</span>\n<span class=\"grvsc-line\">\tIdleConnTimeout:       90 * time.Second,</span>\n<span class=\"grvsc-line\">\t...</span>\n<span class=\"grvsc-line\">}</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">const DefaultMaxIdleConnsPerHost = 2</span></code></pre>\n<p>MaxIdleConns is the connection pool size, and this is the maximum connection that can be open; its default value is 100 connections.</p>\n<p>There is problem with the default setting <code>DefaultMaxIdleConnsPerHost</code> with value of 2 connection,\nDefaultMaxIdleConnsPerHost is the number of connection can be allowed to open per host basic.\nMeans for any particular host out of 100 connection from the connection pool only two connection will be allocated to that host.</p>\n<p>With the more request came, it will process only two requests; other requests will wait for the connection to communicate with the host server and go in the <code>TIME_WAIT</code> state. As more request came, increase the connection to the <code>TIME_WAIT</code> state and increase the server resource utilization; at the limit, the server will crash.</p>\n<h3 id=\"solution-dont-use-default-transport-and-increase-maxidleconnsperhost\" style=\"position:relative;\"><a href=\"#solution-dont-use-default-transport-and-increase-maxidleconnsperhost\" aria-label=\"solution dont use default transport and increase maxidleconnsperhost permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Solution: Don't use Default Transport and increase MaxIdleConnsPerHost</h3>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">t := http.DefaultTransport.(*http.Transport).Clone()</span>\n<span class=\"grvsc-line\">t.MaxIdleConns = 100</span>\n<span class=\"grvsc-line\">t.MaxConnsPerHost = 100</span>\n<span class=\"grvsc-line\">t.MaxIdleConnsPerHost = 100</span>\n<span class=\"grvsc-line\">\t</span>\n<span class=\"grvsc-line\">httpClient = &http.Client{</span>\n<span class=\"grvsc-line\">  Timeout:   10 * time.Second,</span>\n<span class=\"grvsc-line\">  Transport: t,</span>\n<span class=\"grvsc-line\">}</span></code></pre>\n<p>By increasing connection per host and the total number of idle connection, this will increase the performance and serve more request with minimal server resources.</p>\n<p>Connection pool size and connection per host count can be increased as per server resources and requirements.</p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>In this article, we discussed the problems around the 'net/http' client default configurations. By changing some of the default settings of HTTP Client, we can achieve a High-performance HTTP client for production use. If you want to learn more about http, here is an interesting post on <a href=\"https://www.loginradius.com/blog/engineering/http-security-headers/\">HTTP security headers</a> If you like what you read, share your thoughts in the comment section.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n</style>","frontmatter":{"date":"January 12, 2021","updated_date":null,"description":"In this post, we will discuss how to make HTTP requests for higher performance in Go, and also how to tune it.","title":"How to Use the HTTP Client in GO To Enhance Performance","tags":["Golang","HTTP","Performance"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/2aae63044134172737715b9d1801c174/58556/index.webp","srcSet":"/static/2aae63044134172737715b9d1801c174/61e93/index.webp 200w,\n/static/2aae63044134172737715b9d1801c174/1f5c5/index.webp 400w,\n/static/2aae63044134172737715b9d1801c174/58556/index.webp 800w,\n/static/2aae63044134172737715b9d1801c174/99238/index.webp 1200w,\n/static/2aae63044134172737715b9d1801c174/135cd/index.webp 1280w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Mayank Agarwal","github":"mayankagrwal","avatar":null}}}},{"node":{"excerpt":"One fairly popular question that got asked on programming bulletin boards has to do with the similarities and differences between React’s…","fields":{"slug":"/engineering/react-constructor-get-initial-state/"},"html":"<p>One fairly popular question that got asked on programming bulletin boards has to do with the similarities and differences between React’s <code>constructor</code> and the built in method <code>getInitialState</code>. While the simple answer to this question is indeed simple: “getInitialState is the ES5 friendly method to define the initial state of a React component,” there are a couple more details around <code>getInitialState</code> as well as React’s ES5 support that are interesting and useful to highlight.</p>\n<h2 id=\"constructor-vs-getinitialstate-with-or-without-classes\" style=\"position:relative;\"><a href=\"#constructor-vs-getinitialstate-with-or-without-classes\" aria-label=\"constructor vs getinitialstate with or without classes permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Constructor vs getInitialState: With or without Classes:</h2>\n<p>One of the fundamental differences between ES5 and ES6 in regards to React implementation is the new <code>class</code> keyword. It allows definition of React components as classes, which is a familiar data structure for anyone who has had experience with more traditional object-oriented languages such as Java or C++. The class structure also allows for natural organization of the component’s elements like state, props, lifecycle methods and member functions. However, ES5 did not provide the same convenience. So instead of defining a React component as a class:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">HelloWorld</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">React</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Component</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">render</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Hello World</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>You would rely on a helper module called <code>create-react-class</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">createReactClass</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">require</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;create-react-class&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">HelloWorld</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">createReactClass</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">render</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Hello World</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span></code></pre>\n<p>And it is within the object passed into <code>create-react-class</code> that you could define an initial state by populating the <code>getInitialState</code> attribute:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">HelloWorld</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">createReactClass</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">getInitialState</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> {</span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">props</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">render</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Hello </span><span class=\"mtk4\">{this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">state</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span></code></pre>\n<p>Which, in ES6 implementation would be the equivalent of:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">HelloWorld</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">React</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Component</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span><span class=\"mtk12\">props</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">super</span><span class=\"mtk1\">(</span><span class=\"mtk12\">props</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">state</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">props</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">render</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Hello </span><span class=\"mtk4\">{this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">state</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">span</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<h2 id=\"autobinding\" style=\"position:relative;\"><a href=\"#autobinding\" aria-label=\"autobinding permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Autobinding</h2>\n<p>One difference worth noting is that the <code>create-react-class</code> method automatically binds <code>this</code> to every attribute method. This no longer holds true if you define React components using the common ES6 class syntax, making it so that you have to manually bind <code>this</code> to internal methods:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">HelloWorld</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">React</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Component</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span><span class=\"mtk12\">props</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">super</span><span class=\"mtk1\">(</span><span class=\"mtk12\">props</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">state</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">props</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">changeName</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">changeName</span><span class=\"mtk1\">.</span><span class=\"mtk11\">bind</span><span class=\"mtk1\">(</span><span class=\"mtk4\">this</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">changeName</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setState</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;World&quot;</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Or otherwise use the “arrow function” shorthand which takes care of binding:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">HelloWorld</span><span class=\"mtk1\"> </span><span class=\"mtk4\">extends</span><span class=\"mtk1\"> </span><span class=\"mtk10\">React</span><span class=\"mtk1\">.</span><span class=\"mtk10\">Component</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">constructor</span><span class=\"mtk1\">(</span><span class=\"mtk12\">props</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">super</span><span class=\"mtk1\">(</span><span class=\"mtk12\">props</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk12\">state</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">props</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">changeName</span><span class=\"mtk1\"> = () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">this</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setState</span><span class=\"mtk1\">({ </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;World&quot;</span><span class=\"mtk1\"> });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<h2 id=\"parting-words\" style=\"position:relative;\"><a href=\"#parting-words\" aria-label=\"parting words permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Parting Words</h2>\n<p>Since the update to ES6, there have been multiple new React iterations. You could now forgo the <code>constructor</code> declaration altogether and just declare <code>state</code> inline as a class member, or utilize React Hooks as a new way to initialize states. However, the ES5 support remains useful for legacy systems and adds to the overall flexibility of React as a toolset.</p>\n<p>You can read more about React's ES5 support <a href=\"https://reactjs.org/docs/react-without-es6.html\">in the official doc entry here</a>, and <a href=\"https://reactjs.org/blog/2015/01/27/react-v0.13.0-beta-1.html\">the v0.13.0 beta release blog entry here</a>, for the respective ES6 changes.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk17 { color: #808080; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n</style>","frontmatter":{"date":"January 05, 2021","updated_date":null,"description":"No ES6? No problem. getInitialState is the ES5 friendly method to define the initial state of a React component.","title":"Constructor vs getInitialState in React","tags":["JavaScript","React"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/d152aa4ad7b599edbdd9b6465d8f014b/58556/index.webp","srcSet":"/static/d152aa4ad7b599edbdd9b6465d8f014b/61e93/index.webp 200w,\n/static/d152aa4ad7b599edbdd9b6465d8f014b/1f5c5/index.webp 400w,\n/static/d152aa4ad7b599edbdd9b6465d8f014b/58556/index.webp 800w,\n/static/d152aa4ad7b599edbdd9b6465d8f014b/2eb2f/index.webp 865w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Nathan Nguyen","github":"nathannguyenn","avatar":null}}}},{"node":{"excerpt":"In JavaScript, web workers allow developers to benefit from parallel programming. Parallel programming enables various computations to be…","fields":{"slug":"/engineering/web-workers/"},"html":"<p>In JavaScript, web workers allow developers to benefit from parallel programming. Parallel programming enables various computations to be performed at the same time by applications. </p>\n<p>Web Workers are a browser feature that allows scripts to be executed on a separate thread from the main execution thread of your web application. This allows the main thread of your web application to run without being blocked by slow scripts in your application.</p>\n<h3 id=\"isnt-javascript-already-asynchronous\" style=\"position:relative;\"><a href=\"#isnt-javascript-already-asynchronous\" aria-label=\"isnt javascript already asynchronous permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Isn't JavaScript already asynchronous?</h3>\n<p>Well, sort of. This has been something that had confused me many a time when I was initially learning about JavaScript. JavaScript a synchronous, single-threaded language. However, JavaScript has features that allow you to execute asynchronous code, which is handled by browser engines (on your client) or by your OS (in NodeJS), which are capable of executing code in multiple threads.</p>\n<p>We work with asynchronous methods in JavaScript by either using callbacks, <a href=\"https://compile7.org/decompile/callback-vs-promises-vs-async-await/\">Promises or async/await</a>. We'll use Promises as an example for exploring asynchronicity in JavaScript.</p>\n<p>Promises are proxies for values that are not yet available when the Promise is created. This lets you organize parts of your code to run when the value becomes available or if something goes wrong.</p>\n<p>This does not mean that your code is running asynchronously. As I mentioned before, JavaScript code is executed on a single thread. The callback that processes the response from your created Promises still runs on your single main thread. Promises do, however, allow you to spawn asynchronous tasks, such as file I/O or making an HTTP request which runs outside of your code. This allows your main thread to work on something else while waiting for these tasks to return a response. This means that the callback functions which run after a response is received are called asynchronously.</p>\n<p>I feel that the distinction between your code running asynchronously vs. being called asynchronously is important, as you will see that you are not able to perform computationally expensive tasks without blocking your main thread, even when using Promises.</p>\n<p>Here is an example of using an expensive function (finding prime numbers) wrapped in a Promise.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">findPrimeNumbers</span><span class=\"mtk1\">(</span><span class=\"mtk12\">max</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Promise</span><span class=\"mtk1\">((</span><span class=\"mtk12\">resolve</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;starting findPrimeNumbers&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">primes</span><span class=\"mtk1\"> = [];</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">for</span><span class=\"mtk1\"> (</span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">0</span><span class=\"mtk1\">; </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> &lt; </span><span class=\"mtk12\">max</span><span class=\"mtk1\">; </span><span class=\"mtk12\">i</span><span class=\"mtk1\">++) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">i</span><span class=\"mtk1\"> === </span><span class=\"mtk7\">0</span><span class=\"mtk1\"> || </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> === </span><span class=\"mtk7\">1</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">continue</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">isPrime</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">true</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">for</span><span class=\"mtk1\"> (</span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">y</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">2</span><span class=\"mtk1\">; </span><span class=\"mtk12\">y</span><span class=\"mtk1\"> &lt; </span><span class=\"mtk12\">i</span><span class=\"mtk1\">; ++</span><span class=\"mtk12\">y</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">i</span><span class=\"mtk1\"> % </span><span class=\"mtk12\">y</span><span class=\"mtk1\"> === </span><span class=\"mtk7\">0</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">isPrime</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">false</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk15\">break</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">isPrime</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">primes</span><span class=\"mtk1\">.</span><span class=\"mtk11\">push</span><span class=\"mtk1\">(</span><span class=\"mtk12\">i</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;prime numbers found&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">resolve</span><span class=\"mtk1\">(</span><span class=\"mtk12\">primes</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;a&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">findPrimeNumbers</span><span class=\"mtk1\">(</span><span class=\"mtk7\">100000</span><span class=\"mtk1\">).</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;b&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;c&quot;</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>You'll find that the above program will print the following:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">a</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">starting</span><span class=\"mtk1\"> </span><span class=\"mtk12\">findPrimeNumbers</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">prime</span><span class=\"mtk1\"> </span><span class=\"mtk12\">numbers</span><span class=\"mtk1\"> </span><span class=\"mtk12\">found</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">c</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">b</span></span></code></pre>\n<p>The ordering of <code>a</code>, <code>b</code>, and <code>c</code> is not particularly noteworthy, as we already know that the callback for the <code>findPrimeNumbers</code> function will only execute after the main thread has nothing left to do, after printing <code>c</code>.</p>\n<p>What I did find interesting was that the statement printing <code>c</code> waits until the <code>findPrimeNumbers</code> function completes before being executed. To prevent functions like this from blocking the main thread, we'll have to use Web Workers.</p>\n<p>Web Workers run in a separate thread altogether, with no access to the context of the main thread. Data is sent between the worker and the main thread using a system of messages: the <code>postMessage()</code> method is used to send a message from one to the other, and the <code>onmessage</code> event handler is used to receive and respond to messages.</p>\n<p>First we need to create the script (we'll just call it <code>find-prime-numbers.js</code>) that the Web Worker will run:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">onmessage</span><span class=\"mtk1\"> = (</span><span class=\"mtk12\">event</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">data</span><span class=\"mtk1\"> } = </span><span class=\"mtk12\">event</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">primes</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">findPrimeNumbers</span><span class=\"mtk1\">(</span><span class=\"mtk11\">parseInt</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">));</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">postMessage</span><span class=\"mtk1\">(</span><span class=\"mtk12\">primes</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">findPrimeNumbers</span><span class=\"mtk1\">(</span><span class=\"mtk12\">max</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;starting findPrimeNumbers&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">primes</span><span class=\"mtk1\"> = [];</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">for</span><span class=\"mtk1\"> (</span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">0</span><span class=\"mtk1\">; </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> &lt; </span><span class=\"mtk12\">max</span><span class=\"mtk1\">; </span><span class=\"mtk12\">i</span><span class=\"mtk1\">++) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">i</span><span class=\"mtk1\"> === </span><span class=\"mtk7\">0</span><span class=\"mtk1\"> || </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> === </span><span class=\"mtk7\">1</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">continue</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">isPrime</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">true</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">for</span><span class=\"mtk1\"> (</span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">y</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">2</span><span class=\"mtk1\">; </span><span class=\"mtk12\">y</span><span class=\"mtk1\"> &lt; </span><span class=\"mtk12\">i</span><span class=\"mtk1\">; ++</span><span class=\"mtk12\">y</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">i</span><span class=\"mtk1\"> % </span><span class=\"mtk12\">y</span><span class=\"mtk1\"> === </span><span class=\"mtk7\">0</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">isPrime</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">false</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">break</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">isPrime</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">primes</span><span class=\"mtk1\">.</span><span class=\"mtk11\">push</span><span class=\"mtk1\">(</span><span class=\"mtk12\">i</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;prime numbers found&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk12\">primes</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}  </span></span></code></pre>\n<p>The <code>onmessage</code> handler receives an event with the message itself contained in the event's <code>data</code> attribute. Here we execute the <code>findPrimeNumbers()</code> function again, and use <code>postMessage()</code> function to send the result back to the main thread.</p>\n<p>Over in your main script, we'll create a worker object using the constructor <code>new Worker()</code>, which runs the named JavaScript file containing the code that we just wrote, which will run in the worker thread.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">primeNumberWorker</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Worker</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;./find-prime-numbers.js&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">primeNumberWorker</span><span class=\"mtk1\">.</span><span class=\"mtk11\">onmessage</span><span class=\"mtk1\"> = (</span><span class=\"mtk12\">event</span><span class=\"mtk1\">) </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;b&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;a&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">primeNumberWorker</span><span class=\"mtk1\">.</span><span class=\"mtk11\">postMessage</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;100000&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;c&quot;</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>Running this script will print the following:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">a</span>\n<span class=\"grvsc-line\">c</span>\n<span class=\"grvsc-line\">starting findPrimeNumbers</span>\n<span class=\"grvsc-line\">prime numbers found</span>\n<span class=\"grvsc-line\">b</span></code></pre>\n<p>You can see that this time, the prime numbers function is actually running on a thread separate from our main one, which allows the main thread to continue printing the statement <code>c</code> while the worker thread works out its own response.</p>\n<h3 id=\"when-should-you-use-javascript-web-worker\" style=\"position:relative;\"><a href=\"#when-should-you-use-javascript-web-worker\" aria-label=\"when should you use javascript web worker permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>When should you use JavaScript Web Worker</h3>\n<p>To reiterate, Web Workers allow you to run your own <a href=\"https://www.loginradius.com/blog/engineering/adding-multi-threading-to-javascript-using-web-workers/\">code on a separate thread</a>, which allows your main thread to continue rendering the UI, receive user input, etc., while your worker thread processes a response. </p>\n<p>For most web applications, the most expensive operations in your code will often be I/O, interacting with resources in your network. Thanks to <a href=\"https://www.loginradius.com/blog/engineering/understanding-event-loop/\">JavaScript's Event Loop</a>, these are already offloaded from your main thread to your system's operating system. As such, there is no need for Web Workers when making these kinds of operations. </p>\n<p>If you need to process large sets of data, there is a decent chance that you will be able to perform this on your server-side before sending it to your front end client for display to the user. This will allow you to rely on JavaScript's event loop to prevent these expensive operations from blocking your main thread.</p>\n<p>However, if your scenario must have these long-running tasks running on your client end, Web Workers would be an ideal solution for your needs. Some examples of these could be:</p>\n<ul>\n<li>As-you-type string validation, in situations where your validation logic is complex, such as a spell checker.</li>\n<li>Encrypting and decrypting data within your client, especially in cases where data is being exchanged frequently and cannot be exposed to your server.</li>\n<li>Client-side workspaces to allow your users to process and manipulate data before sending it to your server.</li>\n</ul>\n<h3 id=\"javascripty-web-worker-limitations\" style=\"position:relative;\"><a href=\"#javascripty-web-worker-limitations\" aria-label=\"javascripty web worker limitations permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Javascripty Web Worker Limitations</h3>\n<p>As Web Workers work on a separate thread, it has no access to the parent page, which calls it. This means that the worker itself cannot manipulate the DOM nor access any data stored within it. It is not able to access the browser's localStorage and sessionStorage either. You are limited to the data sent directly via <code>postMessage</code> or IndexedDB for accessing stored client data.</p>\n<p>As with anything multithreaded, adding Web Workers into your application will add complexity to your application. Natively, <code>postMessage</code> is the only direct line of communication between threads. You will need to define how more complex workflows will be managed between your main thread and worker thread (such as error handling).</p>\n<p>If your worker can be triggered multiple times, each request will simply be queued and will run when the previous has been completed. For more complex queuing mechanisms, you would have to define this yourself.</p>\n<h3 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h3>\n<p>With discussions dating back a decade, Web Workers are not a new feature. Despite their powerful potential, they haven't been widely adopted. Client side applications, for the most part, just haven't needed to perform intensive tasks where Web Workers would have been a solution. In addition, with a lack of widespread use, finding relatable examples to reference when implementing them is an extra barrier for adoption. </p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n</style>","frontmatter":{"date":"December 28, 2020","updated_date":null,"description":"Learn how to use JavaScript web workers to create parallel programming and execute multiple operations concurrently rather than interconnecting them.","title":"Web Workers in JS - An Introductory Guide","tags":["Web Workers"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/60585d671e6de5ad794eb12d714614ec/58556/unsplash.webp","srcSet":"/static/60585d671e6de5ad794eb12d714614ec/61e93/unsplash.webp 200w,\n/static/60585d671e6de5ad794eb12d714614ec/1f5c5/unsplash.webp 400w,\n/static/60585d671e6de5ad794eb12d714614ec/58556/unsplash.webp 800w,\n/static/60585d671e6de5ad794eb12d714614ec/99238/unsplash.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Nick Chim","github":"nickc95","avatar":null}}}}]},"markdownRemark":{"excerpt":"Introduction Ever wondered how apps like Spotify, Netflix, or Slack manage seamless login experiences across devices? Many of them use JWT…","fields":{"slug":"/engineering/how-to-integrate-jwt/"},"html":"<h2 id=\"introduction\" style=\"position:relative;\"><a href=\"#introduction\" aria-label=\"introduction 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>Introduction</h2>\n<p>Ever wondered how apps like Spotify, Netflix, or Slack manage seamless login experiences across devices? Many of them use JWT, or JSON Web Tokens, a compact, stateless method for securely transmitting user identity and session data across services.</p>\n<p>With JWT token authentication, identity information is embedded in a signed token, allowing you to maintain user sessions without server-side storage. This approach is highly scalable and ideal for modern architectures like SPAs, mobile apps, and microservices.</p>\n<p>In this blog, we’ll walk you through what is JWT, why use it, and how to implement JWT authentication using LoginRadius. </p>\n<p>You’ll learn what JWT is, why it’s effective, and how it works in real-world applications. We'll cover both integration methods (IDX and Direct API), generating your signing key, managing sessions, storing the JWT token securely, and applying best practices throughout.</p>\n<p>Whether you're a developer, product manager, or IAM architect, this guide offers a complete foundation for implementing JWT token authentication into your application stack.</p>\n<h2 id=\"what-is-jwt\" style=\"position:relative;\"><a href=\"#what-is-jwt\" aria-label=\"what is jwt 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 is JWT?</h2>\n<p><a href=\"https://www.loginradius.com/blog/engineering/jwt/\">JSON Web Token (JWT)</a> is an open standard (RFC 7519) used to transmit information securely between parties as a JSON object. It’s compact, self-contained, and digitally signed, making it a reliable format for authentication and authorization across modern applications.</p>\n<p>A JWT consists of three parts:</p>\n<ol>\n<li><strong>Header –</strong> Contains metadata like the type of token and signing algorithm (e.g., HS256).</li>\n<li><strong>Payload –</strong> Stores the actual data or “claims,” such as user ID, roles, and token expiry.</li>\n<li><strong>Signature –</strong> A cryptographic hash that ensures the token hasn’t been tampered with.</li>\n</ol>\n<p><em>Example of a token structure:</em></p>\n<p>&#x3C;base64Header>.&#x3C;base64Payload>.&#x3C;signature></p>\n<h2 id=\"why-use-jwt\" style=\"position:relative;\"><a href=\"#why-use-jwt\" aria-label=\"why use jwt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Why Use JWT?</h2>\n<ul>\n<li><strong>Stateless Authentication</strong>: No server-side session storage is needed — the token holds all necessary user info. </li>\n<li><strong>Portable</strong>: Works seamlessly across domains, services, and APIs. </li>\n<li><strong>Scalable</strong>: Ideal for microservices, SPAs, mobile apps, and serverless functions. </li>\n<li><strong>Interoperable</strong>: JWTs are supported across many languages and frameworks.</li>\n</ul>\n<h2 id=\"how-jwt-works\" style=\"position:relative;\"><a href=\"#how-jwt-works\" aria-label=\"how jwt works 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 JWT Works?</h2>\n<p><img src=\"/f29edbf2978577390c7ffa02e9bc4dda/lr-JWT-authentication.webp\" alt=\"Flowchart illustrating LoginRadius JWT authentication via Identity Provider (IDP), showing user redirection from login icon to login page, authentication with IDP, JWT token validation, and subsequent redirection to the customer&#x27;s website or error page based on validation results.\"></p>\n<ol>\n<li>A user logs in with credentials. </li>\n<li>Your app (or identity provider like LoginRadius) issues a signed JWT. </li>\n<li>The client stores the token and sends it with each request (usually in the Authorization header). </li>\n<li>The server validates the token’s signature and claims. </li>\n<li>If valid, access is granted — without any session stored on the backend.</li>\n</ol>\n<p>JWT simplifies identity verification, especially when you're building apps that talk to APIs or need to scale without centralized session storage.</p>\n<h2 id=\"jwt-authentication-with-loginradius-overview\" style=\"position:relative;\"><a href=\"#jwt-authentication-with-loginradius-overview\" aria-label=\"jwt authentication with loginradius overview 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>JWT Authentication with LoginRadius: Overview</h2>\n<p>LoginRadius provides robust support for JWT (JSON Web Token) authentication, which allows for flexible and secure access control across different digital platforms. Whether you're building a fully custom identity flow or using a pre-built interface, the platform supports various integration approaches depending on your architecture.</p>\n<p>If you're looking to understand how to implement JWT token authentication effectively, LoginRadius offers two primary implementation models that cater to different levels of customization and control:</p>\n<h3 id=\"1-idx-implementation--jwt-through-a-hosted-login-page\" style=\"position:relative;\"><a href=\"#1-idx-implementation--jwt-through-a-hosted-login-page\" aria-label=\"1 idx implementation  jwt through a hosted login page permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. IDX Implementation – JWT through a Hosted Login Page</h3>\n<p>The IDX-hosted login approach enables secure, standards-compliant, JWT-based authentication without requiring you to build a custom login interface. This is a strategic option for fast, compliant, and user-friendly deployments.</p>\n<ul>\n<li>The Identity Experience Framework (IDX) comes with a fully custom branded hosted login page.</li>\n<li>Once the user logs in and gets enrolled, the user’s JWTs are automatically generated and issued. These tokens can be utilized for managing user sessions and accessing the APIs.</li>\n<li>This approach simplifies deployment without compromising on user experience and security standards.</li>\n</ul>\n<h3 id=\"configuration-steps\" style=\"position:relative;\"><a href=\"#configuration-steps\" aria-label=\"configuration steps 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><strong>Configuration Steps:</strong></h3>\n<ol>\n<li>Enable JWT Login</li>\n<li>Go to <a href=\"https://console.loginradius.com/authentication/authentication-configuration\">authentication configuration settings</a> and enable JWT Login in the Admin Console.</li>\n</ol>\n<p><img src=\"/9fb19dd9c88c7916aeebd03ab6e661b7/lr-admin-console.webp\" alt=\"Screenshot of LoginRadius Admin Console showing JWT Custom IDP configuration interface with options for provider name, algorithm (HS256), key entry, clock skew, and expiration time settings.\"></p>\n<ol start=\"2\">\n<li>Specify your signing algorithm and expiry policy, and define your JWT Secret Key.</li>\n<li>Input a secure JWT signing key.</li>\n<li>Specify token expiry duration (e.g., 15–60 minutes)</li>\n<li>Select the desired algorithm —HS256 for symmetric signing (same key signs and verifies)</li>\n<li>RS256 for asymmetric signing, where LoginRadius securely stores the private key used to sign the JWT.</li>\n<li>Your app or backend service uses the public key to validate the token signature.</li>\n<li>LoginRadius provides a JWKS (JSON Web Key Set) endpoint to dynamically fetch and rotate public keys, ensuring trust without key exposure.</li>\n<li>Update IDX Template for Callback</li>\n<li>Modify your IDX login page template to retrieve the JWT post-login. You can access the token via redirect URL parameters or secure JavaScript callbacks.</li>\n</ol>\n<h3 id=\"example-response\" style=\"position:relative;\"><a href=\"#example-response\" aria-label=\"example response 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>Example Response:</h3>\n<p>{</p>\n<p>  \"access_token\": \"eyJhbGciOiJIUzI1NiIsInR...\",</p>\n<p>  \"expires_in\": 1800</p>\n<p>}</p>\n<p>This integration approach works best for all teams that want effective identity workflows without the complexity of building proprietary login screens, something that is crucial for customer portals, onboarding of mobile applications, and even managing access for business partners.</p>\n<h3 id=\"2-direct-api-implementation--self-managed-login\" style=\"position:relative;\"><a href=\"#2-direct-api-implementation--self-managed-login\" aria-label=\"2 direct api implementation  self managed login 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>2. Direct API Implementation – Self Managed Login</h3>\n<p>If you’re building a custom login UI or working in a headless environment, LoginRadius lets you generate and handle JWTs directly through its <a href=\"https://www.loginradius.com/docs/api/v2/customer-identity-api/\">Authentication APIs</a>. Here’s how you can programmatically perform token authentication using the classic method:</p>\n<ul>\n<li>For custom front-end applications, LR offers an API to authenticate users and issue JWT tokens.</li>\n<li>In response to the login request, the developers are provided with signed tokens that can be validated on the client’s side or by downstream services.</li>\n<li>This method is best fit for enterprise applications that have complex custom workflows or are designed to be embedded into other applications.</li>\n</ul>\n<h3 id=\"configuration-steps-1\" style=\"position:relative;\"><a href=\"#configuration-steps-1\" aria-label=\"configuration steps 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><strong>Configuration Steps:</strong></h3>\n<h4 id=\"step-1-authenticate-via-api\" style=\"position:relative;\"><a href=\"#step-1-authenticate-via-api\" aria-label=\"step 1 authenticate via api permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Step 1: Authenticate via API:</h4>\n<ul>\n<li>\n<p>Send a POST login request to the LR Authentication URL: </p>\n<p>POST /identity/v2/auth/login</p>\n</li>\n</ul>\n<p>Include the user’s credentials (email + password) in the request body.</p>\n<h4 id=\"step-2-get-jwt-in-response\" style=\"position:relative;\"><a href=\"#step-2-get-jwt-in-response\" aria-label=\"step 2 get jwt in response 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: Get JWT in Response</h4>\n<ul>\n<li>If the user credentials are authentic, then the JWT token will be available in response.</li>\n</ul>\n<p>{</p>\n<p> \"access_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",</p>\n<p> \"expires_in\": 3600</p>\n<p>}</p>\n<h4 id=\"step-3-jwt-decoding-and-validation\" style=\"position:relative;\"><a href=\"#step-3-jwt-decoding-and-validation\" aria-label=\"step 3 jwt decoding and validation 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: JWT Decoding and Validation</h4>\n<ul>\n<li>Use any JWT library (e.g., jsonwebtoken for Node.js or pyjwt for Python) to decode the token.</li>\n<li>Validate the signature using your configured secret key.</li>\n<li>Confirm claims like exp, iat, aud, and iss.</li>\n</ul>\n<h4 id=\"step-4-set-custom-claims-optional\" style=\"position:relative;\"><a href=\"#step-4-set-custom-claims-optional\" aria-label=\"step 4 set custom claims optional 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: Set Custom Claims (Optional)</h4>\n<p>With LoginRadius, it is possible to customize the payload to include user roles and/or any additional metadata. You can set custom JWT claims on the Admin Console.</p>\n<p>With this method, you have complete customization over login flows while using LoginRadius to issue signed JWTs for user session management.</p>\n<p><strong>NOTE-</strong> With either method, LoginRadius ensures that JWTs are securely signed, optionally short-lived, and compatible with standard token validation libraries, making integration seamless for everyone.</p>\n<p>To get started with JWT implementation, you can<a href=\"https://www.loginradius.com/docs/single-sign-on/federated-sso/jwt-login/jwt-implementation-guide/\"> read our complete developer documentation</a>. </p>\n<h2 id=\"hosted-login-vs-direct-api\" style=\"position:relative;\"><a href=\"#hosted-login-vs-direct-api\" aria-label=\"hosted login vs direct api permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Hosted Login vs Direct API</h2>\n<p><img src=\"/15ec02ac98d24a9f1f28e5d0f06b9174/IDX-vs-Direct-API-JWT.webp\" alt=\"Illustration showing IDX vs Direct API JWT flow diagram comparing LoginRadius JWT authentication methods via Hosted Login Page (IDX) and Custom Login UI using Direct API, illustrating user login, JWT issuance, and token return process.\"></p>\n<h2 id=\"what-is-session-management-and-how-it-works-with-jwt\" style=\"position:relative;\"><a href=\"#what-is-session-management-and-how-it-works-with-jwt\" aria-label=\"what is session management and how it works with jwt 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 is Session Management and How It Works with JWT</h2>\n<p><a href=\"https://www.loginradius.com/blog/identity/user-session-management/\">Session management </a>is how your app keeps track of a user after they log in so they don’t have to prove who they are with every request.</p>\n<p>In traditional apps, sessions are stored on the server using session IDs. Every time a request comes in, the server checks that session ID to verify the user.</p>\n<p>In modern apps, especially SPAs and APIs, JWTs are used to manage sessions without needing server-side storage; this is called stateless session management. The token itself carries the user’s identity, roles, and expiration details. As long as the token is valid, the user stays logged in.</p>\n<p>Good session management ensures:</p>\n<ul>\n<li>Security against session hijacking</li>\n<li>Fast user validation without hitting a database</li>\n<li>Smooth experiences with token refresh strategies</li>\n</ul>\n<h2 id=\"how-loginradius-handles-session-management-with-jwt\" style=\"position:relative;\"><a href=\"#how-loginradius-handles-session-management-with-jwt\" aria-label=\"how loginradius handles session management with jwt 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 LoginRadius Handles Session Management with JWT:</h2>\n<ol>\n<li>\n<p>User Logs In </p>\n<ul>\n<li>LoginRadius returns an access token (JWT) and, optionally, a refresh token.</li>\n</ul>\n</li>\n<li>\n<p>Client Stores the Token </p>\n<ul>\n<li>Access tokens are stored in memory, sessionStorage, or secure cookies. </li>\n<li>They’re sent on every request via the Authorization: Bearer header. </li>\n</ul>\n</li>\n<li>\n<p>Access Token Expiry </p>\n<ul>\n<li>These tokens are short-lived by design (e.g., 15–30 minutes). </li>\n<li>Once expired, the client can use the refresh token to request a new access token. </li>\n</ul>\n</li>\n<li>\n<p>Token Renewal </p>\n<ul>\n<li>LoginRadius validates the refresh token and issues a new JWT, i.e., no user re-authentication is needed. </li>\n<li>Refresh tokens can be revoked at any time.</li>\n</ul>\n</li>\n<li>Logout and Token Revocation Strategy</li>\n</ol>\n<p>When the user logs out, both the access token and refresh token should be cleared from client storage.</p>\n<ul>\n<li>The refresh token can be explicitly revoked via the LoginRadius API, terminating the ability to renew sessions. </li>\n<li>\n<p>However, access tokens are stateless and cannot be revoked mid-lifecycle unless: </p>\n<ul>\n<li>You maintain a blacklist of token IDs (jti claims) and check them on each request. </li>\n<li>You use short-lived access tokens to limit exposure naturally. </li>\n<li>Or, you rotate your JWT signing key, invalidating all previously issued tokens. </li>\n</ul>\n</li>\n</ul>\n<p>Combining these strategies gives you greater control over token misuse and enables a robust, enterprise-grade logout flow. </p>\n<p><a href=\"https://www.loginradius.com/resource/whitepaper/secure-api-using-oauth2\"><img src=\"/e55ae4bbc8ce62e13f03e46e29ebe7cc/api-economy.webp\" alt=\"illustration showing LoginRadius free downloadable resource named API economy is transforming digitization: how to secure it using oauth 2.0.\"></a></p>\n<h2 id=\"how-to-store-jwt-tokens\" style=\"position:relative;\"><a href=\"#how-to-store-jwt-tokens\" aria-label=\"how to store jwt tokens 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 Store JWT Tokens?</h2>\n<p>When you implement JWT-based authentication, the client (browser or mobile app) needs a way to store the access token and, optionally, the refresh token after they are issued by the authentication server. This stored token is then attached to every subsequent request to prove the user's identity.</p>\n<p>Choosing where to store the JWT is a crucial security decision. The most common storage options are:</p>\n<ul>\n<li>localStorage</li>\n<li>sessionStorage</li>\n<li>HTTP-only cookies</li>\n</ul>\n<p>Each option has trade-offs between security, accessibility, and persistence, and the right choice depends on your application's architecture and threat model.</p>\n<h4 id=\"recommended-storage-strategy\" style=\"position:relative;\"><a href=\"#recommended-storage-strategy\" aria-label=\"recommended storage strategy 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>Recommended Storage Strategy</h4>\n<ul>\n<li>\n<p>Access Tokens </p>\n<ul>\n<li>For SPAs: store in memory or sessionStorage for short-term access </li>\n<li>If stored in the browser, protect against XSS </li>\n</ul>\n</li>\n<li>\n<p>Refresh Tokens</p>\n<ul>\n<li>Always store the JWT refresh token in HTTP-only secure cookies to prevent JavaScript access. This adds a critical layer of protection against XSS attacks.</li>\n<li>Combine with SameSite=Strict or SameSite=Lax attributes to mitigate CSRF risks and ensure the JWT refresh token is only sent in intended contexts.</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"best-practices-for-storing-jwts\" style=\"position:relative;\"><a href=\"#best-practices-for-storing-jwts\" aria-label=\"best practices for storing jwts 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>Best Practices for Storing JWTs</h2>\n<ol>\n<li>Never store sensitive tokens (like refresh tokens) in localStorage or sessionStorage.</li>\n<li>Use Secure and HttpOnly flags with cookies to prevent JavaScript access and ensure transmission only over HTTPS.</li>\n<li>Set the SameSite=Strict or Lax attribute on cookies to protect against CSRF.</li>\n<li>Use short-lived access tokens and rotate refresh tokens regularly.</li>\n<li>Implement CSP (Content Security Policy) to reduce XSS risk.</li>\n<li>Avoid storing any tokens in frontend code (e.g., hardcoded in JS files).</li>\n</ol>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>JWT authentication with LoginRadius offers a modern, stateless approach to managing sessions across distributed systems. The IDX integration is ideal for rapid deployment, while the Direct API model is best for organizations needing deep customization and integration flexibility.</p>\n<p>With robust token signing, refresh capabilities, and centralized control, LoginRadius provides a future-ready foundation for secure, scalable identity architecture. <a href=\"https://www.loginradius.com/contact-us?utm_source=blog&#x26;utm_medium=web&#x26;utm_campaign=how-to-integrate-jwt\">Contact us</a> to know more about JWT authentication and implementation guide. </p>\n<h2 id=\"faqs\" style=\"position:relative;\"><a href=\"#faqs\" aria-label=\"faqs 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>FAQs</h2>\n<h3 id=\"1-what-is-jwt-authentication-used-for\" style=\"position:relative;\"><a href=\"#1-what-is-jwt-authentication-used-for\" aria-label=\"1 what is jwt authentication used for 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>1. What is JWT authentication used for?</h3>\n<p><strong>A:</strong> JWT authentication securely verifies user identities, enabling stateless session management across web, mobile apps, and microservices without server-side session storage.</p>\n<h3 id=\"2-how-does-loginradius-simplify-jwt-integration\" style=\"position:relative;\"><a href=\"#2-how-does-loginradius-simplify-jwt-integration\" aria-label=\"2 how does loginradius simplify jwt integration 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>2. How does LoginRadius simplify JWT integration?</h3>\n<p><strong>A:</strong> LoginRadius simplifies JWT integration by offering hosted <a href=\"https://www.loginradius.com/docs/single-sign-on/federated-sso/jwt-login/jwt-implementation-guide/\">IDX login pages </a>and direct API-based authentication methods, enabling rapid deployment and deep customization.</p>\n<h3 id=\"3-is-jwt-authentication-secure\" style=\"position:relative;\"><a href=\"#3-is-jwt-authentication-secure\" aria-label=\"3 is jwt authentication secure 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>3. Is JWT authentication secure?</h3>\n<p><strong>A:</strong> Yes, JWT authentication is secure when implemented with best practices like short-lived tokens, secure storage methods, signature validation, and refresh token rotation.</p>\n<h3 id=\"4-can-jwt-tokens-be-revoked-with-loginradius\" style=\"position:relative;\"><a href=\"#4-can-jwt-tokens-be-revoked-with-loginradius\" aria-label=\"4 can jwt tokens be revoked with loginradius 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>4. Can JWT tokens be revoked with LoginRadius?</h3>\n<p><strong>A:</strong> Yes, LoginRadius allows<a href=\"https://www.loginradius.com/docs/api/v2/customer-identity-api/refresh-token/revoke-refresh-token/?q=revoke+jwt\"> revocation of JWT</a> refresh tokens explicitly, and supports strategies like short-lived tokens and key rotation to manage token lifecycles securely.</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":"April 15, 2025","updated_date":null,"description":"Discover JWT (JSON Web Token) authentication, its advantages, and how to integrate it seamlessly using LoginRadius' hosted IDX and Direct API methods for secure, scalable identity management.","title":"JWT Authentication with LoginRadius: Quick Integration Guide","tags":["JWT","JSON Web Token","Authentication","Authorization"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":0.7782101167315175,"src":"/static/4cedb7829f98208cbc6d5a9aea4e983d/58556/how-to-integrate-jwt.webp","srcSet":"/static/4cedb7829f98208cbc6d5a9aea4e983d/61e93/how-to-integrate-jwt.webp 200w,\n/static/4cedb7829f98208cbc6d5a9aea4e983d/1f5c5/how-to-integrate-jwt.webp 400w,\n/static/4cedb7829f98208cbc6d5a9aea4e983d/58556/how-to-integrate-jwt.webp 800w,\n/static/4cedb7829f98208cbc6d5a9aea4e983d/1cc9f/how-to-integrate-jwt.webp 896w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Kundan Singh","github":null,"avatar":null}}}},"pageContext":{"limit":6,"skip":96,"currentPage":17,"type":"//engineering//","numPages":53,"pinned":"5c425581-f474-5ae9-abe7-cf5342db2aaa"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}