tag:blogger.com,1999:blog-34294662388276101002024-03-27T12:59:45.009+05:30Best way of learning is Sharing.Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.comBlogger77125tag:blogger.com,1999:blog-3429466238827610100.post-24754620073489685222024-03-20T15:46:00.002+05:302024-03-20T15:47:50.141+05:30End-to-End test with cypress<p> <span style="background-color: white; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">Before we start on E2E test writing using cypress, let’s know the cpress.</span></p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="dc7b" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;"><span class="ti jo" style="box-sizing: inherit; font-weight: 700;">What is Cypress?</span><br style="box-sizing: inherit;" />Cypress is a next-generation front-end testing tool built for modern web applications. In short, it enables any browser-based web application to write unit, integration, or end-to-end tests.</p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="5940" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">Cypress also has a companion product to record your test runs and make it available anywhere anytime with <a class="af la" href="https://docs.cypress.io/guides/cloud/introduction" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">Cypress Cloud</a> enterprise application.</p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="be34" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">Here in this article, we will learn to setup the E2E project for our web based application.</p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="337e" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;"><span class="ti jo" style="box-sizing: inherit; font-weight: 700;">Installing Cypress</span><br style="box-sizing: inherit;" />First we need to setup cypress and we can do it as explained on the link below based on your OS enviornment.</p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="38fe" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;"><a class="af la" href="https://docs.cypress.io/guides/getting-started/installing-cypress" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">Seamless Cypress Installation Guide | Cypress Documentation</a></p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="c059" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">After you are done with installing, you will see a basic structure added in your designated location with some config files and a folder called ‘cypress/e2e’ under which we will be writing E2E tests.</p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="e2c4" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">From here, we will certain changes to organize our structure by following some best practices for our E2E test coverage.</p><ol class="" style="background-color: white; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; list-style: none none; margin: 0px; padding: 0px;"><li class="tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud aez afa afb bj" data-selectable-paragraph="" id="4a1d" style="box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 2.14em; padding-left: 0px;">Run your tests always in incognito mode to avoid browser’s cached data and to do this, we need add the following setting in the ‘<span class="ti jo" style="box-sizing: inherit; font-weight: 700;">cypress.config.js</span>’ file available in your base project location (where cypress folder is created). * if the file is not created then add it.</li></ol><pre class="ue uf ug uh ui uj uk ul bo um ba bj" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="un uo pb uk b bf up uq l ur us" data-selectable-paragraph="" id="5fe6" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">`const <span class="hljs-punctuation" style="box-sizing: inherit;">{</span> defineConfig <span class="hljs-punctuation" style="box-sizing: inherit;">}</span> = require(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"cypress"</span>);<br style="box-sizing: inherit;" />const cucumber = require('cypress-cucumber-preprocessor').default<br style="box-sizing: inherit;" />const createBundler = require(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"@bahmutov/cypress-esbuild-preprocessor"</span>);<br style="box-sizing: inherit;" />const preprocessor = require(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"@badeball/cypress-cucumber-preprocessor"</span>);<br style="box-sizing: inherit;" />const createEsbuildPlugin = require(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"@badeball/cypress-cucumber-preprocessor/esbuild"</span>);<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" />const setupNodeEvents = async (on<span class="hljs-punctuation" style="box-sizing: inherit;">,</span> config) => <span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> on(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"before:browser:launch"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span> (browser = <span class="hljs-punctuation" style="box-sizing: inherit;">{</span><span class="hljs-punctuation" style="box-sizing: inherit;">}</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span> launchOptions) => <span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> if (browser.family === 'chromium' && browser.name !== 'electron') <span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> launchOptions.args.push(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"--incognito"</span>);<br style="box-sizing: inherit;" /> return launchOptions;<br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> if (browser.name === 'electron') <span class="hljs-punctuation" style="box-sizing: inherit;">{</span> <br style="box-sizing: inherit;" /> launchOptions.preferences.incognito = <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span>;<br style="box-sizing: inherit;" /> return launchOptions;<br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span>);<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> await preprocessor.addCucumberPreprocessorPlugin(on<span class="hljs-punctuation" style="box-sizing: inherit;">,</span> config);<br style="box-sizing: inherit;" /> on(<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"file:preprocessor"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> createBundler(<span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> plugins<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-punctuation" style="box-sizing: inherit;">[</span>createEsbuildPlugin.default(config)<span class="hljs-punctuation" style="box-sizing: inherit;">]</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span>)<span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> );<br style="box-sizing: inherit;" /> return config;<br style="box-sizing: inherit;" /><span class="hljs-punctuation" style="box-sizing: inherit;">}</span>;</span></pre><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="ae32" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">2. Add the below setting to avoid issues with Microsoft SSO login in the config file after the above code.</p><pre class="ue uf ug uh ui uj uk ul bo um ba bj" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="un uo pb uk b bf up uq l ur us" data-selectable-paragraph="" id="691d" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">module.exports = defineConfig(<span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> viewportWidth<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">1920</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> viewportHeight<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">1080</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> defaultCommandTimeout<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">20000</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> chromeWebSecurity<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">false</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> fixturesFolder<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">false</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> video<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> e2e<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> projectId<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"mywebapp"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> hideXHRInCommandLog<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//to avoid "Infinite redirection - iframe-request-id" issue with Azure AD SSO login issue in cypress</span><br style="box-sizing: inherit;" /> experimentalSessionAndOrigin<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> experimentalModifyObstructiveThirdPartyCode <span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> setupNodeEvents<span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> specPattern<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"**/*.feature"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> excludeSpecPattern<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-punctuation" style="box-sizing: inherit;">[</span><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"*.js"</span><span class="hljs-punctuation" style="box-sizing: inherit;">]</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span>);</span></pre><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="a66a" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">To know more about this go through my previous article here as: <a class="af la" href="https://medium.com/@binodmahto/infinite-redirection-iframe-request-id-issue-with-azure-ad-sso-login-issue-in-cypress-89cf40d8e58a" rel="noopener" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;">https://binodmahto.blogspot.com/2024/03/infinite-redirection-iframe-request-id.html</a></p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="3a85" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">3. To avoid hardcoding any sensitive or common values required for tests, add an environment config file in the base folder (where cypress.config.js is there) as ‘<span class="ti jo" style="box-sizing: inherit; font-weight: 700;">cypress.env.json</span>’.</p><pre class="ue uf ug uh ui uj uk ul bo um ba bj" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="un uo pb uk b bf up uq l ur us" data-selectable-paragraph="" id="bfc7" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"web_url"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"https://mywebapp.com"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"username"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"*****"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"password"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"*****"</span><br style="box-sizing: inherit;" /><span class="hljs-punctuation" style="box-sizing: inherit;">}</span></span></pre><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="8569" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">4. Add all your E2E test scenarios by creating *.feature file inside cypress/e2e/features. For example, I’m adding a file as <span class="ti jo" style="box-sizing: inherit; font-weight: 700;">home.feature </span>with the below code.</p><pre class="ue uf ug uh ui uj uk ul bo um ba bj" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="un uo pb uk b bf up uq l ur us" data-selectable-paragraph="" id="4944" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">Feature: Welcome User Test<br style="box-sizing: inherit;" />@smoke<br style="box-sizing: inherit;" />Scenario: verify if user is successfully able to login<br style="box-sizing: inherit;" /> Given User logs in through azure ad sso<br style="box-sizing: inherit;" /> Then User can view the welcome home page</span></pre><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="ecfb" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">Based on the above code, basically, I created a test scenario where a user will be able to log in to my web application with Microsoft SSO login and then be redirected to the welcome home page after successful login.</p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="78d4" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">Note: What you mentioned in Given and Then is your test steps and the cypress will look for the exact match of these defined steps here in all the step definitions files in crpress/e2e/step_definitions folder by scanning through all *.cy.ts files here.</p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="09ae" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">5. Add/create step definitions files. Based on above steps our test sceanrio has two steps as given and then so lets create fisrt step definition file for login as <span class="ti jo" style="box-sizing: inherit; font-weight: 700;">ssologinpage.cy.ts </span>inside <span class="ti jo" style="box-sizing: inherit; font-weight: 700;">crpress/e2e/step_definitions</span> folder with below code.</p><pre class="ue uf ug uh ui uj uk ul bo um ba bj" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="un uo pb uk b bf up uq l ur us" data-selectable-paragraph="" id="b89c" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-selector-tag" style="box-sizing: inherit; color: #aa0d91;">import</span> { <span class="hljs-selector-tag" style="box-sizing: inherit; color: #aa0d91;">Given</span>, <span class="hljs-selector-tag" style="box-sizing: inherit; color: #aa0d91;">Then</span>, <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">When</span> } from <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"@badeball/cypress-cucumber-preprocessor"</span>;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">Given</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"User logs in through azure ad sso"</span>, () => {<br style="box-sizing: inherit;" /> try{<br style="box-sizing: inherit;" /> cy.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">visit</span>(Cypress.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">env</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'web_url'</span>));<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> cy.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">origin</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'login.microsoftonline.com'</span>, () => {<br style="box-sizing: inherit;" /> cy.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">get</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'input[type="email"]'</span>).<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">type</span>(Cypress.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">env</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'username'</span>));<br style="box-sizing: inherit;" /> cy.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">get</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'input[type="submit"]'</span>).<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">click</span>();<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> cy.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">get</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'input[type="password"]'</span>).<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">type</span>(Cypress.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">env</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'password'</span>), {<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">log</span>: false,<br style="box-sizing: inherit;" /> });<br style="box-sizing: inherit;" /> cy.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">get</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'input[type="submit"]'</span>).<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">click</span>();<br style="box-sizing: inherit;" /> cy.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">get</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'#idBtn_Back'</span>).<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">click</span>();<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> });<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">catch</span>(exception){<br style="box-sizing: inherit;" /> throw new <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">SyntaxError</span>( <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Failed to login"</span>,);<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />});</span></pre><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="b7cf" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">Above code define the script for login steps where SSO login will be performed using configure user credentials in cypress.env.json file.</p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="f351" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">Note: If your application uses your custom login form then change the code here accordingly.</p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="0264" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">6. Next add the step for Then steps for welcome home vaildation as <span class="ti jo" style="box-sizing: inherit; font-weight: 700;">homepage.cy.ts</span> inside <span class="ti jo" style="box-sizing: inherit; font-weight: 700;">crpress/e2e/step_definitions</span> folder with below code.</p><pre class="ue uf ug uh ui uj uk ul bo um ba bj" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="un uo pb uk b bf up uq l ur us" data-selectable-paragraph="" id="f994" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">import</span> { <span class="hljs-title.class" style="box-sizing: inherit;">Given</span>, <span class="hljs-title.class" style="box-sizing: inherit;">Then</span>, <span class="hljs-title.class" style="box-sizing: inherit;">When</span> } <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">from</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"@badeball/cypress-cucumber-preprocessor"</span>;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-title.class" style="box-sizing: inherit;">Then</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"User can view the welcome home page"</span>, <span class="hljs-function" style="box-sizing: inherit;">() =></span> {<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">try</span>{<br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//Validate Title</span><br style="box-sizing: inherit;" /> cy.<span class="hljs-title.function" style="box-sizing: inherit;">get</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'.page-title'</span>).<span class="hljs-title.function" style="box-sizing: inherit;">contains</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'Welcome User'</span>);<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">catch</span>(exception)<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">throw</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> <span class="hljs-title.class" style="box-sizing: inherit;">SyntaxError</span>(<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Homepage details not displayed"</span>,<br style="box-sizing: inherit;" /> );<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />});</span></pre><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="c1a6" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">7. cypress.env.json file has been created as best practice to separate environment specific variables and to avoid repetitive common values hence it is must to add this file in <span class="ti jo" style="box-sizing: inherit; font-weight: 700;">.gitignore</span> file to avoid any push for this file by any user.</p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="a4fa" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">As a result, your folder structure will look like this:</p><figure class="ue uf ug uh ui aff afc afd paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="afg afh fl afi bg afj" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 680px; z-index: auto;" tabindex="0"><div class="afc afd afe" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 357px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 357px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*1_cE1oIZ1ZqkALMyHea4mw.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*1_cE1oIZ1ZqkALMyHea4mw.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*1_cE1oIZ1ZqkALMyHea4mw.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*1_cE1oIZ1ZqkALMyHea4mw.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*1_cE1oIZ1ZqkALMyHea4mw.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*1_cE1oIZ1ZqkALMyHea4mw.png 1100w, https://miro.medium.com/v2/resize:fit:714/format:webp/1*1_cE1oIZ1ZqkALMyHea4mw.png 714w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 357px" srcset="https://miro.medium.com/v2/resize:fit:640/1*1_cE1oIZ1ZqkALMyHea4mw.png 640w, https://miro.medium.com/v2/resize:fit:720/1*1_cE1oIZ1ZqkALMyHea4mw.png 720w, https://miro.medium.com/v2/resize:fit:750/1*1_cE1oIZ1ZqkALMyHea4mw.png 750w, https://miro.medium.com/v2/resize:fit:786/1*1_cE1oIZ1ZqkALMyHea4mw.png 786w, https://miro.medium.com/v2/resize:fit:828/1*1_cE1oIZ1ZqkALMyHea4mw.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*1_cE1oIZ1ZqkALMyHea4mw.png 1100w, https://miro.medium.com/v2/resize:fit:714/1*1_cE1oIZ1ZqkALMyHea4mw.png 714w" style="box-sizing: inherit;"></source><img alt="" class="bg sr afk c" height="439" loading="lazy" role="presentation" src="https://miro.medium.com/v2/resize:fit:357/1*1_cE1oIZ1ZqkALMyHea4mw.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 357px;" width="357" /></picture></div></div></figure><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="6bc8" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">8. Now to run your tests, type the below command in your VS terminal window as</p><pre class="ue uf ug uh ui uj uk ul bo um ba bj" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="un uo pb uk b bf up uq l ur us" data-selectable-paragraph="" id="5961" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">npx cypress <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">open</span></span></pre><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="d610" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">The above command will open the Cypress tool, which help you to execute your tests.</p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="5520" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;"><span class="ti jo" style="box-sizing: inherit; font-weight: 700;">Hope you enjoyed the content, follow me for more like this, and please don’t forget to like it. Happy programming.</span></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-4849294297794699282024-03-20T15:45:00.002+05:302024-03-20T15:47:55.881+05:30“Infinite redirection — iframe-request-id” issue with Azure AD SSO login issue in cypress<p> <span style="background-color: white; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">Recently I chose Cypress as E2E testing tool after evaluating some other open-source tools for my web application project. All was good by theory until I started the test scripting and encountered the error “Infinite redirection — iframe-request-id” with Azure SSO login, it took me a day with a lot of reading to figure out the workable solution which I’ll explain down here.</span></p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="ce25" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">In my case, the scenario was, that I had a test AD user for which MFA was disabled and needed to the scenario for user from login with Azure AD SSO to lending to my web application.</p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="6934" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">When I started with cy.visit(‘www.myapp.com’) for which Azure AD SSO was configured to auto rediect to the Microsoft <a class="af la" href="https://login.microsoftonline.com/" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://login.microsoftonline.com</a> page, ended up with mentioned error. What was actually happening here is, the <a class="af la" href="https://login.microsoftonline.com/" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://login.microsoftonline.com</a> url was getting suffixed with iframe-request-id indefinite times and url was getting too long. While searching through the Google I came to know the issue was even discussed in cypress github forum: <a class="af la" href="https://github.com/cypress-io/cypress/issues/7619" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://github.com/cypress-io/cypress/issues/7619</a></p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="6bb7" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">I also got recommendations from my colleague or even google to bypass the login step by configuring the users for auto login but that was not solving my need neither I try it.</p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="560c" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">Surprisingly, reading more patiently I found the solution which was very easy and quick. The solution is to configure <span class="ti jo" style="box-sizing: inherit; font-weight: 700;">experimentalSessionAndOrigin and </span>experimentalModifyObstructiveThirdPartyCode variables to true in your cypress.config.js file as</p><pre class="ue uf ug uh ui uj uk ul bo um ba bj" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="un uo pb uk b bf up uq l ur us" data-selectable-paragraph="" id="b87c" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">module.exports = defineConfig(<span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> viewportWidth<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">1920</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> viewportHeight<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">1080</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> defaultCommandTimeout<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">20000</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> chromeWebSecurity<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">false</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> fixturesFolder<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">false</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> video<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> e2e<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> projectId<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"mywebapp"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> hideXHRInCommandLog<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> experimentalSessionAndOrigin<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> experimentalModifyObstructiveThirdPartyCode <span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> setupNodeEvents<span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> specPattern<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"**/*.feature"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> excludeSpecPattern<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-punctuation" style="box-sizing: inherit;">[</span><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"*.js"</span><span class="hljs-punctuation" style="box-sizing: inherit;">]</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> integration<span class="hljs-punctuation" style="box-sizing: inherit;">:</span><span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> experimentalSessionAndOrigin<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> experimentalModifyObstructiveThirdPartyCode <span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> specPattern<span class="hljs-punctuation" style="box-sizing: inherit;">:</span><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"**/*.spec.js"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span> <br style="box-sizing: inherit;" /> projectId<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"mywebapp"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span>);</span></pre><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="caf9" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">and next step, do the setting to run your tests always in incognito mode so the cached ad token will not be picked and the test workflow will execute as expected.<br style="box-sizing: inherit;" /><span class="ti jo" style="box-sizing: inherit; font-weight: 700;">on(“before:browser:launch”, (browser = {}, launchOptions) => {<br style="box-sizing: inherit;" />if (browser.family === ‘chromium’ && browser.name !== ‘electron’) {<br style="box-sizing: inherit;" />launchOptions.args.push(“ — incognito”);<br style="box-sizing: inherit;" />return launchOptions;<br style="box-sizing: inherit;" />}</span></p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="3523" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;"><span class="ti jo" style="box-sizing: inherit; font-weight: 700;">if (browser.name === ‘electron’) {<br style="box-sizing: inherit;" />launchOptions.preferences.incognito = true;<br style="box-sizing: inherit;" />return launchOptions;<br style="box-sizing: inherit;" />}</span></p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="44aa" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;"><span class="ti jo" style="box-sizing: inherit; font-weight: 700;">});</span></p><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="7c80" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">Here is the complete <span class="ti jo" style="box-sizing: inherit; font-weight: 700;">cypress.config.js</span> file</p><pre class="ue uf ug uh ui uj uk ul bo um ba bj" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="un uo pb uk b bf up uq l ur us" data-selectable-paragraph="" id="0325" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">const <span class="hljs-punctuation" style="box-sizing: inherit;">{</span> defineConfig <span class="hljs-punctuation" style="box-sizing: inherit;">}</span> = require(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"cypress"</span>);<br style="box-sizing: inherit;" />const cucumber = require('cypress-cucumber-preprocessor').default<br style="box-sizing: inherit;" />const createBundler = require(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"@bahmutov/cypress-esbuild-preprocessor"</span>);<br style="box-sizing: inherit;" />const preprocessor = require(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"@badeball/cypress-cucumber-preprocessor"</span>);<br style="box-sizing: inherit;" />const createEsbuildPlugin = require(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"@badeball/cypress-cucumber-preprocessor/esbuild"</span>);<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" />const setupNodeEvents = async (on<span class="hljs-punctuation" style="box-sizing: inherit;">,</span> config) => <span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> on(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"before:browser:launch"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span> (browser = <span class="hljs-punctuation" style="box-sizing: inherit;">{</span><span class="hljs-punctuation" style="box-sizing: inherit;">}</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span> launchOptions) => <span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> if (browser.family === 'chromium' && browser.name !== 'electron') <span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> launchOptions.args.push(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"--incognito"</span>);<br style="box-sizing: inherit;" /> return launchOptions;<br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> if (browser.name === 'electron') <span class="hljs-punctuation" style="box-sizing: inherit;">{</span> <br style="box-sizing: inherit;" /> launchOptions.preferences.incognito = <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span>;<br style="box-sizing: inherit;" /> return launchOptions;<br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span>);<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> await preprocessor.addCucumberPreprocessorPlugin(on<span class="hljs-punctuation" style="box-sizing: inherit;">,</span> config);<br style="box-sizing: inherit;" /> on(<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"file:preprocessor"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> createBundler(<span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> plugins<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-punctuation" style="box-sizing: inherit;">[</span>createEsbuildPlugin.default(config)<span class="hljs-punctuation" style="box-sizing: inherit;">]</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span>)<span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> );<br style="box-sizing: inherit;" /> return config;<br style="box-sizing: inherit;" /><span class="hljs-punctuation" style="box-sizing: inherit;">}</span>;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" />module.exports = defineConfig(<span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> viewportWidth<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">1920</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> viewportHeight<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">1080</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> defaultCommandTimeout<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">20000</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> chromeWebSecurity<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">false</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> fixturesFolder<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">false</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> video<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> e2e<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> projectId<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"mywebapp"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> hideXHRInCommandLog<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> experimentalSessionAndOrigin<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> experimentalModifyObstructiveThirdPartyCode <span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> setupNodeEvents<span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> specPattern<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"**/*.feature"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> excludeSpecPattern<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-punctuation" style="box-sizing: inherit;">[</span><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"*.js"</span><span class="hljs-punctuation" style="box-sizing: inherit;">]</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> integration<span class="hljs-punctuation" style="box-sizing: inherit;">:</span><span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> experimentalSessionAndOrigin<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> experimentalModifyObstructiveThirdPartyCode <span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> specPattern<span class="hljs-punctuation" style="box-sizing: inherit;">:</span><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"**/*.spec.js"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span> <br style="box-sizing: inherit;" /> projectId<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"mywebapp"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span>);</span></pre><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="7447" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;">and here is my test script:</p><pre class="ue uf ug uh ui uj uk ul bo um ba bj" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="un uo pb uk b bf up uq l ur us" data-selectable-paragraph="" id="b302" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-selector-tag" style="box-sizing: inherit; color: #aa0d91;">import</span> { <span class="hljs-selector-tag" style="box-sizing: inherit; color: #aa0d91;">Given</span>, <span class="hljs-selector-tag" style="box-sizing: inherit; color: #aa0d91;">Then</span>, <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">When</span> } from <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"@badeball/cypress-cucumber-preprocessor"</span>;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">Given</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"User logs in through azure ad sso"</span>, () => {<br style="box-sizing: inherit;" /> try{<br style="box-sizing: inherit;" /> cy.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">visit</span>(Cypress.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">env</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'web_url'</span>));<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> cy.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">origin</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'login.microsoftonline.com'</span>, () => {<br style="box-sizing: inherit;" /> cy.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">get</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'input[type="email"]'</span>).<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">type</span>(Cypress.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">env</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'username'</span>));<br style="box-sizing: inherit;" /> cy.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">get</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'input[type="submit"]'</span>).<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">click</span>();<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> cy.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">get</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'input[type="password"]'</span>).<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">type</span>(Cypress.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">env</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'password'</span>), {<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">log</span>: false,<br style="box-sizing: inherit;" /> });<br style="box-sizing: inherit;" /> cy.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">get</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'input[type="submit"]'</span>).<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">click</span>();<br style="box-sizing: inherit;" /> cy.<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">get</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'#idBtn_Back'</span>).<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">click</span>();<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> });<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">catch</span>(exception){<br style="box-sizing: inherit;" /> throw new <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">SyntaxError</span>( <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Failed to login"</span>,);<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />});</span></pre><p class="pw-post-body-paragraph tg th pb ti b tj tk tl tm tn to tp tq tr ts tt tu tv tw tx ty tz ua ub uc ud jm bj" data-selectable-paragraph="" id="ee55" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2.14em 0px -0.46em; word-break: break-word;"><span class="ti jo" style="box-sizing: inherit; font-weight: 700;">Hope you enjoyed the content and it helped you if you are coming across the same issue, follow me for more like this, and please don’t forget to like it. Happy programming.</span></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-71352760942325692972023-11-15T14:57:00.009+05:302023-11-16T09:48:35.902+05:30Understanding Watchers in Vue<p> <span face="source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif" style="background-color: white; color: #242424; font-size: 20px; letter-spacing: -0.003em;">One of my favorite features for frontend development and it is fun to use but tricky and deadly too if not used properly.</span></p><blockquote class="yb yc yd" style="background-color: white; box-shadow: rgb(36, 36, 36) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="wk wl ye lz b wm wn wo wp wq wr ws wt yf wu wv ww yg wx wy wz yh xa xb xc xd gw bq" data-selectable-paragraph="" id="b523" style="box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Watchers are functions to trigger a callback whenever the reactive state changes for the data property. We use it when certain action needs to be performed on data change for a property.</p></blockquote><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="572b" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="lz gn" style="box-sizing: inherit; font-weight: 700;">Watch for data property</span></p><pre class="xf xg xh xi xj xq xr xs jx xt bi bq" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="xu xv sl xr b bm xw xx s xy xz" data-selectable-paragraph="" id="e58c" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><template><br style="box-sizing: inherit;" /> <span class="hljs-undefined" style="box-sizing: inherit;"><span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">div</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">class</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"about"</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">input</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"input1"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">v-model</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"fullName"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">type</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"text"</span> /></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">div</span>></span></span><br style="box-sizing: inherit;" /></template><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-undefined" style="box-sizing: inherit;"><span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">script</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">lang</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"ts"</span>></span><span class="hljs-undefined" style="box-sizing: inherit;"><br style="box-sizing: inherit;" />import { reactive, computed, onMounted, ref } from 'vue'<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" />export default {<br style="box-sizing: inherit;" /> name: 'aboutViewComponent',<br style="box-sizing: inherit;" /> components: {},<br style="box-sizing: inherit;" /> props: {},<br style="box-sizing: inherit;" /> data() {<br style="box-sizing: inherit;" /> return {<br style="box-sizing: inherit;" /> fullName: 'John Cena'<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> watch: {<br style="box-sizing: inherit;" /> fullName: {<br style="box-sizing: inherit;" /> handler: function (newValue, oldValue) {<br style="box-sizing: inherit;" /> alert(newValue);<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /></span><span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">script</span>></span></span></span></pre><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="563b" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In the above code, when the value changes for the data property ‘fullName’ the watch trigger will be triggered and it will show the new value in alert. it is so simple but the fun starts from here.</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="6c92" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="lz gn" style="box-sizing: inherit; font-weight: 700;">Watch with a complex type of data property</span>.</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="1e15" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Let’s replace the data property ‘fullName’ with a complex type ‘author’ that has a name property and then we need to watch the change when the author’s name changes.</p><pre class="xf xg xh xi xj xq xr xs jx xt bi bq" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="xu xv sl xr b bm xw xx s xy xz" data-selectable-paragraph="" id="b736" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">template</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">div</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">class</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"about"</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">input</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"input"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">v-model</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"author.name"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">type</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"text"</span> /></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">button</span> @<span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">click</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"onSubmit"</span>></span>Submit<span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">button</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /><span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">template</span>></span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">script</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">lang</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"ts"</span>></span><span class="hljs-undefined" style="box-sizing: inherit;"><br style="box-sizing: inherit;" />import { reactive, computed, onMounted, ref } from 'vue'<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" />export default {<br style="box-sizing: inherit;" /> name: 'aboutViewComponent',<br style="box-sizing: inherit;" /> components: {},<br style="box-sizing: inherit;" /> props: {},<br style="box-sizing: inherit;" /> data() {<br style="box-sizing: inherit;" /> return {<br style="box-sizing: inherit;" /> author: {<br style="box-sizing: inherit;" /> name: 'John Doe',<br style="box-sizing: inherit;" /> books: [<br style="box-sizing: inherit;" /> 'Vue 2 - Advanced Guide',<br style="box-sizing: inherit;" /> 'Vue 3 - Basic Guide',<br style="box-sizing: inherit;" /> 'Vue 4 - The Mystery'<br style="box-sizing: inherit;" /> ]<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> watch: {<br style="box-sizing: inherit;" /> author: {<br style="box-sizing: inherit;" /> handler: function (newValue, oldValue) {<br style="box-sizing: inherit;" /> alert(newValue.name);<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> methods: {<br style="box-sizing: inherit;" /> onSubmit() {<br style="box-sizing: inherit;" /> this.$data.author = {<br style="box-sizing: inherit;" /> name: 'John Cena',<br style="box-sizing: inherit;" /> books: [<br style="box-sizing: inherit;" /> 'Vue 2 - Advanced Guide',<br style="box-sizing: inherit;" /> 'Vue 3 - Basic Guide',<br style="box-sizing: inherit;" /> 'Vue 4 - The Mystery',<br style="box-sizing: inherit;" /> ]<br style="box-sizing: inherit;" /> };<br style="box-sizing: inherit;" /> console.log("Submit is fired");<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /></span><span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">script</span>></span></span></pre><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="9678" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">But here, the watch handler on ‘author’ doesn’t work as expected when you change the author name for text input,<span class="lz gn" style="box-sizing: inherit; font-weight: 700;"><em class="ye" style="box-sizing: inherit;"> though the watch implicitly creates a deep watcher and the callback should trigger for all nested mutations for ‘author’.</em></span><br style="box-sizing: inherit;" />At the same time, the watch handler on ‘author’ triggered if you click on the submit button and the difference is, on submit we are changing the whole object of the author.</p><blockquote class="yb yc yd" style="background-color: white; box-shadow: rgb(36, 36, 36) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="wk wl ye lz b wm wn wo wp wq wr ws wt yf wu wv ww yg wx wy wz yh xa xb xc xd gw bq" data-selectable-paragraph="" id="310d" style="box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">N<span class="lz gn" style="box-sizing: inherit; font-weight: 700;">ote: The watcher on getters returns a reactive object will be triggered only when the getter returns a different object.</span></p></blockquote><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="fbb8" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="lz gn" style="box-sizing: inherit; font-weight: 700;">Deep watchers</span></p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="82f8" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">But we need to get the watcher triggers whenever any property of the author changes, and to do this we need to explicitly force the deep watcher by using the <span class="lz gn" style="box-sizing: inherit; font-weight: 700;">deep </span>option:</p><pre class="xf xg xh xi xj xq xr xs jx xt bi bq" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="xu xv sl xr b bm xw xx s xy xz" data-selectable-paragraph="" id="8545" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">watch:</span> {<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">author:</span> {<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">deep:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">handler:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">function</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">(newValue</span>, <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">oldValue)</span> {<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">alert(newValue.name);</span><br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">,</span></span></pre><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="1ef6" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">After this modification, any changes on the author either value change for nested property or entire object change, the watch will trigger the handler as per the code and we will see the alert popup.</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="0b48" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="lz gn" style="box-sizing: inherit; font-weight: 700;">Problem with Deep watch</span></p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="b3ed" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Deep watch requires traversing all nested properties in the watched object and can be expensive when used on large data structures. Use it only when necessary and beware of the performance implications.</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="0243" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">This is the part where most of the developers make mistakes.</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="1625" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="lz gn" style="box-sizing: inherit; font-weight: 700;">Problem Statement:</span> In a scenario, if I need to make a REST API call or emit an event to notify the change to other components only when the author name changes but should ignore it if otherwise.</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="cf77" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="lz gn" style="box-sizing: inherit; font-weight: 700;">Solution 1</span>: This is where newValue and oldValue help, so we just need to put a check to compare the value before acting on this handler call. i.e.</p><pre class="xf xg xh xi xj xq xr xs jx xt bi bq" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="xu xv sl xr b bm xw xx s xy xz" data-selectable-paragraph="" id="5582" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">watch:</span> {<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">author:</span> {<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">deep:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">handler:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">function</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">(newValue</span>, <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">oldValue)</span> {<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">if(newValue.name</span> <span class="hljs-type" style="box-sizing: inherit; color: #5c2699;">!==</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">oldValue.name)</span>{<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">alert(newValue.name);</span><br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">,</span></span></pre><p class="pw-post-body-paragraph lg lh fr li b lj lk ll lm ln lo lp lq lr ls lt lu lv lw lx ly lz ma mb mc md fk bj" data-selectable-paragraph="" id="3c25" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="li fs" style="box-sizing: inherit; font-weight: 700;">Solution 2</span>: Create a computed method to return the author name and put a watch on the computed method.</p><pre class="ml mm mn mo mp mq mr ms bo mt ba bj" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="mu mv fr mr b bf mw mx l my mz" data-selectable-paragraph="" id="3331" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">computed</span>: {<br style="box-sizing: inherit;" /> <span class="hljs-title.function" style="box-sizing: inherit;">autherName</span>(){<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">return</span> <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">author</span>.<span class="hljs-property" style="box-sizing: inherit;">name</span>;<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /><span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">watch</span>: {<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">autherName</span>:{<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">handler</span>: <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">function</span> (<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">newValue, oldValue</span>) {<br style="box-sizing: inherit;" /> <span class="hljs-title.function" style="box-sizing: inherit;">alert</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"computed:"</span>+ newValue);<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },</span></pre><p class="pw-post-body-paragraph lg lh fr li b lj lk ll lm ln lo lp lq lr ls lt lu lv lw lx ly lz ma mb mc md fk bj" data-selectable-paragraph="" id="2c1a" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">I would prefer <span class="li fs" style="box-sizing: inherit; font-weight: 700;"><em class="mh" style="box-sizing: inherit;">Solution 2 </em></span>as this avoids traversing through all nested properties.</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="c497" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="lz gn" style="box-sizing: inherit; font-weight: 700;">Eager watchers</span></p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="76b4" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><code class="cn ahq ahr ahs xr b" style="background-color: #f2f2f2; box-sizing: inherit; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; font-size: 15px; padding: 2px 4px;">watch</code> is lazy by default: the callback won't be called until the watched source has changed.</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="dc65" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In a case, where we want to make the API call to fetch some initial data and then re-fetch whenever the author name changes, we can use the <span class="lz gn" style="box-sizing: inherit; font-weight: 700;">immediate: true</span> option to force the watcher’s callback immediately with author initialization.</p><pre class="xf xg xh xi xj xq xr xs jx xt bi bq" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="xu xv sl xr b bm xw xx s xy xz" data-selectable-paragraph="" id="a0e0" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">watch:</span> {<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">author:</span> {<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">deep:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">immediate:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">handler:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">function</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">(newValue</span>, <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">oldValue)</span> {<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">if(newValue.name</span> <span class="hljs-type" style="box-sizing: inherit; color: #5c2699;">!==</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">oldValue.name)</span>{<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">alert(newValue.name);</span><br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">,</span></span></pre><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="2a26" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In this case, the handler will be executed when the page loads the first time.</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="7ec8" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="lz gn" style="box-sizing: inherit; font-weight: 700;">Watchers on Props and computed functions</span></p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="26de" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">You can also put a watch on props and computed methods. Putting a watch on computed fields becomes very useful when you want to watch the change on mapGetters which directly you cannot but you can combine it with the computed method.</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="683a" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Here is the complete code that I use as an example above:</p><pre class="xf xg xh xi xj xq xr xs jx xt bi bq" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="xu xv sl xr b bm xw xx s xy xz" data-selectable-paragraph="" id="291a" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">template</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">div</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">class</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"about"</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">input</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"input1"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">v-model</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"fullName"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">type</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"text"</span> /></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">input</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"input2"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">v-model</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"author.name"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">type</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"text"</span> /></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">button</span> @<span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">click</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"onSubmit"</span>></span>Submit<span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">button</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /><span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">template</span>></span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">script</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">lang</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"ts"</span>></span><span class="hljs-undefined" style="box-sizing: inherit;"><br style="box-sizing: inherit;" />import { reactive, computed, onMounted, ref } from 'vue'<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" />export default {<br style="box-sizing: inherit;" /> name: 'aboutViewComponent',<br style="box-sizing: inherit;" /> components: {},<br style="box-sizing: inherit;" /> props: {<br style="box-sizing: inherit;" /> city:{<br style="box-sizing: inherit;" /> type: String<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> data() {<br style="box-sizing: inherit;" /> return {<br style="box-sizing: inherit;" /> author: {<br style="box-sizing: inherit;" /> name: 'John Doe',<br style="box-sizing: inherit;" /> books: [<br style="box-sizing: inherit;" /> 'Vue 2 - Advanced Guide',<br style="box-sizing: inherit;" /> 'Vue 3 - Basic Guide',<br style="box-sizing: inherit;" /> 'Vue 4 - The Mystery'<br style="box-sizing: inherit;" /> ]<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> fullName: 'John Cena'<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> watch: {<br style="box-sizing: inherit;" /> author: {<br style="box-sizing: inherit;" /> deep: true,<br style="box-sizing: inherit;" /> immediate: true,<br style="box-sizing: inherit;" /> handler: function (newValue, oldValue) {<br style="box-sizing: inherit;" /> alert(newValue.name);<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> fullName: {<br style="box-sizing: inherit;" /> handler: function (newValue, oldValue) {<br style="box-sizing: inherit;" /> alert(newValue);<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> city: {<br style="box-sizing: inherit;" /> handler: function (newValue, oldValue) {<br style="box-sizing: inherit;" /> alert(newValue);<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> publishedBooksMessage: {<br style="box-sizing: inherit;" /> immediate: true,<br style="box-sizing: inherit;" /> handler: function (newValue, oldValue) {<br style="box-sizing: inherit;" /> alert(newValue);<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> methods: {<br style="box-sizing: inherit;" /> onSubmit() {<br style="box-sizing: inherit;" /> this.$data.author.books.push("Vue 3 - The Watcher");<br style="box-sizing: inherit;" /> this.$data.author = {<br style="box-sizing: inherit;" /> name: 'John Cena',<br style="box-sizing: inherit;" /> books: [<br style="box-sizing: inherit;" /> 'Vue 2 - Advanced Guide',<br style="box-sizing: inherit;" /> 'Vue 3 - Basic Guide',<br style="box-sizing: inherit;" /> 'Vue 4 - The Mystery',<br style="box-sizing: inherit;" /> ]<br style="box-sizing: inherit;" /> };<br style="box-sizing: inherit;" /> console.log("Submit is fired");<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> setup(props, { attrs }) {<br style="box-sizing: inherit;" /> console.log(`the component is now setup.`)<br style="box-sizing: inherit;" /> console.log(attrs)<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> computed: {<br style="box-sizing: inherit;" /> publishedBooksMessage() {<br style="box-sizing: inherit;" /> return this.author.books.length > 0 ? 'Yes' : 'No'<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> mounted() {<br style="box-sizing: inherit;" /> console.log(`the component is now mounted.`)<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /></span><span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">script</span>></span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">style</span>></span><span class="hljs-undefined" style="box-sizing: inherit;"><br style="box-sizing: inherit;" />@media (min-width: 1024px) {<br style="box-sizing: inherit;" /> .about {<br style="box-sizing: inherit;" /> min-height: 100vh;<br style="box-sizing: inherit;" /> display: flex;<br style="box-sizing: inherit;" /> align-items: center;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /></span><span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">style</span>></span></span></pre><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="16d9" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span style="color: #292929; font-weight: 700; letter-spacing: -0.06px;">Hope you enjoyed the content, follow me for more like this, and please don’t forget to LIKE it. Happy programming.</span><br style="color: #292929; letter-spacing: -0.06px;" /></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-85907715087061631182023-11-15T14:56:00.004+05:302023-11-15T14:56:23.651+05:30Use Microsoft Graph API with Azure AD Authentication in .Net Core, C#<p> <span style="background-color: white; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">Microsoft Graph is a RESTful web API that enables you to access Microsoft Cloud service resources. It allows you to access data across Microsoft 365 services i.e. emails, chats, calendars, user profiles, etc.</span></p><figure class="xf xg xh xi xj xk ki kj paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="xl xm by xn bn xo" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 680px; z-index: auto;" tabindex="0"><div class="ki kj xe" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1230px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/0*LNuqQcUX3NRlEYVR.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*LNuqQcUX3NRlEYVR.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*LNuqQcUX3NRlEYVR.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*LNuqQcUX3NRlEYVR.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*LNuqQcUX3NRlEYVR.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*LNuqQcUX3NRlEYVR.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/0*LNuqQcUX3NRlEYVR.png 1400w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/0*LNuqQcUX3NRlEYVR.png 640w, https://miro.medium.com/v2/resize:fit:720/0*LNuqQcUX3NRlEYVR.png 720w, https://miro.medium.com/v2/resize:fit:750/0*LNuqQcUX3NRlEYVR.png 750w, https://miro.medium.com/v2/resize:fit:786/0*LNuqQcUX3NRlEYVR.png 786w, https://miro.medium.com/v2/resize:fit:828/0*LNuqQcUX3NRlEYVR.png 828w, https://miro.medium.com/v2/resize:fit:1100/0*LNuqQcUX3NRlEYVR.png 1100w, https://miro.medium.com/v2/resize:fit:1400/0*LNuqQcUX3NRlEYVR.png 1400w" style="box-sizing: inherit;"></source><img alt="" class="bn vv xp c" height="348" loading="eager" role="presentation" src="https://miro.medium.com/v2/resize:fit:700/0*LNuqQcUX3NRlEYVR.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 680px;" width="700" /></picture></div></div></figure><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="c1b6" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">REST APIs are built on OData standards so can use the Odata syntax to query data through graph API with Postman or programmatically. Here in this article, we will see, how to call the Graph APIs in the .Net Core Web API project with C#.</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="8698" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">For this example, we will create an ASP.NET Core web API project and follow the below steps:</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="3cd9" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="lz gn" style="box-sizing: inherit; font-weight: 700;">Step 1:</span> <span class="lz gn" style="box-sizing: inherit; font-weight: 700;">Configure Azure AD Authentication from the Project side.</span></p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="2093" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">To configure the Azure AD authentication, we need to add a few settings in appsettings.json and the below code in Program.cs as well as a middleware to validate the Azure AD Token.</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="eb4b" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="lz gn" style="box-sizing: inherit; font-weight: 700;">appsettings.json</span></p><pre class="xf xg xh xi xj xq xr xs jx xt bi bq" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="xu xv sl xr b bm xw xx s xy xz" data-selectable-paragraph="" id="22e8" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"AzureAd"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"Domain"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"domain name"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"TenantId"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"AD Tenant ID"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"ClientId"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"AD Client Id"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"Instance"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"https://login.microsoftonline.com"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"ClientSecret"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Client secret"</span><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"GraphApi"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"BaseUrl"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"https://graph.microsoft.com/v1.0"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"Scopes"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"User.Read.All"</span><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span></span></pre><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="5fe0" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Above all values must be available in the appsettings.json otherwise Azure AD authentication and Graph API calls will fail.</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="d0de" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="lz gn" style="box-sizing: inherit; font-weight: 700;">Program.cs</span></p><pre class="xf xg xh xi xj xq xr xs jx xt bi bq" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="xu xv sl xr b bm xw xx s xy xz" data-selectable-paragraph="" id="133c" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">using</span> Microsoft.AspNetCore.Authentication.JwtBearer;<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">using</span> Microsoft.Identity.Web;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" />builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)<br style="box-sizing: inherit;" /> .AddMicrosoftIdentityWebApi(options =><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> options.TokenValidationParameters.ValidateAudience = <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">false</span>;<br style="box-sizing: inherit;" /> options.TokenValidationParameters.ValidateIssuer = <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span>;<br style="box-sizing: inherit;" /> options.TokenValidationParameters.ValidIssuers = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">string</span>[] { <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">$"https://login.microsoftonline.com/<span class="hljs-subst" style="box-sizing: inherit; color: black;">{builder.Configuration[<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"AzureAD:TenantId"</span>]}</span>/v2.0"</span> };<br style="box-sizing: inherit;" /> }, options =><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> builder.Configuration.Bind(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"AzureAd"</span>, options);<br style="box-sizing: inherit;" /> })<br style="box-sizing: inherit;" /> .EnableTokenAcquisitionToCallDownstreamApi(options =><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> builder.Configuration.Bind(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"AzureAd"</span>, options);<br style="box-sizing: inherit;" /> })<br style="box-sizing: inherit;" /> .AddMicrosoftGraph(builder.Configuration.GetSection(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"GraphApi"</span>))<br style="box-sizing: inherit;" /> .AddDistributedTokenCaches();</span></pre><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="fe98" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In the above code here, we are enabling the Authentication service to validate Azure AD Jwt auth Token and adding the Graph API support to make a call to Graph APIs using the AD Token.<br style="box-sizing: inherit;" />Nuget packages required are:</p><pre class="xf xg xh xi xj xq xr xs jx xt bi bq" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="xu xv sl xr b bm xw xx s xy xz" data-selectable-paragraph="" id="9e6b" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-type" style="box-sizing: inherit; color: #5c2699;">Microsoft</span>.<span class="hljs-type" style="box-sizing: inherit; color: #5c2699;">Graph</span><br style="box-sizing: inherit;" /><span class="hljs-type" style="box-sizing: inherit; color: #5c2699;">Microsoft</span>.<span class="hljs-type" style="box-sizing: inherit; color: #5c2699;">Identity</span>.<span class="hljs-type" style="box-sizing: inherit; color: #5c2699;">Web</span>.<span class="hljs-type" style="box-sizing: inherit; color: #5c2699;">GraphServiceClient</span> <br style="box-sizing: inherit;" /><span class="hljs-type" style="box-sizing: inherit; color: #5c2699;">Microsoft</span>.<span class="hljs-type" style="box-sizing: inherit; color: #5c2699;">AspNetCore</span>.<span class="hljs-type" style="box-sizing: inherit; color: #5c2699;">Authentication</span>.<span class="hljs-type" style="box-sizing: inherit; color: #5c2699;">AzureAD</span>.<span class="hljs-type" style="box-sizing: inherit; color: #5c2699;">UI</span> and <br style="box-sizing: inherit;" /><span class="hljs-type" style="box-sizing: inherit; color: #5c2699;">Microsoft</span>.<span class="hljs-type" style="box-sizing: inherit; color: #5c2699;">Identity</span>.<span class="hljs-type" style="box-sizing: inherit; color: #5c2699;">Web</span></span></pre><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="3649" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="lz gn" style="box-sizing: inherit; font-weight: 700;">a Middleware to validate the token, i.e. JwtTokenValidationMiddleware.cs</span></p><pre class="xf xg xh xi xj xq xr xs jx xt bi bq" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="xu xv sl xr b bm xw xx s xy xz" data-selectable-paragraph="" id="81d7" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">using</span> Microsoft.Extensions.Options;<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">using</span> Microsoft.IdentityModel.Protocols;<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">using</span> Microsoft.IdentityModel.Protocols.OpenIdConnect;<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">using</span> Microsoft.IdentityModel.Tokens;<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">using</span> System.IdentityModel.Tokens.Jwt;<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">using</span> System.Net;<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">using</span> System.Security.Claims;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">JwtTokenValidationMiddleware</span><br style="box-sizing: inherit;" />{<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">readonly</span> RequestDelegate _next;<br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">JwtTokenValidationMiddleware</span>(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">RequestDelegate next</span>)</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> _next = next;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">async</span> Task <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">Invoke</span>(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">HttpContext context</span>)</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">bool</span> isAuthenticated = <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">false</span>;<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">var</span> token = context.Request.Headers[<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Authorization"</span>].FirstOrDefault()?.Split(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">" "</span>).Last();<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">var</span> AzureAdInstance = <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"value from appsettings.json"</span>;<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">var</span> AzureAdTenantId = <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"value from appsettings.json"</span>;<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">var</span> AzureAdClientId = <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"value from appsettings.json"</span>;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span> (token != <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">null</span>)<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//set the value for AzureAdTenantId, AzureAdClientId and AzureAdInstance as per your appsettings.json</span><br style="box-sizing: inherit;" /> <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">string</span> issuer = <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">$"<span class="hljs-subst" style="box-sizing: inherit; color: black;">{AzureAdInstance}</span>/<span class="hljs-subst" style="box-sizing: inherit; color: black;">{AzureAdTenantId}</span>/v2.0"</span>;<br style="box-sizing: inherit;" /> <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">string</span> stsDiscoveryEndpoint = <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">$"<span class="hljs-subst" style="box-sizing: inherit; color: black;">{AzureAdInstance}</span>/<span class="hljs-subst" style="box-sizing: inherit; color: black;">{AzureAdTenantId}</span>/v2.0/.well-known/openid-configuration"</span>;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">try</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">var</span> configManager = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> ConfigurationManager<OpenIdConnectConfiguration>(stsDiscoveryEndpoint, <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> OpenIdConnectConfigurationRetriever());<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">var</span> config = configManager.GetConfigurationAsync().Result;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">var</span> tokenHandler = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> JwtSecurityTokenHandler();<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">var</span> validationParameters = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> TokenValidationParameters<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> ValidAudience = {AzureAdClientId},<br style="box-sizing: inherit;" /> ValidIssuer = issuer,<br style="box-sizing: inherit;" /> IssuerSigningKeys = config.SigningKeys,<br style="box-sizing: inherit;" /> ValidateLifetime = <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span>,<br style="box-sizing: inherit;" /> };<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">var</span> claim = tokenHandler.ValidateToken(token, validationParameters, <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">out</span> _);<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span>(claim != <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">null</span>)<br style="box-sizing: inherit;" /> isAuthenticated = <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span>;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">catch</span> (Exception ex)<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> isAuthenticated = <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">false</span>;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span>(isAuthenticated)<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> _next(context);<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">else</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> context.Response.Clear();<br style="box-sizing: inherit;" /> context.Response.StatusCode = (<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">int</span>)HttpStatusCode.Unauthorized;<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> context.Response.WriteAsync(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Unauthorized"</span>);<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">return</span>; <br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="d3ac" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In the code in Program.cs, you can configure as many TokenValidationParameters to validate the token accordingly as per your need.<br style="box-sizing: inherit;" />With this, we are done with Azure AD authentication from the code side.</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="0ef6" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Note: Don’t forget to use the JwtTokenValidationMiddleware in the Configure method of startup.cs.</p><pre class="xf xg xh xi xj xq xr xs jx xt bi bq" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="xu xv sl xr b bm xw xx s xy xz" data-selectable-paragraph="" id="4cd8" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"> app.UseMiddleware<JwtTokenValidationMiddleware>();</span></pre><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="c16d" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="lz gn" style="box-sizing: inherit; font-weight: 700;">Step 2: Add the required resource scope permission for Graph APIs</span></p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="ea49" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Your Enterprise Application, which is used to generate the Azure AD token must have Microsoft Graph API permission w.r.t to Microsoft 365 resources you need to access.</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="f233" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">For example, if you need to access the user’s profile like name, email, profile pic, org hierarchy etc then you would need User.Read.All scope permission assigned for the application.</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="c2dc" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Go to Azure AD and search your application and navigate to API Permissions add the required permissions for Graph API. In this example, I’m adding User.Read.All delegated permission to read the user’s profile.</p><figure class="xf xg xh xi xj xk ki kj paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="xl xm by xn bn xo" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 680px; z-index: auto;" tabindex="0"><div class="ki kj ya" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1295px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*Hzv8oQAMf8Uqro7et8SySQ.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*Hzv8oQAMf8Uqro7et8SySQ.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*Hzv8oQAMf8Uqro7et8SySQ.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*Hzv8oQAMf8Uqro7et8SySQ.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*Hzv8oQAMf8Uqro7et8SySQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*Hzv8oQAMf8Uqro7et8SySQ.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*Hzv8oQAMf8Uqro7et8SySQ.png 1400w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/1*Hzv8oQAMf8Uqro7et8SySQ.png 640w, https://miro.medium.com/v2/resize:fit:720/1*Hzv8oQAMf8Uqro7et8SySQ.png 720w, https://miro.medium.com/v2/resize:fit:750/1*Hzv8oQAMf8Uqro7et8SySQ.png 750w, https://miro.medium.com/v2/resize:fit:786/1*Hzv8oQAMf8Uqro7et8SySQ.png 786w, https://miro.medium.com/v2/resize:fit:828/1*Hzv8oQAMf8Uqro7et8SySQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*Hzv8oQAMf8Uqro7et8SySQ.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*Hzv8oQAMf8Uqro7et8SySQ.png 1400w" style="box-sizing: inherit;"></source><img alt="" class="bn vv xp c" height="347" loading="lazy" role="presentation" src="https://miro.medium.com/v2/resize:fit:700/1*Hzv8oQAMf8Uqro7et8SySQ.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 680px;" width="700" /></picture></div></div></figure><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="1035" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Note: You might need admin consent for your required scopes.</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="b5f9" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">With this step, we are done with Settings.</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="8418" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Step 3: Adding a service class for User profiles data fetching using Graph API. .i.e. UserProfileService.cs</p><pre class="xf xg xh xi xj xq xr xs jx xt bi bq" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="xu xv sl xr b bm xw xx s xy xz" data-selectable-paragraph="" id="27e6" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">using</span> Microsoft.Graph;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">namespace</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">MyApplication</span><br style="box-sizing: inherit;" />{<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">UserInfo</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">string</span> Name { <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">get</span>; <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">set</span>; }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">string</span> EmailId { <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">get</span>; <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">set</span>; }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">string</span> ProfilePic { <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">get</span>; <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">set</span>; }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">UserProfileService</span>: <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">IUserProfileService</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">private</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">readonly</span> GraphServiceClient _graphServiceClient;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">ADUserRepository</span>(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">GraphServiceClient graphServiceClient</span>)</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> _graphServiceClient = graphServiceClient;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">async</span> Task<UserInfo> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">GetUserInformation</span>(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;"><span class="hljs-built_in" style="box-sizing: inherit;">string</span> userId</span>)</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">var</span> result = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> _graphServiceClient.Users[userId].GetAsync();<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">var</span> user = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> UserInfo<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> EmailId = result.Mail,<br style="box-sizing: inherit;" /> Name = result.DisplayName,<br style="box-sizing: inherit;" /> ProfilePic =<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">""</span><br style="box-sizing: inherit;" /> };<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">try</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">var</span> photoresponse = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> _graphServiceClient.Users[userId].Photos[<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"48x48"</span>].Content.GetAsync();<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span> (photoresponse != <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">null</span>)<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> MemoryStream ms = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> MemoryStream();<br style="box-sizing: inherit;" /> photoresponse.CopyTo(ms);<br style="box-sizing: inherit;" /> ms.Position = <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">0</span>;<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">var</span> fileBytes = ms.ToArray();<br style="box-sizing: inherit;" /> user.ProfilePic= <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">$"data:image/png;base64,<span class="hljs-subst" style="box-sizing: inherit; color: black;">{Convert.ToBase64String(fileBytes)}</span>"</span>;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">catch</span> (Exception ex)<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//log your exception</span><br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">return</span> user;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="b47b" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">and add this service to the Service collection in Program.cs as</p><pre class="xf xg xh xi xj xq xr xs jx xt bi bq" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="xu xv sl xr b bm xw xx s xy xz" data-selectable-paragraph="" id="218b" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">builder.Services.AddScoped<IUserProfileService, UserProfileService>();</span></pre><blockquote class="yb yc yd" style="background-color: white; box-shadow: rgb(36, 36, 36) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="wk wl ye lz b wm wn wo wp wq wr ws wt yf wu wv ww yg wx wy wz yh xa xb xc xd gw bq" data-selectable-paragraph="" id="bfad" style="box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Note: Graph Service client can’t be used with singleton instance hence you have to add your service to IServiceCollection as scoped service.</p></blockquote><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="994b" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">We need GraphServiceClient to call the Graph APIs which requires credentials and scopes but with the above approach, it is simple as the GraphServiceClient instance is getting created by Microsoft Dependency service collection and getting injected at run time.</p><p class="pw-post-body-paragraph wk wl sl lz b wm wn wo wp wq wr ws wt lj wu wv ww lo wx wy wz lt xa xb xc xd gw bq" data-selectable-paragraph="" id="994b" style="background-color: white; box-sizing: inherit; color: #242424; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span style="color: #292929; font-weight: 700; letter-spacing: -0.06px;">Hope you enjoyed the content, follow me for more like this, and please don’t forget to LIKE it. Happy programming.</span><br style="color: #292929; letter-spacing: -0.06px;" /></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-47473693733765165382023-06-11T17:27:00.005+05:302023-06-17T09:57:50.798+05:30Build your own web Chat App using Azure Web PubSub Service<p> <span face="source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif" style="background-color: white; color: #292929; font-size: 20px; letter-spacing: -0.003em;">Azure Web Pub Sub Service is an Azure-managed real-time messaging service built on a publish-subscribe pattern using WebSocket. It allows publishing content updates between servers and connected clients in real-time. It has built-in support for large-scale client connection and highly available architectures.</span></p><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="b7a6" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Do not confuse or mix it with Azure’s SignalR service though both serve the same purpose to help customers build real-time web applications easily with large scale and high availability and enable customers to focus on their business logic instead of managing the messaging infrastructure. In general, you may choose Azure SignalR Service if you already use the SignalR library to build real-time applications. Instead, if you’re looking for a generic solution to build real-time applications based on WebSocket and publish-subscribe patterns, you may choose Azure Web PubSub service. The Azure Web PubSub service is not a replacement for Azure SignalR Service.</p><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="d527" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Here we see an example, How to build a quick chat app among clients. The technology we use in the example is as:<br style="box-sizing: inherit;" /><em class="lu" style="box-sizing: inherit;">1. A backend Service, NodeJs and<br style="box-sizing: inherit;" />2. A client application, simple HTML/Angular.Vuejs application. In my case, I’m using Vuejs here.</em></p><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="4a17" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Before we proceed with examples, We need to create the Azure Web Pub Sub Service. Login to your Azure Portal and search for “Web PubSub Service” and create the service. For this example, we create a Free instance.</p><figure class="ly lz ma mb mc md lv lw paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="me mf eb mg bg mh" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 680px; z-index: auto;" tabindex="0"><div class="lv lw lx" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1891px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*mINGt35s7AOpJcGJ1Eb8Cw.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*mINGt35s7AOpJcGJ1Eb8Cw.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*mINGt35s7AOpJcGJ1Eb8Cw.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*mINGt35s7AOpJcGJ1Eb8Cw.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*mINGt35s7AOpJcGJ1Eb8Cw.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*mINGt35s7AOpJcGJ1Eb8Cw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*mINGt35s7AOpJcGJ1Eb8Cw.png 1400w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/1*mINGt35s7AOpJcGJ1Eb8Cw.png 640w, https://miro.medium.com/v2/resize:fit:720/1*mINGt35s7AOpJcGJ1Eb8Cw.png 720w, https://miro.medium.com/v2/resize:fit:750/1*mINGt35s7AOpJcGJ1Eb8Cw.png 750w, https://miro.medium.com/v2/resize:fit:786/1*mINGt35s7AOpJcGJ1Eb8Cw.png 786w, https://miro.medium.com/v2/resize:fit:828/1*mINGt35s7AOpJcGJ1Eb8Cw.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*mINGt35s7AOpJcGJ1Eb8Cw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*mINGt35s7AOpJcGJ1Eb8Cw.png 1400w" style="box-sizing: inherit;"></source><img alt="" class="bg mi mj c" height="273" loading="eager" role="presentation" src="https://miro.medium.com/v2/resize:fit:700/1*mINGt35s7AOpJcGJ1Eb8Cw.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 680px;" width="700" /></picture></div></div></figure><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="33b9" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Our service is created. Let's understand a few basic important concepts of Azure web pubsub service before we move into the code part.</p><ol style="background-color: white; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; list-style: none none; margin: 0px; padding: 0px;"><li class="kw kx fo ky b kz la lb lc ld le lf lg mk li lj lk ml lm ln lo mm lq lr ls lt mn mo mp bj" data-selectable-paragraph="" id="63e3" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; letter-spacing: -0.003em; line-height: 32px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 2em; padding-left: 0px;">Connection: A connection here is a client or a client connection that represents an individual WebSocket connection connected to the Web PubSub service.</li><li class="kw kx fo ky b kz mq lb lc ld mr lf lg mk ms lj lk ml mt ln lo mm mu lr ls lt mn mo mp bj" data-selectable-paragraph="" id="b02f" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; letter-spacing: -0.003em; line-height: 32px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.05em; padding-left: 0px;">Hub: It is a logical concept for a set of client connections. Usually, you use one hub for one purpose, for example, a <em class="lu" style="box-sizing: inherit;">chat</em> hub, or a <em class="lu" style="box-sizing: inherit;">notification</em> hub. When a client connection connects, it connects to a hub, and during its lifetime it belongs to that hub. Once a client connection connects to the hub, the hub exists. Different applications can share one Azure Web PubSub service by using different hub names.<br style="box-sizing: inherit;" />Note: a default hub with the name “Hub” has been created already which we will be using for this example here.</li><li class="kw kx fo ky b kz mq lb lc ld mr lf lg mk ms lj lk ml mt ln lo mm mu lr ls lt mn mo mp bj" data-selectable-paragraph="" id="9b42" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; letter-spacing: -0.003em; line-height: 32px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.05em; padding-left: 0px;">Group: A group is a subset of connections to the hub. You can add a client connection to a group, or remove the client connection from the group, anytime you want. In simple words, the group is a chat room for users.</li><li class="kw kx fo ky b kz mq lb lc ld mr lf lg mk ms lj lk ml mt ln lo mm mu lr ls lt mn mo mp bj" data-selectable-paragraph="" id="e50d" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; letter-spacing: -0.003em; line-height: 32px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.05em; padding-left: 0px;">User: A connection to Web PubSub belonging to a user. A user can have multiple connections i.e. connecting from multiple devices.</li><li class="kw kx fo ky b kz mq lb lc ld mr lf lg mk ms lj lk ml mt ln lo mm mu lr ls lt mn mo mp bj" data-selectable-paragraph="" id="aa62" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; letter-spacing: -0.003em; line-height: 32px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.05em; padding-left: 0px;">Client Events: Events are created during the lifecycle of a client connection. i.e. WebSocket client connection creates a <code class="cw mv mw mx my b" style="background-color: #f2f2f2; box-sizing: inherit; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; font-size: 15.75px; padding: 2px 4px;">connect</code> event when it tries to connect to the service, a <code class="cw mv mw mx my b" style="background-color: #f2f2f2; box-sizing: inherit; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; font-size: 15.75px; padding: 2px 4px;">connected</code> event when it successfully connected to the service, a <code class="cw mv mw mx my b" style="background-color: #f2f2f2; box-sizing: inherit; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; font-size: 15.75px; padding: 2px 4px;">message</code> event when it sends messages to the service and a <code class="cw mv mw mx my b" style="background-color: #f2f2f2; box-sizing: inherit; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; font-size: 15.75px; padding: 2px 4px;">disconnected</code> event when it disconnects from the service.</li><li class="kw kx fo ky b kz mq lb lc ld mr lf lg mk ms lj lk ml mt ln lo mm mu lr ls lt mn mo mp bj" data-selectable-paragraph="" id="f495" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; letter-spacing: -0.003em; line-height: 32px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.05em; padding-left: 0px;">Event Handler: The event handler contains the logic to handle client events. You can register or configure handlers in the service through the portal or Azure CLI.</li></ol><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="c47d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now we can start to build our App and to create the client app first thing we would need is, <span class="ky fp" style="box-sizing: inherit; font-weight: 700;"><em class="lu" style="box-sizing: inherit;">to establish a connection to the Azure Web PubSub service and to do so we need a backend server because the NPM package libraries @azure/web-pubsub and @azure/web-pubsub-client doesn’t satisfy all the need or in other words, is not compatible with the browser (client code) to build/generate the connection URL. Also, you weed need a backend server to manage the groups which you can’t do in client code.</em></span></p><blockquote class="mz na nb" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="kw kx lu ky b kz la lb lc ld le lf lg mk li lj lk ml lm ln lo mm lq lr ls lt fh bj" data-selectable-paragraph="" id="a451" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Note: You may generate the connection URL directly from Azure Web PubSub service’s Key settings but the generated URL is valid for 60 minutes defaulting to 1440 minutes (24 hours) max. Also, it won’t suit your need to build multiple groups at run time.</p></blockquote><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="90fe" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fp" style="box-sizing: inherit; font-weight: 700;">Steps to build the Backend Server app, which helps us to manage the connection, hubs & groups.</span></p><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="fcfd" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fp" style="box-sizing: inherit; font-weight: 700;">Step 1</span>: Create a Node Js application using your favorite Editor tool (In my case, I use Visual Studio Code).</p><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="7b17" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Step 2: if you already create package.json then add the below dependencies or if note then create the package.json file with the below code. It has all the required dependencies.</p><pre class="ly lz ma mb mc nc my nd bo ne nf ng" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="nh ni fo my b bf nj nk l nl nm" data-selectable-paragraph="" id="969f" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"name"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"chatapp-server"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"version"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"1.0.0"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"description"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">""</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"main"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"server.js"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"scripts"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"build"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"webpack --mode=development --watch"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"release"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"webpack --mode=production"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"publish"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"npm run release && dotnet publish -c Release"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"test"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"echo TODO"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"start"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"node server.js"</span><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"keywords"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-punctuation" style="box-sizing: inherit;">[</span><span class="hljs-punctuation" style="box-sizing: inherit;">]</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"author"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">""</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"license"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"ISC"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"dependencies"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"@azure/web-pubsub"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"^1.0.0"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"@azure/web-pubsub-express"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"^1.0.2"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"events"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"latest"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"express"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"^4.17.1"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"devDependencies"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"clean-webpack-plugin"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"latest"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"html-webpack-plugin"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"latest"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"webpack"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"^5.75.0"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"webpack-cli"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"^5.0.1"</span><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span></span></pre><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="c5ea" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">@azure/web-pubsub and @azure/web-pubsub-expres are the npm packages here that will be used to create the service client and the handlers.</p><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="6257" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fp" style="box-sizing: inherit; font-weight: 700;">Step 2</span>: Create a javascript file named server.js with the below code.</p><pre class="ly lz ma mb mc nc my nd bo ne nf ng" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="nh ni fo my b bf nj nk l nl nm" data-selectable-paragraph="" id="21f8" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> express = <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">require</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'express'</span>);<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> { <span class="hljs-title.class" style="box-sizing: inherit;">WebPubSubServiceClient</span>, <span class="hljs-title.class" style="box-sizing: inherit;">AzureKeyCredential</span> } = <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">require</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'@azure/web-pubsub'</span>);<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> { <span class="hljs-title.class" style="box-sizing: inherit;">WebPubSubEventHandler</span> } = <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">require</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'@azure/web-pubsub-express'</span>);<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> app = <span class="hljs-title.function" style="box-sizing: inherit;">express</span>();<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> hubName = <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'Hub'</span>;<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> port = <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">8080</span>;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//let connectionString = process.argv[2] || process.env.WebPubSubConnectionString;</span><br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> key = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> <span class="hljs-title.class" style="box-sizing: inherit;">AzureKeyCredential</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"<Key>"</span>);<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> serviceClient = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> <span class="hljs-title.class" style="box-sizing: inherit;">WebPubSubServiceClient</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"https://<host name>"</span>, key, hubName);<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">let</span> handler = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> <span class="hljs-title.class" style="box-sizing: inherit;">WebPubSubEventHandler</span>(hubName, {<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">path</span>: <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'/eventhandler'</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">onConnected</span>: <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">async</span> req => {<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">console</span>.<span class="hljs-title.function" style="box-sizing: inherit;">log</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">`<span class="hljs-subst" style="box-sizing: inherit; color: black;">${req.context.userId}</span> connected`</span>);<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> serviceClient.<span class="hljs-title.function" style="box-sizing: inherit;">sendToAll</span>({<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">type</span>: <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"system"</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">message</span>: <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">`<span class="hljs-subst" style="box-sizing: inherit; color: black;">${req.context.userId}</span> joined`</span><br style="box-sizing: inherit;" /> });<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">handleUserEvent</span>: <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">async</span> (req, res) => {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span> (req.<span class="hljs-property" style="box-sizing: inherit;">context</span>.<span class="hljs-property" style="box-sizing: inherit;">eventName</span> === <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'broadcast'</span>) {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> serviceClient.<span class="hljs-title.function" style="box-sizing: inherit;">sendToAll</span>({<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">from</span>: req.<span class="hljs-property" style="box-sizing: inherit;">context</span>.<span class="hljs-property" style="box-sizing: inherit;">userId</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">message</span>: req.<span class="hljs-property" style="box-sizing: inherit;">data</span><br style="box-sizing: inherit;" /> });<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> res.<span class="hljs-title.function" style="box-sizing: inherit;">success</span>();<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />});<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" />app.<span class="hljs-title.function" style="box-sizing: inherit;">use</span>(express.<span class="hljs-title.function" style="box-sizing: inherit;">json</span>());<br style="box-sizing: inherit;" />app.<span class="hljs-title.function" style="box-sizing: inherit;">use</span>(<span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">function</span> (<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">req, res, next</span>) {<br style="box-sizing: inherit;" /> res.<span class="hljs-title.function" style="box-sizing: inherit;">header</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Access-Control-Allow-Origin"</span>, <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"*"</span>);<br style="box-sizing: inherit;" /> res.<span class="hljs-title.function" style="box-sizing: inherit;">header</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Access-Control-Allow-Headers"</span>, <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Origin, X-Requested-With, Content-Type, Accept"</span>);<br style="box-sizing: inherit;" /> <span class="hljs-title.function" style="box-sizing: inherit;">next</span>();<br style="box-sizing: inherit;" />});<br style="box-sizing: inherit;" />app.<span class="hljs-title.function" style="box-sizing: inherit;">use</span>(handler.<span class="hljs-title.function" style="box-sizing: inherit;">getMiddleware</span>());<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//Create the client/connection and returns the connection url by user and group.</span><br style="box-sizing: inherit;" />app.<span class="hljs-title.function" style="box-sizing: inherit;">post</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'/negotiate'</span>, <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">async</span> (req, res) => {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> { groupName, id } = req.<span class="hljs-property" style="box-sizing: inherit;">body</span>;<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span> (!id) {<br style="box-sizing: inherit;" /> res.<span class="hljs-title.function" style="box-sizing: inherit;">status</span>(<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">400</span>).<span class="hljs-title.function" style="box-sizing: inherit;">send</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'missing user id'</span>);<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">return</span>;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">let</span> token = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> serviceClient.<span class="hljs-title.function" style="box-sizing: inherit;">getClientAccessToken</span>({ <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">userId</span>: id, <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">expirationTimeInMinutes</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">60</span>,<span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">roles</span>: [<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">`webpubsub.sendToGroup.<span class="hljs-subst" style="box-sizing: inherit; color: black;">${groupName}</span>`</span>,<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">`webpubsub.joinLeaveGroup.<span class="hljs-subst" style="box-sizing: inherit; color: black;">${groupName}</span>`</span><br style="box-sizing: inherit;" /> ] });<br style="box-sizing: inherit;" /> res.<span class="hljs-title.function" style="box-sizing: inherit;">json</span>({<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">url</span>: token.<span class="hljs-property" style="box-sizing: inherit;">url</span><br style="box-sizing: inherit;" /> });<br style="box-sizing: inherit;" />});<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//Add users to the groups</span><br style="box-sizing: inherit;" />app.<span class="hljs-title.function" style="box-sizing: inherit;">post</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'/chatgroup/addusers'</span>, <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">async</span> (req, res) => {<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">console</span>.<span class="hljs-title.function" style="box-sizing: inherit;">log</span>(req.<span class="hljs-property" style="box-sizing: inherit;">body</span>);<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> { groupName, users } = req.<span class="hljs-property" style="box-sizing: inherit;">body</span>;<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span> (!groupName) {<br style="box-sizing: inherit;" /> res.<span class="hljs-title.function" style="box-sizing: inherit;">status</span>(<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">400</span>).<span class="hljs-title.function" style="box-sizing: inherit;">send</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'missing groupName'</span>);<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">return</span>;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span> (!users) {<br style="box-sizing: inherit;" /> res.<span class="hljs-title.function" style="box-sizing: inherit;">status</span>(<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">400</span>).<span class="hljs-title.function" style="box-sizing: inherit;">send</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'missing users'</span>);<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">return</span>;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> groupExists = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> serviceClient.<span class="hljs-title.function" style="box-sizing: inherit;">groupExists</span>(groupName);<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span> (groupExists) {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">let</span> group = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> serviceClient.<span class="hljs-title.function" style="box-sizing: inherit;">group</span>(groupName);<br style="box-sizing: inherit;" /> users.<span class="hljs-title.function" style="box-sizing: inherit;">forEach</span>(<span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">async</span> usr => {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> group.<span class="hljs-title.function" style="box-sizing: inherit;">addUser</span>(usr);<br style="box-sizing: inherit;" /> });<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> res.<span class="hljs-title.function" style="box-sizing: inherit;">json</span>(<span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">true</span>);<br style="box-sizing: inherit;" />});<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//publish message to the group</span><br style="box-sizing: inherit;" />app.<span class="hljs-title.function" style="box-sizing: inherit;">post</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'/chatgroup/message'</span>, <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">async</span> (req, res) => {<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">console</span>.<span class="hljs-title.function" style="box-sizing: inherit;">log</span>(req.<span class="hljs-property" style="box-sizing: inherit;">body</span>);<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> { groupName, message } = req.<span class="hljs-property" style="box-sizing: inherit;">body</span>;<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span> (!groupName) {<br style="box-sizing: inherit;" /> res.<span class="hljs-title.function" style="box-sizing: inherit;">status</span>(<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">400</span>).<span class="hljs-title.function" style="box-sizing: inherit;">send</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'missing groupName'</span>);<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">return</span>;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span> (!message) {<br style="box-sizing: inherit;" /> res.<span class="hljs-title.function" style="box-sizing: inherit;">status</span>(<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">400</span>).<span class="hljs-title.function" style="box-sizing: inherit;">send</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'missing message'</span>);<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">return</span>;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> groupExists = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> serviceClient.<span class="hljs-title.function" style="box-sizing: inherit;">groupExists</span>(groupName);<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span> (groupExists) {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">let</span> group = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> serviceClient.<span class="hljs-title.function" style="box-sizing: inherit;">group</span>(groupName);<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> group.<span class="hljs-title.function" style="box-sizing: inherit;">sendToAll</span>(message);<br style="box-sizing: inherit;" /> res.<span class="hljs-title.function" style="box-sizing: inherit;">json</span>(message);<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> serviceClient.<span class="hljs-title.function" style="box-sizing: inherit;">createGroup</span>(groupName);<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">else</span><br style="box-sizing: inherit;" /> res.<span class="hljs-title.function" style="box-sizing: inherit;">json</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">`<span class="hljs-subst" style="box-sizing: inherit; color: black;">${groupName}</span> group doesn't exist.`</span>);<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" />});<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" />app.<span class="hljs-title.function" style="box-sizing: inherit;">use</span>(express.<span class="hljs-title.function" style="box-sizing: inherit;">static</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'public'</span>));<br style="box-sizing: inherit;" />app.<span class="hljs-title.function" style="box-sizing: inherit;">listen</span>(port, <span class="hljs-function" style="box-sizing: inherit;">() =></span> <span class="hljs-variable.language" style="box-sizing: inherit;">console</span>.<span class="hljs-title.function" style="box-sizing: inherit;">log</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">`Event handler listening at http://localhost:<span class="hljs-subst" style="box-sizing: inherit; color: black;">${port}</span><span class="hljs-subst" style="box-sizing: inherit; color: black;">${handler.path}</span>`</span>));</span></pre><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="afb7" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Here in the above code, we have three endpoints for getting the client connection URL which is required to create a service client instance in our client-side (app) code, and the other two are to add users to the existing group and publish messages to the group from the server if needed.</p><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="e1ee" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Instead of NodeJs you can also use Azure Functions here to get the client access url and code will be as:</p><pre class="ly lz ma mb mc nc my nd bo ne nf ng" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="nh ni fo my b bf nj nk l nl nm" data-selectable-paragraph="" id="91f8" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> { <span class="hljs-title.class" style="box-sizing: inherit;">WebPubSubServiceClient</span>, <span class="hljs-title.class" style="box-sizing: inherit;">AzureKeyCredential</span> } = <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">require</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'@azure/web-pubsub'</span>);<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-variable.language" style="box-sizing: inherit;">module</span>.<span class="hljs-property" style="box-sizing: inherit;">exports</span> = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">async</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">function</span> (<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">context, req</span>) {<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">try</span> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> { groupName, userId, hubName } = req.<span class="hljs-property" style="box-sizing: inherit;">body</span>;<br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">// reading below settings from Azure function application setting</span><br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">// which is pulling these from Azure KeyVault.</span><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> hostUrl = process.<span class="hljs-property" style="box-sizing: inherit;">env</span>[<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"WebPubSubURL"</span>];<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> hostKey = process.<span class="hljs-property" style="box-sizing: inherit;">env</span>[<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"WebPubSubKEY"</span>];<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span> (!userId || !groupName || !hubName) {<br style="box-sizing: inherit;" /> context.<span class="hljs-property" style="box-sizing: inherit;">res</span> = {<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">status</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">400</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">body</span>: <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">`missing user id, hub Name or group name`</span><br style="box-sizing: inherit;" /> };<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">else</span> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> key = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> <span class="hljs-title.class" style="box-sizing: inherit;">AzureKeyCredential</span>(hostKey);<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> serviceClient = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> <span class="hljs-title.class" style="box-sizing: inherit;">WebPubSubServiceClient</span>(hostUrl, key, hubName);<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">let</span> token = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> serviceClient.<span class="hljs-title.function" style="box-sizing: inherit;">getClientAccessToken</span>({<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">userId</span>: userId, <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">expirationTimeInMinutes</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">60</span>, <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">roles</span>: [<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">`webpubsub.sendToGroup.<span class="hljs-subst" style="box-sizing: inherit; color: black;">${groupName}</span>`</span>,<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">`webpubsub.joinLeaveGroup.<span class="hljs-subst" style="box-sizing: inherit; color: black;">${groupName}</span>`</span><br style="box-sizing: inherit;" /> ]<br style="box-sizing: inherit;" /> });<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> context.<span class="hljs-property" style="box-sizing: inherit;">res</span> = {<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">status</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">200</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">body</span>: {<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">url</span>: token.<span class="hljs-property" style="box-sizing: inherit;">url</span><br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> };<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> context.<span class="hljs-title.function" style="box-sizing: inherit;">log</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'JavaScript HTTP trigger function:post-getchatappurl processed a request.'</span>);<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">return</span>;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> } <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">catch</span> (err) {<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">console</span>.<span class="hljs-title.function" style="box-sizing: inherit;">log</span>(err);<br style="box-sizing: inherit;" /> context.<span class="hljs-property" style="box-sizing: inherit;">res</span> = {<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">status</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">500</span><br style="box-sizing: inherit;" /> };<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">return</span>;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="e9e5" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">To read environments for local machine while testing your Azure Function code, use local.settings.json i.e.</p><pre class="ly lz ma mb mc nc my nd bo ne nf ng" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="nh ni fo my b bf nj nk l nl nm" data-selectable-paragraph="" id="7241" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"IsEncrypted"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">false</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"Values"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"AzureWebJobsStorage"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">""</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"FUNCTIONS_WORKER_RUNTIME"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"node"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"WebPubSubURL"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"<web pubsub host url>"</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"WebPubSubKEY"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"web pubsub key"</span><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"Host"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"LocalHttpPort"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">7071</span><span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">"CORS"</span><span class="hljs-punctuation" style="box-sizing: inherit;">:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"*"</span><br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span><br style="box-sizing: inherit;" /><span class="hljs-punctuation" style="box-sizing: inherit;">}</span></span></pre><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="2613" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><em class="lu" style="box-sizing: inherit;">If you do not want the group and instead want to send all users connected to the hub, then avoid creating token with roles enabled by the group as per the below code:</em></p><pre class="ly lz ma mb mc nc my nd bo ne nf ng" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="nh ni fo my b bf nj nk l nl nm" data-selectable-paragraph="" id="0deb" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">let</span> token = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> serviceClient.<span class="hljs-title.function" style="box-sizing: inherit;">getClientAccessToken</span>({ <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">userId</span>: id, <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">expirationTimeInMinutes</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">60</span> });</span></pre><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="5613" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now if run this with the command “npm run start”, you will be able to consume & test the endpoints from Postman.</p><figure class="ly lz ma mb mc md lv lw paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="me mf eb mg bg mh" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 680px; z-index: auto;" tabindex="0"><div class="lv lw nn" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1118px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*buOSrZvKZOEQz0qT3BoPOw.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*buOSrZvKZOEQz0qT3BoPOw.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*buOSrZvKZOEQz0qT3BoPOw.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*buOSrZvKZOEQz0qT3BoPOw.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*buOSrZvKZOEQz0qT3BoPOw.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*buOSrZvKZOEQz0qT3BoPOw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*buOSrZvKZOEQz0qT3BoPOw.png 1400w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/1*buOSrZvKZOEQz0qT3BoPOw.png 640w, https://miro.medium.com/v2/resize:fit:720/1*buOSrZvKZOEQz0qT3BoPOw.png 720w, https://miro.medium.com/v2/resize:fit:750/1*buOSrZvKZOEQz0qT3BoPOw.png 750w, https://miro.medium.com/v2/resize:fit:786/1*buOSrZvKZOEQz0qT3BoPOw.png 786w, https://miro.medium.com/v2/resize:fit:828/1*buOSrZvKZOEQz0qT3BoPOw.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*buOSrZvKZOEQz0qT3BoPOw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*buOSrZvKZOEQz0qT3BoPOw.png 1400w" style="box-sizing: inherit;"></source><img alt="" class="bg mi mj c" height="303" loading="lazy" role="presentation" src="https://miro.medium.com/v2/resize:fit:700/1*buOSrZvKZOEQz0qT3BoPOw.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 680px;" width="700" /></picture></div></div></figure><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="5cd2" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Our server is ready to serve our needs, Now let’s create the chat app.</p><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="4c39" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fp" style="box-sizing: inherit; font-weight: 700;">Steps to build the chat app, a client web application.</span></p><blockquote class="mz na nb" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="kw kx lu ky b kz la lb lc ld le lf lg mk li lj lk ml lm ln lo mm lq lr ls lt fh bj" data-selectable-paragraph="" id="f6f2" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Note: Azure Web PubSub Service doesn’t persist your message hence if a user is not connected will lose the message. Hence you need to build your own logic to persist the message in the database and load it when a user comes online.</p></blockquote><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="7915" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fp" style="box-sizing: inherit; font-weight: 700;">Step 1</span>: Create your web application using Vue/Angular/React your choice.</p><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="e78b" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fp" style="box-sizing: inherit; font-weight: 700;">Step 2</span>: Create the Chat UI to show the user’s chats. If you are also creating the Vuejs application then can use the whole code below here or else, concentrate on UI (Html) code.</p><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="913e" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fp" style="box-sizing: inherit; font-weight: 700;">HTML Code</span></p><pre class="ly lz ma mb mc nc my nd bo ne nf ng" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="nh ni fo my b bf nj nk l nl nm" data-selectable-paragraph="" id="107e" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">template</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">div</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">class</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"chat-container"</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">section</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">ref</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"chatArea"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">class</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"chat-area"</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">u</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">class</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"headline"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">style</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"float: left; padding: 5px;"</span>></span>{{ conversation.groupName}}<span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">u</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">br</span> /></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">div</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">style</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"display: flex; flex-direction: row;"</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;"><!--Here you can show list of users involved in this chat.--></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">div</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">style</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"float: left; padding: 5px;"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">v-for</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"chatuser in groupUsers"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">:key</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"chatuser.name"</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">span</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">class</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"label info"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">v-if</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"chatuser.emailId !== user.username"</span>></span>{{ chatuser.name }}<span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">span</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">input</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">type</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"button"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">value</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Add Users"</span> @<span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">click</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"AddUsers()"</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">style</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"float: right; padding: 5px;"</span>/></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">hr</span> /></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">div</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">v-for</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"message in conversation.messages"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">:key</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"message.messageId"</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;"><!-- <img :src="" class="user-img" /> --></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">p</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">class</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"message"</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">:class</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"{ 'message-out': message.sender === user.userName, 'message-in': message.sender !== user.userName }"</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">b</span>></span>{{ message.sender }} {{ message.timestamp }}<span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">b</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">br</span> /></span><br style="box-sizing: inherit;" /> {{ message.message }}<br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">p</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">div</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">v-show</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"conversation.status === 'Open'"</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">textarea</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">id</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"txtarea"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">name</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"txtarea"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">rows</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"4"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">cols</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"50"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">:value</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"userMessage"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">v-mc-model</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"userMessage"</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">hiddenlabel</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">placeholder</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"type your message here..."</span>/></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">div</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">style</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"display: flex; flex-direction: row;"</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">input</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">type</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"button"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">value</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Send"</span> @<span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">click</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"SendMessage()"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">style</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"float: right; padding: 5px;"</span> /></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">input</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">type</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"button"</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">value</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Cancel"</span> @<span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">click</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"CancelMessage()"</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">style</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"float: right; padding: 5px;"</span> /></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">section</span>></span><br style="box-sizing: inherit;" /> <span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">div</span>></span><br style="box-sizing: inherit;" /><span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">template</span>></span></span></pre><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="7092" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">CSS</p><pre class="ly lz ma mb mc nc my nd bo ne nf ng" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="nh ni fo my b bf nj nk l nl nm" data-selectable-paragraph="" id="4144" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-selector-class" style="box-sizing: inherit; color: #9b703f;">.chat-container</span> {<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">display</span>: flex;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">justify-content</span>: center;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">overflow</span>: hidden;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">padding-left</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">10px</span>;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">padding-right</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">10px</span>;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">padding-bottom</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">10px</span>;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">overflow-y</span>: scroll;<br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-selector-class" style="box-sizing: inherit; color: #9b703f;">.headline</span> {<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">text-align</span>: left;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">font-weight</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">100</span>;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">color</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">#0073AB</span>;<br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /><span class="hljs-selector-class" style="box-sizing: inherit; color: #9b703f;">.chat-area</span> {<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">background-color</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">#FFFFFF</span>;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">height</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">100%</span>;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">width</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">100%</span>;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">padding</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">1em</span>;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">overflow</span>: hidden;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">margin</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">0</span> auto <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">2em</span> auto;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">box-shadow</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">2px</span> <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">2px</span> <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">5px</span> <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">2px</span> <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">#FFFFFF</span>;<br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /><span class="hljs-selector-class" style="box-sizing: inherit; color: #9b703f;">.message</span> {<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">border-radius</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">10px</span>;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">padding</span>: .<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">5em</span>;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">margin-bottom</span>: .<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">5em</span>;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">margin-top</span>: .<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">5em</span>;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">font-size</span>: .<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">8em</span>;<br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /><span class="hljs-selector-class" style="box-sizing: inherit; color: #9b703f;">.message-out</span> {<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">background</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">#B5E0F5</span>;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">color</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">#000000</span>;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">margin-left</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">20%</span>;<br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /><span class="hljs-selector-class" style="box-sizing: inherit; color: #9b703f;">.message-in</span> {<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">background</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">#DBDBDB</span>;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">color</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">#000000</span>;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">margin-right</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">20%</span>;<br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-selector-class" style="box-sizing: inherit; color: #9b703f;">.chat-inputs</span> {<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">display</span>: flex;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">justify-content</span>: space-between;<br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /><span class="hljs-selector-id" style="box-sizing: inherit; color: #9b703f;">#person1-input</span> {<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">padding</span>: .<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">5em</span>;<br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /><span class="hljs-selector-id" style="box-sizing: inherit; color: #9b703f;">#person2-input</span> {<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">padding</span>: .<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">5em</span>; <br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-selector-class" style="box-sizing: inherit; color: #9b703f;">.label</span> {<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">color</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">#00243D</span>;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">padding</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">5px</span>;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">float</span>: left;<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">white-space</span>: nowrap;<br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /><span class="hljs-selector-class" style="box-sizing: inherit; color: #9b703f;">.info</span> {<br style="box-sizing: inherit;" /> <span class="hljs-attribute" style="box-sizing: inherit; color: #aa0d91;">background-color</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">#D3ECF9</span>;<br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /></span></pre><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="2cd8" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Please ignore if the above CSS has any extra unused CSS class as I just pasted it as it is from my local.</p><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="7e48" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fp" style="box-sizing: inherit; font-weight: 700;">Step 2</span>: Build the code as per the UI created Above. Above UI expecting the Message conversation in a format as:</p><pre class="ly lz ma mb mc nc my nd bo ne nf ng" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="nh ni fo my b bf nj nk l nl nm" data-selectable-paragraph="" id="ef7e" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> groupName<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> String<span class="hljs-punctuation" style="box-sizing: inherit;">,</span> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//Group Name</span><br style="box-sizing: inherit;" /> message<span class="hljs-punctuation" style="box-sizing: inherit;">:</span><span class="hljs-punctuation" style="box-sizing: inherit;">{</span><br style="box-sizing: inherit;" /> message<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> String<span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> timestamp <span class="hljs-punctuation" style="box-sizing: inherit;">:</span> String<span class="hljs-punctuation" style="box-sizing: inherit;">,</span><br style="box-sizing: inherit;" /> sender<span class="hljs-punctuation" style="box-sizing: inherit;">:</span> String<br style="box-sizing: inherit;" /> <span class="hljs-punctuation" style="box-sizing: inherit;">}</span> <br style="box-sizing: inherit;" /><span class="hljs-punctuation" style="box-sizing: inherit;">}</span><br style="box-sizing: inherit;" /></span></pre><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="b98c" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Code</p><pre class="ly lz ma mb mc nc my nd bo ne nf ng" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="nh ni fo my b bf nj nk l nl nm" data-selectable-paragraph="" id="2a2b" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"><<span class="hljs-name" style="box-sizing: inherit;">script</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">lang</span>=<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"ts"</span>></span><span class="hljs-undefined" style="box-sizing: inherit;"><br style="box-sizing: inherit;" /><span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//@ts-nocheck</span><br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">import</span> <span class="hljs-title.class" style="box-sizing: inherit;">Vue</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">from</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'vue'</span>;<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">import</span> { <span class="hljs-title.class" style="box-sizing: inherit;">IData</span>, <span class="hljs-title.class" style="box-sizing: inherit;">IMethods</span>, <span class="hljs-title.class" style="box-sizing: inherit;">IComputed</span>, <span class="hljs-title.class" style="box-sizing: inherit;">IProps</span> } <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">from</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'./interfaces'</span>;<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">import</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'./styles/web-pubsubchat.scss'</span>;<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">import</span> { mapGetters } <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">from</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'vuex'</span>;<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">import</span> { <span class="hljs-title.class" style="box-sizing: inherit;">GlobalGetterEnum</span>, <span class="hljs-title.class" style="box-sizing: inherit;">GlobalActionEnum</span>, <span class="hljs-variable.constant" style="box-sizing: inherit;">NAMESPACE</span> } <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">from</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'@/store/modules/global/static'</span>;<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">import</span> {<br style="box-sizing: inherit;" /> <span class="hljs-title.class" style="box-sizing: inherit;">WebPubSubClient</span><br style="box-sizing: inherit;" />} <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">from</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"@azure/web-pubsub-client"</span>;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> hubName = <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'Hub'</span>;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">export</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">default</span> <span class="hljs-title.class" style="box-sizing: inherit;">Vue</span>.<span class="hljs-property" style="box-sizing: inherit;">extend</span><<span class="hljs-title.class" style="box-sizing: inherit;">IData</span>, <span class="hljs-title.class" style="box-sizing: inherit;">IMethods</span>, <span class="hljs-title.class" style="box-sizing: inherit;">IComputed</span>, <span class="hljs-title.class" style="box-sizing: inherit;">IProps</span>>({<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">name</span>: <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'web-pubsubchat'</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">props</span>: {<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> <span class="hljs-title.function" style="box-sizing: inherit;">data</span>() {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">return</span> {<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">conversation</span>: {},<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">userMessage</span>: <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">''</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">webPubSubClinet</span>: {} <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">as</span> <span class="hljs-title.class" style="box-sizing: inherit;">WebPubSubClient</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">groupUsers</span>: [] <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//list of users in this chat.</span><br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">computed</span>: {<br style="box-sizing: inherit;" /> ...<span class="hljs-title.function" style="box-sizing: inherit;">mapGetters</span>(<span class="hljs-variable.constant" style="box-sizing: inherit;">NAMESPACE</span>, {<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">user</span>: <span class="hljs-title.class" style="box-sizing: inherit;">GlobalGetterEnum</span>.<span class="hljs-property" style="box-sizing: inherit;">GET_USER</span>,<br style="box-sizing: inherit;" /> }),<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">methods</span>: {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">async</span> <span class="hljs-title.class" style="box-sizing: inherit;">SendMessage</span>() {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">try</span> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">webPubSubClinet</span>.<span class="hljs-title.function" style="box-sizing: inherit;">sendToGroup</span>(<br style="box-sizing: inherit;" /> groupName,<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">groupName</span>: <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">conversation</span>.<span class="hljs-property" style="box-sizing: inherit;">groupName</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">message</span>: {<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">message</span>: responseMessage.<span class="hljs-property" style="box-sizing: inherit;">message</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">timestamp</span>: responseMessage.<span class="hljs-property" style="box-sizing: inherit;">timestamp</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">sender</span>: responseMessage.<span class="hljs-property" style="box-sizing: inherit;">sender</span><br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"json"</span><br style="box-sizing: inherit;" /> );<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">userMessage</span> = <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">''</span>;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">catch</span> (error) {<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">console</span>.<span class="hljs-title.function" style="box-sizing: inherit;">log</span>(error);<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">userMessage</span> = <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">''</span>;<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">async</span> <span class="hljs-title.class" style="box-sizing: inherit;">CancelMessage</span>() {<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">userMessage</span> = <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">''</span>;<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">async</span> <span class="hljs-title.function" style="box-sizing: inherit;">removeUser</span>(<span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">$event</span>: any, <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">userEmailId</span>: string): promise<<span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">void</span>> {<br style="box-sizing: inherit;" /> <span class="hljs-title.function" style="box-sizing: inherit;">alert</span>($event.<span class="hljs-property" style="box-sizing: inherit;">details</span>);<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">async</span> <span class="hljs-title.class" style="box-sizing: inherit;">AddUsers</span>() {<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">async</span> <span class="hljs-title.class" style="box-sizing: inherit;">InitializeChatRoom</span>() {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">try</span> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">let</span> groupName = <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"HelpGroup"</span>;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">let</span> clientAccessUrl = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> api.<span class="hljs-property" style="box-sizing: inherit;">chatHub</span>.<span class="hljs-title.function" style="box-sizing: inherit;">getClientAccessUrl</span>(<span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">user</span>.<span class="hljs-property" style="box-sizing: inherit;">userName</span>, groupName);<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">webPubSubClinet</span> = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> <span class="hljs-title.class" style="box-sizing: inherit;">WebPubSubClient</span>(clientAccessUrl);<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">webPubSubClinet</span>.<span class="hljs-title.function" style="box-sizing: inherit;">on</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"connected"</span>, <span class="hljs-function" style="box-sizing: inherit;">(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">e</span>) =></span> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">debugger</span>;<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">console</span>.<span class="hljs-title.function" style="box-sizing: inherit;">log</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">`Connection <span class="hljs-subst" style="box-sizing: inherit; color: black;">${e.connectionId}</span> is connected.`</span>);<br style="box-sizing: inherit;" /> });<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">webPubSubClinet</span>.<span class="hljs-title.function" style="box-sizing: inherit;">on</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"disconnected"</span>, <span class="hljs-function" style="box-sizing: inherit;">(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">e</span>) =></span> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">debugger</span>;<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">console</span>.<span class="hljs-title.function" style="box-sizing: inherit;">log</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">`Connection disconnected: <span class="hljs-subst" style="box-sizing: inherit; color: black;">${e.message}</span>`</span>);<br style="box-sizing: inherit;" /> });<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">webPubSubClinet</span>.<span class="hljs-title.function" style="box-sizing: inherit;">on</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"group-message"</span>, <span class="hljs-function" style="box-sizing: inherit;">(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">e</span>) =></span> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">debugger</span>;<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span> (e.<span class="hljs-property" style="box-sizing: inherit;">message</span>.<span class="hljs-property" style="box-sizing: inherit;">data</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">instanceof</span> <span class="hljs-title.class" style="box-sizing: inherit;">ArrayBuffer</span>) {<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">console</span>.<span class="hljs-title.function" style="box-sizing: inherit;">log</span>(<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">`Received message from <span class="hljs-subst" style="box-sizing: inherit; color: black;">${e.message.group}</span> <span class="hljs-subst" style="box-sizing: inherit; color: black;">${Buffer.<span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">from</span>(e.message.data).toString(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"base64"</span>)}</span>`</span><br style="box-sizing: inherit;" /> );<br style="box-sizing: inherit;" /> } <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">else</span> {<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">console</span>.<span class="hljs-title.function" style="box-sizing: inherit;">log</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">`Received message from <span class="hljs-subst" style="box-sizing: inherit; color: black;">${e.message.group}</span>: <span class="hljs-subst" style="box-sizing: inherit; color: black;">${e.message.data}</span>`</span>);<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">conversation</span>.<span class="hljs-property" style="box-sizing: inherit;">messages</span>.<span class="hljs-title.function" style="box-sizing: inherit;">push</span>({<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">message</span>: e.<span class="hljs-property" style="box-sizing: inherit;">message</span>.<span class="hljs-property" style="box-sizing: inherit;">data</span>.<span class="hljs-property" style="box-sizing: inherit;">message</span>.<span class="hljs-property" style="box-sizing: inherit;">message</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">timestamp</span>: e.<span class="hljs-property" style="box-sizing: inherit;">message</span>.<span class="hljs-property" style="box-sizing: inherit;">data</span>.<span class="hljs-property" style="box-sizing: inherit;">message</span>.<span class="hljs-property" style="box-sizing: inherit;">timestamp</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">sender</span>: e.<span class="hljs-property" style="box-sizing: inherit;">message</span>.<span class="hljs-property" style="box-sizing: inherit;">data</span>.<span class="hljs-property" style="box-sizing: inherit;">message</span>.<span class="hljs-property" style="box-sizing: inherit;">sender</span><br style="box-sizing: inherit;" /> });<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> });<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">webPubSubClinet</span>.<span class="hljs-title.function" style="box-sizing: inherit;">start</span>();<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">webPubSubClinet</span>.<span class="hljs-title.function" style="box-sizing: inherit;">joinGroup</span>(groupName);<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">webPubSubClinet</span>.<span class="hljs-title.function" style="box-sizing: inherit;">sendToGroup</span>(<br style="box-sizing: inherit;" /> groupName,<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">groupName</span>: <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">conversation</span>.<span class="hljs-property" style="box-sizing: inherit;">groupName</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">message</span>: {<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">message</span>: <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">`Hello, You are welcome to the group: <span class="hljs-subst" style="box-sizing: inherit; color: black;">${groupName}</span>`</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">timestamp</span>: <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"08-06 06:20 PM"</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">sender</span>: <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">user</span>.<span class="hljs-property" style="box-sizing: inherit;">userName</span><br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"json"</span><br style="box-sizing: inherit;" /> );<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">catch</span> (error) {<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">console</span>.<span class="hljs-title.function" style="box-sizing: inherit;">log</span>(error);<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">finally</span> {<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">processing</span> = <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">false</span>;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">async</span> <span class="hljs-title.function" style="box-sizing: inherit;">created</span>() {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-title.class" style="box-sizing: inherit;">InitializeChatRoom</span>();<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">async</span> <span class="hljs-title.function" style="box-sizing: inherit;">unmounted</span>() {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">try</span> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">webPubSubClinet</span>.<span class="hljs-title.function" style="box-sizing: inherit;">stop</span>();<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">catch</span> (error) {<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">console</span>.<span class="hljs-title.function" style="box-sizing: inherit;">log</span>(error);<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" />});<br style="box-sizing: inherit;" /></span><span class="hljs-tag" style="box-sizing: inherit; color: #aa0d91;"></<span class="hljs-name" style="box-sizing: inherit;">script</span>></span></span></pre><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="2782" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In the above code, my application is connected through Azure AD, and the logged-in user state is stored in the Vuex store module which I’m reading through getter props “user”. Hence user.username is user’s email id.</p><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="aa0a" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">When the page starts, the Chat room is initialized with the unique group name “HelloGroup” and the current logged in user. if you want you can add more users to it.</p><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="2c32" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In the InitializeChatRoom() method (called when page loads with created hook of vuejs app), we below important actions (actions order are important here):<br style="box-sizing: inherit;" /><span class="ky fp" style="box-sizing: inherit; font-weight: 700;">1</span>. Create the client connection. Here we call the nodejs backend server api to generate the unique connection for the mentioned group and user. the code is:</p><pre class="ly lz ma mb mc nc my nd bo ne nf ng" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="nh ni fo my b bf nj nk l nl nm" data-selectable-paragraph="" id="8542" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">let</span> clientAccessUrl = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> api.chatHub.getClientAccessUrl(<span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">this</span>.user.userName, groupName);<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">this</span>.$data.webPubSubClinet = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> WebPubSubClient(clientAccessUrl);</span></pre><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="e0a0" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">we will persist the service client object in the “this.$data.webPubSubClinet” object to re-use throughout the page.</p><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="13a9" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fp" style="box-sizing: inherit; font-weight: 700;">2.</span> Add event handlers to listen “connected”, “disconnected” and “group-message”.</p><pre class="ly lz ma mb mc nc my nd bo ne nf ng" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="nh ni fo my b bf nj nk l nl nm" data-selectable-paragraph="" id="3d53" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">webPubSubClinet</span>.<span class="hljs-title.function" style="box-sizing: inherit;">on</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"connected"</span>, <span class="hljs-function" style="box-sizing: inherit;">(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">e</span>) =></span> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">debugger</span>;<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">console</span>.<span class="hljs-title.function" style="box-sizing: inherit;">log</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">`Connection <span class="hljs-subst" style="box-sizing: inherit; color: black;">${e.connectionId}</span> is connected.`</span>);<br style="box-sizing: inherit;" /> });<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">webPubSubClinet</span>.<span class="hljs-title.function" style="box-sizing: inherit;">on</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"disconnected"</span>, <span class="hljs-function" style="box-sizing: inherit;">(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">e</span>) =></span> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">debugger</span>;<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">console</span>.<span class="hljs-title.function" style="box-sizing: inherit;">log</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">`Connection disconnected: <span class="hljs-subst" style="box-sizing: inherit; color: black;">${e.message}</span>`</span>);<br style="box-sizing: inherit;" /> });<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">webPubSubClinet</span>.<span class="hljs-title.function" style="box-sizing: inherit;">on</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"group-message"</span>, <span class="hljs-function" style="box-sizing: inherit;">(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">e</span>) =></span> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">debugger</span>;<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span> (e.<span class="hljs-property" style="box-sizing: inherit;">message</span>.<span class="hljs-property" style="box-sizing: inherit;">data</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">instanceof</span> <span class="hljs-title.class" style="box-sizing: inherit;">ArrayBuffer</span>) {<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">console</span>.<span class="hljs-title.function" style="box-sizing: inherit;">log</span>(<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">`Received message from <span class="hljs-subst" style="box-sizing: inherit; color: black;">${e.message.group}</span> <span class="hljs-subst" style="box-sizing: inherit; color: black;">${Buffer.<span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">from</span>(e.message.data).toString(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"base64"</span>)}</span>`</span><br style="box-sizing: inherit;" /> );<br style="box-sizing: inherit;" /> } <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">else</span> {<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">console</span>.<span class="hljs-title.function" style="box-sizing: inherit;">log</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">`Received message from <span class="hljs-subst" style="box-sizing: inherit; color: black;">${e.message.group}</span>: <span class="hljs-subst" style="box-sizing: inherit; color: black;">${e.message.data}</span>`</span>);<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">this</span>.<span class="hljs-property" style="box-sizing: inherit;">$data</span>.<span class="hljs-property" style="box-sizing: inherit;">conversation</span>.<span class="hljs-property" style="box-sizing: inherit;">messages</span>.<span class="hljs-title.function" style="box-sizing: inherit;">push</span>({<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">message</span>: e.<span class="hljs-property" style="box-sizing: inherit;">message</span>.<span class="hljs-property" style="box-sizing: inherit;">data</span>.<span class="hljs-property" style="box-sizing: inherit;">message</span>.<span class="hljs-property" style="box-sizing: inherit;">message</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">timestamp</span>: e.<span class="hljs-property" style="box-sizing: inherit;">message</span>.<span class="hljs-property" style="box-sizing: inherit;">data</span>.<span class="hljs-property" style="box-sizing: inherit;">message</span>.<span class="hljs-property" style="box-sizing: inherit;">timestamp</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">sender</span>: e.<span class="hljs-property" style="box-sizing: inherit;">message</span>.<span class="hljs-property" style="box-sizing: inherit;">data</span>.<span class="hljs-property" style="box-sizing: inherit;">message</span>.<span class="hljs-property" style="box-sizing: inherit;">sender</span><br style="box-sizing: inherit;" /> });<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> });</span></pre><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="0cff" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">When we receive the message in group, through “group-message” event handler, we add the same to the “this.$data.conversation” object so that it will appear in chat area.</p><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="59ea" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fp" style="box-sizing: inherit; font-weight: 700;">3.</span> Start the client</p><pre class="ly lz ma mb mc nc my nd bo ne nf ng" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="nh ni fo my b bf nj nk l nl nm" data-selectable-paragraph="" id="ef70" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">await <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">this</span>.$<span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">data</span>.webPubSubClinet.start();</span></pre><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="d89a" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fp" style="box-sizing: inherit; font-weight: 700;">4.</span> Join the group. This is important, if you don’t join then you won’t get messages back.</p><pre class="ly lz ma mb mc nc my nd bo ne nf ng" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="nh ni fo my b bf nj nk l nl nm" data-selectable-paragraph="" id="ccad" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"> await <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">this</span>.$<span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">data</span>.webPubSubClinet.joinGroup(groupName);</span></pre><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="1742" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">That’s all. Now to send the message to the group, you use the code as:</p><pre class="ly lz ma mb mc nc my nd bo ne nf ng" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="nh ni fo my b bf nj nk l nl nm" data-selectable-paragraph="" id="24d5" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">await <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">this</span>.$<span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">data</span>.webPubSubClinet.sendToGroup(<br style="box-sizing: inherit;" /> groupName,<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> groupName: <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">this</span>.$<span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">data</span>.conversation.groupName,<br style="box-sizing: inherit;" /> message: {<br style="box-sizing: inherit;" /> message: `Hello, You are welcome to the group: ${groupName}`,<br style="box-sizing: inherit;" /> timestamp: <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"08-06 06:20 PM"</span>,<br style="box-sizing: inherit;" /> sender: <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">this</span>.user.userName<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"json"</span><br style="box-sizing: inherit;" /> );</span></pre><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="d274" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now you run the application and open with multiple browsers with different/same user(s) and test the app, your UI will look like this:</p><figure class="ly lz ma mb mc md lv lw paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="lv lw no" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 399px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 399px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*b0frv3YRm6jlfBBQvb5qkg.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*b0frv3YRm6jlfBBQvb5qkg.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*b0frv3YRm6jlfBBQvb5qkg.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*b0frv3YRm6jlfBBQvb5qkg.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*b0frv3YRm6jlfBBQvb5qkg.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*b0frv3YRm6jlfBBQvb5qkg.png 1100w, https://miro.medium.com/v2/resize:fit:798/format:webp/1*b0frv3YRm6jlfBBQvb5qkg.png 798w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 399px" srcset="https://miro.medium.com/v2/resize:fit:640/1*b0frv3YRm6jlfBBQvb5qkg.png 640w, https://miro.medium.com/v2/resize:fit:720/1*b0frv3YRm6jlfBBQvb5qkg.png 720w, https://miro.medium.com/v2/resize:fit:750/1*b0frv3YRm6jlfBBQvb5qkg.png 750w, https://miro.medium.com/v2/resize:fit:786/1*b0frv3YRm6jlfBBQvb5qkg.png 786w, https://miro.medium.com/v2/resize:fit:828/1*b0frv3YRm6jlfBBQvb5qkg.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*b0frv3YRm6jlfBBQvb5qkg.png 1100w, https://miro.medium.com/v2/resize:fit:798/1*b0frv3YRm6jlfBBQvb5qkg.png 798w" style="box-sizing: inherit;"></source><img alt="" class="bg mi mj c" height="478" loading="lazy" role="presentation" src="https://miro.medium.com/v2/resize:fit:399/1*b0frv3YRm6jlfBBQvb5qkg.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 399px;" width="399" /></picture></div></figure><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="4d54" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><em class="lu" style="box-sizing: inherit;">Note: I hide the names (which is the user’s email Id) purposefully here as I had integrated it with Azure AD.</em></p><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="c2a1" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Enjoy, your chat app is ready.</p><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="921e" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">References used for this app code:</p><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="89d0" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><a class="af np" href="https://github.com/Azure/azure-sdk-for-js" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://github.com/Azure/azure-sdk-for-js</a><br style="box-sizing: inherit;" /><a class="af np" href="https://learn.microsoft.com/en-us/azure/azure-web-pubsub/overview" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://learn.microsoft.com/en-us/azure/azure-web-pubsub/overview</a><br style="box-sizing: inherit;" /><a class="af np" href="https://learn.microsoft.com/en-us/azure/azure-web-pubsub/tutorial-build-chat?tabs=csharp" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://learn.microsoft.com/en-us/azure/azure-web-pubsub/tutorial-build-chat?tabs=csharp</a></p><p class="pw-post-body-paragraph kw kx fo ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt fh bj" data-selectable-paragraph="" id="89d0" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><br /><span style="font-weight: 700; letter-spacing: -0.06px;">Hope you enjoyed the content, follow me for more like this, and please don’t forget to LIKE it. Happy programming.</span><br /><br /></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-41880220165654488052023-05-03T20:36:00.004+05:302023-05-04T18:20:32.009+05:30GraphQL API with ASP.NET Core— Making your API smart<p> <span style="background-color: white; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">GraphQL was created in 2012 and open-sourced by Facebook in 2015. In 2019, Facebook and others</span><span style="background-color: white; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;"> </span><a class="af lu" href="https://foundation.graphql.org/news/2019/03/12/the-graphql-foundation-announces-collaboration-with-the-joint-development-foundation-to-drive-open-source-and-open-standards/" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;" target="_blank">created the GraphQL Foundation</a><span style="background-color: white; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;"> </span><span style="background-color: white; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">as a neutral, non-profit home for the GraphQL assets and ongoing collaboration, and hosted by</span><span style="background-color: white; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;"> </span><a class="af lu" href="https://linuxfoundation.org/" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;" target="_blank">The Linux Foundation</a><span style="background-color: white; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">. The GraphQL Foundation is a fully neutral home for the GraphQL trademark and provides a means of collecting and distributing membership dues to support core community infrastructure and programs.</span></p><h2 class="lv lw fl be lx ly lz ma mb mc md me mf lh mg mh mi ll mj mk ml lp mm mn mo mp bj" data-selectable-paragraph="" id="568d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 20px; line-height: 24px; margin: 1.72em 0px -0.31em;">What is GraphQL</h2><p class="pw-post-body-paragraph kw kx fl ky b kz mq lb lc ld mr lf lg lh ms lj lk ll mt ln lo lp mu lr ls lt ey bj" data-selectable-paragraph="" id="446e" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 0.86em 0px -0.46em; word-break: break-word;">GraphQL is a query language for APIs, it gives power to the client to control the response on what they need instead of the server deciding what to respond.</p><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="2a74" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">It sits between clients and backend services and fulfills the query for clients. GraphQL can aggregate multiple resource requests into a single query.</p><figure class="my mz na nb nc nd mv mw paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="ne nf dj ng bg nh" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 680px; z-index: auto;" tabindex="0"><div class="mv mw mx" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 813px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*QcbktmBAe-kQI-0TQ2R73w.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*QcbktmBAe-kQI-0TQ2R73w.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*QcbktmBAe-kQI-0TQ2R73w.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*QcbktmBAe-kQI-0TQ2R73w.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*QcbktmBAe-kQI-0TQ2R73w.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*QcbktmBAe-kQI-0TQ2R73w.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*QcbktmBAe-kQI-0TQ2R73w.png 1400w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/1*QcbktmBAe-kQI-0TQ2R73w.png 640w, https://miro.medium.com/v2/resize:fit:720/1*QcbktmBAe-kQI-0TQ2R73w.png 720w, https://miro.medium.com/v2/resize:fit:750/1*QcbktmBAe-kQI-0TQ2R73w.png 750w, https://miro.medium.com/v2/resize:fit:786/1*QcbktmBAe-kQI-0TQ2R73w.png 786w, https://miro.medium.com/v2/resize:fit:828/1*QcbktmBAe-kQI-0TQ2R73w.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*QcbktmBAe-kQI-0TQ2R73w.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*QcbktmBAe-kQI-0TQ2R73w.png 1400w" style="box-sizing: inherit;"></source><img alt="" class="bg ni nj c" height="349" loading="lazy" role="presentation" src="https://miro.medium.com/v2/resize:fit:1050/1*QcbktmBAe-kQI-0TQ2R73w.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 680px;" width="700" /></picture></div></div></figure><h2 class="lv lw fl be lx ly lz ma mb mc md me mf lh mg mh mi ll mj mk ml lp mm mn mo mp bj" data-selectable-paragraph="" id="cab0" style="background-color: white; box-sizing: inherit; color: #292929; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 20px; line-height: 24px; margin: 1.72em 0px -0.31em;">REST API VS GraphQL API</h2><p class="pw-post-body-paragraph kw kx fl ky b kz mq lb lc ld mr lf lg lh ms lj lk ll mt ln lo lp mu lr ls lt ey bj" data-selectable-paragraph="" id="46f5" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 0.86em 0px -0.46em; word-break: break-word;">Let's see some commonalities and differences between REST and GraphQL APIs which will help to take a call on their uses.</p><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="40b1" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fm" style="box-sizing: inherit; font-weight: 700;">In REST:</span></p><ul class="" style="background-color: white; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; list-style: none none; margin: 0px; padding: 0px;"><li class="kw kx fl ky b kz la lb lc ld le lf lg nk li lj lk nl lm ln lo nm lq lr ls lt nn no np bj" data-selectable-paragraph="" id="ded0" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; letter-spacing: -0.003em; line-height: 32px; list-style-type: disc; margin-bottom: -0.46em; margin-left: 30px; margin-top: 2em; padding-left: 0px;">The query endpoint is simple i.e. <a class="af lu" href="https://localhost:7025/graphql?query={employees{id,name,deptName}}" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://localhost:7025/e</a>mployees?id=2</li><li class="kw kx fl ky b kz nq lb lc ld nr lf lg nk ns lj lk nl nt ln lo nm nu lr ls lt nn no np bj" data-selectable-paragraph="" id="db62" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; letter-spacing: -0.003em; line-height: 32px; list-style-type: disc; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.05em; padding-left: 0px;">The Server decides what data to send back as the response.</li><li class="kw kx fl ky b kz nq lb lc ld nr lf lg nk ns lj lk nl nt ln lo nm nu lr ls lt nn no np bj" data-selectable-paragraph="" id="4598" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; letter-spacing: -0.003em; line-height: 32px; list-style-type: disc; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.05em; padding-left: 0px;">Multiple API endpoints are required to pull multiple resources i.e. can’t pull employee as well as department data in a single API call.</li><li class="kw kx fl ky b kz nq lb lc ld nr lf lg nk ns lj lk nl nt ln lo nm nu lr ls lt nn no np bj" data-selectable-paragraph="" id="e398" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; letter-spacing: -0.003em; line-height: 32px; list-style-type: disc; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.05em; padding-left: 0px;">Easy to cache the response because of REST’s HTTP GET has a well-defined caching behavior leveraged by browsers, CDNs, proxies, web servers, etc.</li><li class="kw kx fl ky b kz nq lb lc ld nr lf lg nk ns lj lk nl nt ln lo nm nu lr ls lt nn no np bj" data-selectable-paragraph="" id="d4f4" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; letter-spacing: -0.003em; line-height: 32px; list-style-type: disc; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.05em; padding-left: 0px;">Doesn't require any special library to consume REST APIs</li></ul><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="9837" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fm" style="box-sizing: inherit; font-weight: 700;">In GraphQL:</span></p><ul class="" style="background-color: white; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; list-style: none none; margin: 0px; padding: 0px;"><li class="kw kx fl ky b kz la lb lc ld le lf lg nk li lj lk nl lm ln lo nm lq lr ls lt nn no np bj" data-selectable-paragraph="" id="0af2" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; letter-spacing: -0.003em; line-height: 32px; list-style-type: disc; margin-bottom: -0.46em; margin-left: 30px; margin-top: 2em; padding-left: 0px;">The Query is complex i.e. <a class="af lu" href="https://localhost:7025/graphql?query={employee(id:2){name,deptName}}" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://localhost:7025/graphql?query={employee(id:2){name,deptName}}</a></li><li class="kw kx fl ky b kz nq lb lc ld nr lf lg nk ns lj lk nl nt ln lo nm nu lr ls lt nn no np bj" data-selectable-paragraph="" id="dd97" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; letter-spacing: -0.003em; line-height: 32px; list-style-type: disc; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.05em; padding-left: 0px;">Clients decide what data to get back as a response.</li><li class="kw kx fl ky b kz nq lb lc ld nr lf lg nk ns lj lk nl nt ln lo nm nu lr ls lt nn no np bj" data-selectable-paragraph="" id="5a28" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; letter-spacing: -0.003em; line-height: 32px; list-style-type: disc; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.05em; padding-left: 0px;">Allow combining multiple resource queries into one API call. i.e. <a class="af lu" href="https://localhost:7025/graphql?query={employee(id:2){name,deptName}," rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://localhost:7025/graphql?query={employee(id:2){name,deptName},</a> department(id:1){deptName}}. This API query results in an employee with id=2 as well as the department with department id = 1.</li><li class="kw kx fl ky b kz nq lb lc ld nr lf lg nk ns lj lk nl nt ln lo nm nu lr ls lt nn no np bj" data-selectable-paragraph="" id="2ee1" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; letter-spacing: -0.003em; line-height: 32px; list-style-type: disc; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.05em; padding-left: 0px;">It supports caching too but not as easy because of query behavior.</li><li class="kw kx fl ky b kz nq lb lc ld nr lf lg nk ns lj lk nl nt ln lo nm nu lr ls lt nn no np bj" data-selectable-paragraph="" id="ee25" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; letter-spacing: -0.003em; line-height: 32px; list-style-type: disc; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.05em; padding-left: 0px;">It requires heavier tooling support, both on the client and server sides. This may not be suitable for simple CRUD operations.</li></ul><h2 class="lv lw fl be lx ly lz ma mb mc md me mf lh mg mh mi ll mj mk ml lp mm mn mo mp bj" data-selectable-paragraph="" id="d419" style="background-color: white; box-sizing: inherit; color: #292929; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 20px; line-height: 24px; margin: 1.72em 0px -0.31em;">How to implement</h2><p class="pw-post-body-paragraph kw kx fl ky b kz mq lb lc ld mr lf lg lh ms lj lk ll mt ln lo lp mu lr ls lt ey bj" data-selectable-paragraph="" id="b7d4" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 0.86em 0px -0.46em; word-break: break-word;">Let's see how to implement GraphQL API in ASP.NET Core through an example.</p><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="2bc4" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><em class="nv" style="box-sizing: inherit;">Problem Statement:</em> Need to develop APIs to query Employees and their departments. For demo purposes, I’m keeping the API simple and hardcoding the data hence there won’t be any db connections.</p><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="dea1" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">First thing, we would create an ASP.NET Core web API project and follow the steps below.</p><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="99e9" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fm" style="box-sizing: inherit; font-weight: 700;">Step 1:</span> Install the required Nuget packages.</p><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="4d41" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><em class="nv" style="box-sizing: inherit;">GraphQL.Server.All</em></p><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="bf2e" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">This Nuget package has everything you need.</p><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="97c0" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fm" style="box-sizing: inherit; font-weight: 700;">Step 2:</span> Define the model. Create a class called EmployeeModel.cs and add the code below to it.</p><pre class="my mz na nb nc nw nx ny bo nz oa ob" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="oc lw fl nx b bf od oe l of og" data-selectable-paragraph="" id="593c" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">record</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">Employee</span>(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;"><span class="hljs-built_in" style="box-sizing: inherit;">int</span> Id, <span class="hljs-built_in" style="box-sizing: inherit;">string</span> Name, <span class="hljs-built_in" style="box-sizing: inherit;">int</span> Age, <span class="hljs-built_in" style="box-sizing: inherit;">int</span> DeptId </span>)</span>;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">record</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">Department</span>(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;"><span class="hljs-built_in" style="box-sizing: inherit;">int</span> Id, <span class="hljs-built_in" style="box-sizing: inherit;">string</span> Name</span>)</span>;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">EmployeeDetails</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">int</span> Id { <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">get</span>; <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">set</span>; }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">string</span> Name { <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">get</span>; <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">set</span>; }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">int</span> Age { <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">get</span>; <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">set</span>; }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">string</span> DeptName { <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">get</span>; <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">set</span>; }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">EmployeeDetailsType</span> : <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">ObjectGraphType</span><<span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">EmployeeDetails</span>><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">EmployeeDetailsType</span>()</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> Field(x => x.Id);<br style="box-sizing: inherit;" /> Field(x => x.Name);<br style="box-sizing: inherit;" /> Field(x => x.Age);<br style="box-sizing: inherit;" /> Field(x => x.DeptName);<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }</span></pre><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="a9fb" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><em class="nv" style="box-sizing: inherit;">EmployeeDetails </em>is the model for API response but GraphQL can’t understand this hence we need to create a mapping and as a result, we create <em class="nv" style="box-sizing: inherit;">EmployeeDetailsType </em>Field mapping<em class="nv" style="box-sizing: inherit;"> </em>class.</p><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="102a" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fm" style="box-sizing: inherit; font-weight: 700;">Step 3:</span> Create the Employee Service class, which caters to the data from the data source. For this example we hardcode. Create the EmployeeService.cs class and add the below code.</p><pre class="my mz na nb nc nw nx ny bo nz oa ob" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="oc lw fl nx b bf od oe l of og" data-selectable-paragraph="" id="ba47" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">interface</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">IEmployeeService</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> List<EmployeeDetails> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">GetEmployees</span>()</span>;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> List<EmployeeDetails> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">GetEmployee</span>(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;"><span class="hljs-built_in" style="box-sizing: inherit;">int</span> empId</span>)</span>;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> List<EmployeeDetails> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">GetEmployeesByDepartment</span>(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;"><span class="hljs-built_in" style="box-sizing: inherit;">int</span> deptId</span>)</span>;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">EmployeeService</span> : <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">IEmployeeService</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">EmployeeService</span>()</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">private</span> List<Employee> employees = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> List<Employee><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> Employee(<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">1</span>, <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Tom"</span>, <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">25</span>, <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">1</span>),<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> Employee(<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">2</span>, <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Henry"</span>, <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">28</span>, <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">1</span>),<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> Employee(<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">3</span>, <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Steve"</span>, <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">30</span>, <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">2</span>),<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> Employee(<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">4</span>, <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Ben"</span>, <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">26</span>, <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">2</span>),<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> Employee(<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">5</span>, <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"John"</span>, <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">35</span>, <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">3</span>),<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> };<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">private</span> List<Department> departments = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> List<Department><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> Department(<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">1</span>, <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"IT"</span>),<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> Department(<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">2</span>, <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Finance"</span>),<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> Department(<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">3</span>, <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"HR"</span>),<br style="box-sizing: inherit;" /> };<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> List<EmployeeDetails> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">GetEmployees</span>()</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">return</span> employees.Select(emp => <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> EmployeeDetails { <br style="box-sizing: inherit;" /> Id = emp.Id,<br style="box-sizing: inherit;" /> Name = emp.Name,<br style="box-sizing: inherit;" /> Age = emp.Age,<br style="box-sizing: inherit;" /> DeptName = departments.First(d => d.Id == emp.DeptId).Name,<br style="box-sizing: inherit;" /> }).ToList();<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> List<EmployeeDetails> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">GetEmployee</span>(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;"><span class="hljs-built_in" style="box-sizing: inherit;">int</span> empId</span>)</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">return</span> employees.Where(emp => emp.Id == empId).Select(emp => <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> EmployeeDetails<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> Id = emp.Id,<br style="box-sizing: inherit;" /> Name = emp.Name,<br style="box-sizing: inherit;" /> Age = emp.Age,<br style="box-sizing: inherit;" /> DeptName = departments.First(d => d.Id == emp.DeptId).Name,<br style="box-sizing: inherit;" /> }).ToList();<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> List<EmployeeDetails> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">GetEmployeesByDepartment</span>(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;"><span class="hljs-built_in" style="box-sizing: inherit;">int</span> deptId</span>)</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">return</span> employees.Where(emp => emp.DeptId == deptId).Select(emp => <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> EmployeeDetails<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> Id = emp.Id,<br style="box-sizing: inherit;" /> Name = emp.Name,<br style="box-sizing: inherit;" /> Age = emp.Age,<br style="box-sizing: inherit;" /> DeptName = departments.First(d => d.Id == deptId).Name,<br style="box-sizing: inherit;" /> }).ToList();<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }</span></pre><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="bf3d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">The above code is self-explanatory hence moving to the next step.</p><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="e5d3" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fm" style="box-sizing: inherit; font-weight: 700;">Step 4:</span> Here we will create the GraphQL Query which is the key for GraphQL APIs. Add a class EmployeeQuery.cs and the below code to it.</p><pre class="my mz na nb nc nw nx ny bo nz oa ob" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="oc lw fl nx b bf od oe l of og" data-selectable-paragraph="" id="ce8d" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">EmployeeQuery</span> : <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">ObjectGraphType</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">EmployeeQuery</span>(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">IEmployeeService employeeService</span>)</span> {<br style="box-sizing: inherit;" /> Field<ListGraphType<EmployeeDetailsType>>(Name = <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Employees"</span>, resolve : x => employeeService.GetEmployees());<br style="box-sizing: inherit;" /> Field<ListGraphType<EmployeeDetailsType>>(Name = <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Employee"</span>, <br style="box-sizing: inherit;" /> arguments: <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> QueryArguments(<span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> QueryArgument<IntGraphType> { Name = <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"id"</span>}),<br style="box-sizing: inherit;" /> resolve: x => employeeService.GetEmployee(x.GetArgument<<span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">int</span>>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"id"</span>)));<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">EmployeeDetailsSchema</span> : <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">Schema</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">EmployeeDetailsSchema</span>(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">IServiceProvider serviceProvider</span>) : <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">base</span>(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">serviceProvider</span>)</span> {<br style="box-sizing: inherit;" /> Query = serviceProvider.GetRequiredService<EmployeeQuery>();<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }</span></pre><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="8b8a" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Here we do two things, One, we create the GraphQL Query (i.e <em class="nv" style="box-sizing: inherit;">EmployeeQuery</em>) mapping against our EmployeeService methods to fetch data and the syntax is:<br style="box-sizing: inherit;" />Field<ListGraphType<{modelmappingtype class}>(Name, arguments, resolve);<br style="box-sizing: inherit;" />Arguments are optional if not needed.</p><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="3fe9" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In the above code, we have created two query mapping to fetch all employees and employees with employee IDs.</p><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="f713" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">The second part is to map the Employee query (<em class="nv" style="box-sizing: inherit;">EmployeeQuery) </em>class to the GraphQL schema by creating a class (<em class="nv" style="box-sizing: inherit;">EmployeeDetailsSchema</em>) that inherits <em class="nv" style="box-sizing: inherit;">Schema</em>.</p><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="99ba" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fm" style="box-sizing: inherit; font-weight: 700;">Step 5:</span> Register the types and services including GraphQL to the dependency container in Program.cs class.</p><pre class="my mz na nb nc nw nx ny bo nz oa ob" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="oc lw fl nx b bf od oe l of og" data-selectable-paragraph="" id="7e2b" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">builder.Services.AddSingleton<IEmployeeService, EmployeeService>();<br style="box-sizing: inherit;" />builder.Services.AddSingleton<EmployeeDetailsType>();<br style="box-sizing: inherit;" />builder.Services.AddSingleton<EmployeeQuery>();<br style="box-sizing: inherit;" />builder.Services.AddSingleton<ISchema, EmployeeDetailsSchema>();<br style="box-sizing: inherit;" />builder.Services.AddGraphQL(b => b<br style="box-sizing: inherit;" /> .AddAutoSchema<EmployeeQuery>() <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">// schema</span><br style="box-sizing: inherit;" /> .AddSystemTextJson()); <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">// serializer</span></span></pre><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="9771" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fm" style="box-sizing: inherit; font-weight: 700;">Step 6:</span> As part of the last step, we will register the GraphQL endpoint and playground (it is like Swagger) to the application.</p><pre class="my mz na nb nc nw nx ny bo nz oa ob" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="oc lw fl nx b bf od oe l of og" data-selectable-paragraph="" id="fcb9" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">app.UseGraphQL<ISchema>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"/graphql"</span>); <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">// url to host GraphQL endpoint</span><br style="box-sizing: inherit;" />app.UseGraphQLPlayground(<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"/"</span>, <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">// url to host Playground at</span><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> GraphQL.Server.Ui.Playground.PlaygroundOptions<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> GraphQLEndPoint = <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"/graphql"</span>, <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">// url of GraphQL endpoint</span><br style="box-sizing: inherit;" /> SubscriptionsEndPoint = <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"/graphql"</span>, <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">// url of GraphQL endpoint</span><br style="box-sizing: inherit;" /> });</span></pre><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="1e3e" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now we run the application and the output you would see as:</p><figure class="my mz na nb nc nd mv mw paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="ne nf dj ng bg nh" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 680px; z-index: auto;" tabindex="0"><div class="mv mw oh" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1919px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*aYEmsr3mfh0gK8aK3DeeOA.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*aYEmsr3mfh0gK8aK3DeeOA.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*aYEmsr3mfh0gK8aK3DeeOA.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*aYEmsr3mfh0gK8aK3DeeOA.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*aYEmsr3mfh0gK8aK3DeeOA.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*aYEmsr3mfh0gK8aK3DeeOA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*aYEmsr3mfh0gK8aK3DeeOA.png 1400w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/1*aYEmsr3mfh0gK8aK3DeeOA.png 640w, https://miro.medium.com/v2/resize:fit:720/1*aYEmsr3mfh0gK8aK3DeeOA.png 720w, https://miro.medium.com/v2/resize:fit:750/1*aYEmsr3mfh0gK8aK3DeeOA.png 750w, https://miro.medium.com/v2/resize:fit:786/1*aYEmsr3mfh0gK8aK3DeeOA.png 786w, https://miro.medium.com/v2/resize:fit:828/1*aYEmsr3mfh0gK8aK3DeeOA.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*aYEmsr3mfh0gK8aK3DeeOA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*aYEmsr3mfh0gK8aK3DeeOA.png 1400w" style="box-sizing: inherit;"></source><img alt="" class="bg ni nj c" height="323" loading="lazy" role="presentation" src="https://miro.medium.com/v2/resize:fit:1050/1*aYEmsr3mfh0gK8aK3DeeOA.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 680px;" width="700" /></picture></div></div></figure><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="9175" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">From the right-side tab options, you will be able to see the Schema and the Docs which tell about queries details as:</p><figure class="my mz na nb nc nd mv mw paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="ne nf dj ng bg nh" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 680px; z-index: auto;" tabindex="0"><div class="mv mw oi" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 717px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*fwFG_nEd57iyY61rKJef3g.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*fwFG_nEd57iyY61rKJef3g.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*fwFG_nEd57iyY61rKJef3g.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*fwFG_nEd57iyY61rKJef3g.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*fwFG_nEd57iyY61rKJef3g.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*fwFG_nEd57iyY61rKJef3g.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*fwFG_nEd57iyY61rKJef3g.png 1400w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/1*fwFG_nEd57iyY61rKJef3g.png 640w, https://miro.medium.com/v2/resize:fit:720/1*fwFG_nEd57iyY61rKJef3g.png 720w, https://miro.medium.com/v2/resize:fit:750/1*fwFG_nEd57iyY61rKJef3g.png 750w, https://miro.medium.com/v2/resize:fit:786/1*fwFG_nEd57iyY61rKJef3g.png 786w, https://miro.medium.com/v2/resize:fit:828/1*fwFG_nEd57iyY61rKJef3g.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*fwFG_nEd57iyY61rKJef3g.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*fwFG_nEd57iyY61rKJef3g.png 1400w" style="box-sizing: inherit;"></source><img alt="" class="bg ni nj c" height="694" loading="lazy" role="presentation" src="https://miro.medium.com/v2/resize:fit:1050/1*fwFG_nEd57iyY61rKJef3g.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 680px;" width="700" /></picture></div></div></figure><figure class="my mz na nb nc nd mv mw paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="ne nf dj ng bg nh" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 680px; z-index: auto;" tabindex="0"><div class="mv mw oj" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 893px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*JSnsV5xpUF3AXBzwe1WpJw.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*JSnsV5xpUF3AXBzwe1WpJw.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*JSnsV5xpUF3AXBzwe1WpJw.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*JSnsV5xpUF3AXBzwe1WpJw.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*JSnsV5xpUF3AXBzwe1WpJw.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*JSnsV5xpUF3AXBzwe1WpJw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*JSnsV5xpUF3AXBzwe1WpJw.png 1400w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/1*JSnsV5xpUF3AXBzwe1WpJw.png 640w, https://miro.medium.com/v2/resize:fit:720/1*JSnsV5xpUF3AXBzwe1WpJw.png 720w, https://miro.medium.com/v2/resize:fit:750/1*JSnsV5xpUF3AXBzwe1WpJw.png 750w, https://miro.medium.com/v2/resize:fit:786/1*JSnsV5xpUF3AXBzwe1WpJw.png 786w, https://miro.medium.com/v2/resize:fit:828/1*JSnsV5xpUF3AXBzwe1WpJw.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*JSnsV5xpUF3AXBzwe1WpJw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*JSnsV5xpUF3AXBzwe1WpJw.png 1400w" style="box-sizing: inherit;"></source><img alt="" class="bg ni nj c" height="508" loading="lazy" role="presentation" src="https://miro.medium.com/v2/resize:fit:1050/1*JSnsV5xpUF3AXBzwe1WpJw.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 680px;" width="700" /></picture></div></div></figure><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="4417" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">And this is how we will make the query.</p><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="0d6d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fm" style="box-sizing: inherit; font-weight: 700;">Query 1:</span> Get all Employees with only Employee Name and their Department Name.</p><figure class="my mz na nb nc nd mv mw paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="ne nf dj ng bg nh" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 680px; z-index: auto;" tabindex="0"><div class="mv mw ok" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1920px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*kpTUCXjyS09sPT-XlI5a3A.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*kpTUCXjyS09sPT-XlI5a3A.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*kpTUCXjyS09sPT-XlI5a3A.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*kpTUCXjyS09sPT-XlI5a3A.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*kpTUCXjyS09sPT-XlI5a3A.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*kpTUCXjyS09sPT-XlI5a3A.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*kpTUCXjyS09sPT-XlI5a3A.png 1400w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/1*kpTUCXjyS09sPT-XlI5a3A.png 640w, https://miro.medium.com/v2/resize:fit:720/1*kpTUCXjyS09sPT-XlI5a3A.png 720w, https://miro.medium.com/v2/resize:fit:750/1*kpTUCXjyS09sPT-XlI5a3A.png 750w, https://miro.medium.com/v2/resize:fit:786/1*kpTUCXjyS09sPT-XlI5a3A.png 786w, https://miro.medium.com/v2/resize:fit:828/1*kpTUCXjyS09sPT-XlI5a3A.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*kpTUCXjyS09sPT-XlI5a3A.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*kpTUCXjyS09sPT-XlI5a3A.png 1400w" style="box-sizing: inherit;"></source><img alt="" class="bg ni nj c" height="324" loading="lazy" role="presentation" src="https://miro.medium.com/v2/resize:fit:1050/1*kpTUCXjyS09sPT-XlI5a3A.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 680px;" width="700" /></picture></div></div></figure><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="01dc" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ky fm" style="box-sizing: inherit; font-weight: 700;">Query 2: </span>Combining two queries: Get all Employees with only Employee Name and their Department Name and the employee with employee id as 2.</p><figure class="my mz na nb nc nd mv mw paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="ne nf dj ng bg nh" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 680px; z-index: auto;" tabindex="0"><div class="mv mw ok" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1920px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*rP5jqhUXoUiwToPZt_uftA.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*rP5jqhUXoUiwToPZt_uftA.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*rP5jqhUXoUiwToPZt_uftA.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*rP5jqhUXoUiwToPZt_uftA.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*rP5jqhUXoUiwToPZt_uftA.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*rP5jqhUXoUiwToPZt_uftA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*rP5jqhUXoUiwToPZt_uftA.png 1400w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/1*rP5jqhUXoUiwToPZt_uftA.png 640w, https://miro.medium.com/v2/resize:fit:720/1*rP5jqhUXoUiwToPZt_uftA.png 720w, https://miro.medium.com/v2/resize:fit:750/1*rP5jqhUXoUiwToPZt_uftA.png 750w, https://miro.medium.com/v2/resize:fit:786/1*rP5jqhUXoUiwToPZt_uftA.png 786w, https://miro.medium.com/v2/resize:fit:828/1*rP5jqhUXoUiwToPZt_uftA.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*rP5jqhUXoUiwToPZt_uftA.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*rP5jqhUXoUiwToPZt_uftA.png 1400w" style="box-sizing: inherit;"></source><img alt="" class="bg ni nj c" height="300" loading="lazy" role="presentation" src="https://miro.medium.com/v2/resize:fit:1050/1*rP5jqhUXoUiwToPZt_uftA.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 680px;" width="700" /></picture></div></div></figure><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="fa6f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">To know more about the GraphQL.NET library please visit: <a class="af lu" href="https://github.com/graphql-dotnet/server" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://github.com/graphql-dotnet/server</a></p><h2 class="lv lw fl be lx ly lz ma mb mc md me mf lh mg mh mi ll mj mk ml lp mm mn mo mp bj" data-selectable-paragraph="" id="35e5" style="background-color: white; box-sizing: inherit; color: #292929; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 20px; line-height: 24px; margin: 1.72em 0px -0.31em;">Bonus</h2><p class="pw-post-body-paragraph kw kx fl ky b kz mq lb lc ld mr lf lg lh ms lj lk ll mt ln lo lp mu lr ls lt ey bj" data-selectable-paragraph="" id="f367" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 0.86em 0px -0.46em; word-break: break-word;">You can get the complete code used in this example here: <a class="af lu" href="https://github.com/binodmahto/FunProjects/tree/main/GraphQL/graphqlapidemo" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://github.com/binodmahto/FunProjects/tree/main/GraphQL/graphqlapidemo</a><br style="box-sizing: inherit;" />This also has the WEB API REST implementation of the same endpoints which we discussed here in case you want to compare the code for REST API and GraphQL API side by side.</p><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="1b96" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Also here is an example to consume the API through HTTP GET and POST.</p><h2 class="lv lw fl be lx ly lz ma mb mc md me mf lh mg mh mi ll mj mk ml lp mm mn mo mp bj" data-selectable-paragraph="" id="0065" style="background-color: white; box-sizing: inherit; color: #292929; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 20px; line-height: 24px; margin: 1.72em 0px -0.31em;">HTTP GET</h2><figure class="my mz na nb nc nd mv mw paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="ne nf dj ng bg nh" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 680px; z-index: auto;" tabindex="0"><div class="mv mw ol" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1258px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*wOfyV5tvYPL3AHwxQ4SLNw.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*wOfyV5tvYPL3AHwxQ4SLNw.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*wOfyV5tvYPL3AHwxQ4SLNw.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*wOfyV5tvYPL3AHwxQ4SLNw.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*wOfyV5tvYPL3AHwxQ4SLNw.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*wOfyV5tvYPL3AHwxQ4SLNw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*wOfyV5tvYPL3AHwxQ4SLNw.png 1400w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/1*wOfyV5tvYPL3AHwxQ4SLNw.png 640w, https://miro.medium.com/v2/resize:fit:720/1*wOfyV5tvYPL3AHwxQ4SLNw.png 720w, https://miro.medium.com/v2/resize:fit:750/1*wOfyV5tvYPL3AHwxQ4SLNw.png 750w, https://miro.medium.com/v2/resize:fit:786/1*wOfyV5tvYPL3AHwxQ4SLNw.png 786w, https://miro.medium.com/v2/resize:fit:828/1*wOfyV5tvYPL3AHwxQ4SLNw.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*wOfyV5tvYPL3AHwxQ4SLNw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*wOfyV5tvYPL3AHwxQ4SLNw.png 1400w" style="box-sizing: inherit;"></source><img alt="" class="bg ni nj c" height="475" loading="lazy" role="presentation" src="https://miro.medium.com/v2/resize:fit:1050/1*wOfyV5tvYPL3AHwxQ4SLNw.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 680px;" width="700" /></picture></div></div></figure><p class="pw-post-body-paragraph kw kx fl ky b kz la lb lc ld le lf lg lh li lj lk ll lm ln lo lp lq lr ls lt ey bj" data-selectable-paragraph="" id="5463" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">We need to pass the json query as part of query string with a syntax ?query= {json query string}</p><h2 class="lv lw fl be lx ly lz ma mb mc md me mf lh mg mh mi ll mj mk ml lp mm mn mo mp bj" data-selectable-paragraph="" id="29c1" style="background-color: white; box-sizing: inherit; color: #292929; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 20px; line-height: 24px; margin: 1.72em 0px -0.31em;">HTTP POST</h2><p class="pw-post-body-paragraph kw kx fl ky b kz mq lb lc ld mr lf lg lh ms lj lk ll mt ln lo lp mu lr ls lt ey bj" data-selectable-paragraph="" id="d64c" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 0.86em 0px -0.46em; word-break: break-word;">In case of a POST request, we will follow the syntax for the same above query as:</p><figure class="my mz na nb nc nd mv mw paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="ne nf dj ng bg nh" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 680px; z-index: auto;" tabindex="0"><div class="mv mw om" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1275px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*YYQool2T7qj5nIiMzB_jBg.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*YYQool2T7qj5nIiMzB_jBg.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*YYQool2T7qj5nIiMzB_jBg.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*YYQool2T7qj5nIiMzB_jBg.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*YYQool2T7qj5nIiMzB_jBg.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*YYQool2T7qj5nIiMzB_jBg.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*YYQool2T7qj5nIiMzB_jBg.png 1400w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/v2/resize:fit:640/1*YYQool2T7qj5nIiMzB_jBg.png 640w, https://miro.medium.com/v2/resize:fit:720/1*YYQool2T7qj5nIiMzB_jBg.png 720w, https://miro.medium.com/v2/resize:fit:750/1*YYQool2T7qj5nIiMzB_jBg.png 750w, https://miro.medium.com/v2/resize:fit:786/1*YYQool2T7qj5nIiMzB_jBg.png 786w, https://miro.medium.com/v2/resize:fit:828/1*YYQool2T7qj5nIiMzB_jBg.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*YYQool2T7qj5nIiMzB_jBg.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*YYQool2T7qj5nIiMzB_jBg.png 1400w" style="box-sizing: inherit;"></source><img alt="" class="bg ni nj c" height="434" loading="lazy" role="presentation" src="https://miro.medium.com/v2/resize:fit:1050/1*YYQool2T7qj5nIiMzB_jBg.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 680px;" width="700" /></picture></div></div></figure><p class="pw-post-body-paragraph xc xd th jv b tp xe xf xg ts xh xi xj jf xk xl xm jk xn xo xp jp xq xr xs xt io bj" data-selectable-paragraph="" id="f169" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span style="font-weight: 700; letter-spacing: -0.06px;">Hope you enjoyed the content, follow me for more like this, and please don’t forget to LIKE it. Happy programming.</span></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-23209606824247130082023-04-26T16:29:00.001+05:302023-05-03T20:36:21.406+05:30CI/CD with GitHub Actions to deploy background jobs as Azure WebJobs<p> <span face="source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif" style="background-color: white; color: #292929; font-size: 20px; letter-spacing: -0.003em;">A background job is a task that we need to run in the background like a scheduled job and the Azure WebJobs provides this capability as part of the Azure App Service.</span></p><p class="pw-post-body-paragraph hv hw hm hx b hy hz ia ib ic id ie if ig ih ii ij ik il im in io ip iq ir is hf bj" data-selectable-paragraph="" id="ee32" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="hx hn" style="box-sizing: inherit; font-weight: 700;">Azure WebJobs</span> is the feature of Azure AppService where you can run your background tasks along with your web application deployed in App Service with NO additional cost.</p><p class="pw-post-body-paragraph hv hw hm hx b hy hz ia ib ic id ie if ig ih ii ij ik il im in io ip iq ir is hf bj" data-selectable-paragraph="" id="9f5f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">To know more about WebJobs please read through this article here: <a class="af it" href="https://learn.microsoft.com/en-us/azure/app-service/webjobs-create" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://learn.microsoft.com/en-us/azure/app-service/webjobs-create</a></p><p class="pw-post-body-paragraph hv hw hm hx b hy hz ia ib ic id ie if ig ih ii ij ik il im in io ip iq ir is hf bj" data-selectable-paragraph="" id="b79d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In this article, we will talk about how to automate the background task deployment to the Azure AppService WebJob along with the web application. Please note that you can also deploy only the background job as a web job in the Azure app service too.</p><p class="pw-post-body-paragraph hv hw hm hx b hy hz ia ib ic id ie if ig ih ii ij ik il im in io ip iq ir is hf bj" data-selectable-paragraph="" id="af9d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">If you would have followed me on my previous article about automating the web application deployment to the Azure AppService here “<a class="af it" href="https://binodmahto.blogspot.com/2022/08/cicd-with-github-actions-to-deploy.html" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank"><span class="hx hn" style="box-sizing: inherit; font-weight: 700;">CI/CD with GitHub Actions to deploy Applications to Azure App Service</span></a>” then you have almost got this to 90%. Yes, it is 90% because the deployment and the process are all the same and for rest 10% all you have to do is, publish your background tasks to a specific folder along with your web application.</p><blockquote class="iu iv iw" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="hv hw ix hx b hy hz ia ib ic id ie if iy ih ii ij iz il im in ja ip iq ir is hf bj" data-selectable-paragraph="" id="aac7" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Note: If you are hosting the web application along with web job then you must have to host it together in a single pipeline as I’ll be showing here or else the wwwroot folder will get overrriden with lastest deployment and this happens because everything goes into the <span class="hx hn" style="box-sizing: inherit; font-weight: 700;">wwwroot </span>folder. Web application content will got directly to the wwwroot folder and background task will insided wwwroot/App_Data/Jobs/Triggered/{your Job Name}</p></blockquote><p class="pw-post-body-paragraph hv hw hm hx b hy hz ia ib ic id ie if ig ih ii ij ik il im in io ip iq ir is hf bj" data-selectable-paragraph="" id="dfd2" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">For this example, I’ve got a simple .net console application as a background task which I’m going to deploy as a web Job.</p><p class="pw-post-body-paragraph hv hw hm hx b hy hz ia ib ic id ie if ig ih ii ij ik il im in io ip iq ir is hf bj" data-selectable-paragraph="" id="24f9" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">To achieve this, We need to modify <span class="hx hn" style="box-sizing: inherit; font-weight: 700;">Step 7</span> from my previous article to prepare the app settings. In my case, I’m adding one more execution step in the pipeline as I’m deploying the web application and web job both. So the Step 7 code will finally be as:</p><pre class="jb jc jd je fu jf jg jh bo ji jj jk" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="jl jm hm jg b bf jn jo l jp jq" data-selectable-paragraph="" id="fee5" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">jobs:</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">build:</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">runs-on:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">windows-latest</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">environment:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Production</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">steps:</span><br style="box-sizing: inherit;" /> <span class="hljs-bullet" style="box-sizing: inherit; color: #1c00cf;">-</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">uses:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">actions/checkout@v2</span><br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> <span class="hljs-bullet" style="box-sizing: inherit; color: #1c00cf;">-</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">name:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Replace</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">token</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">for</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">appsettings.Production.json</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">uses:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">cschleiden/replace-tokens@v1.1</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">with:</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">tokenPrefix:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'#{'</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">tokenSuffix:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'}#'</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">files:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'["src/DemoAPI/appsettings.Production.json"]'</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">env:</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">ConnectionString:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">${{secrets.CONNECTION_STRING}}</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-bullet" style="box-sizing: inherit; color: #1c00cf;">-</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">name:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Replace</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">token</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">for</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">web</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">job</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">appsettings.Production.json</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">uses:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">cschleiden/replace-tokens@v1.1</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">with:</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">tokenPrefix:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'#{'</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">tokenSuffix:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'}#'</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">files:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'["webjob/DemoTask/appsettings.Production.json"]'</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">env:</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">ConnectionString:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">${{secrets.CONNECTION_STRING}}</span></span></pre><p class="pw-post-body-paragraph hv hw hm hx b hy hz ia ib ic id ie if ig ih ii ij ik il im in io ip iq ir is hf bj" data-selectable-paragraph="" id="fc25" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In the above code, I added the extra step in the build job to modify the connection string of the background task “DemoTask” which is a console application for me inside a folder called “webjob” from my code repo.</p><p class="pw-post-body-paragraph hv hw hm hx b hy hz ia ib ic id ie if ig ih ii ij ik il im in io ip iq ir is hf bj" data-selectable-paragraph="" id="a408" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Next, we will modify <span class="hx hn" style="box-sizing: inherit; font-weight: 700;">Step 8</span> from my previous article, to add a new step to build and publish the console application as a background task i.e. web job. Here is the modified step 8:</p><pre class="jb jc jd je fu jf jg jh bo ji jj jk" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #242424; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="jl jm hm jg b bf jn jo l jp jq" data-selectable-paragraph="" id="9d1e" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"> <span class="hljs-bullet" style="box-sizing: inherit; color: #1c00cf;">-</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">name:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Set</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">up</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">.NET</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Core</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">uses:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">actions/setup-dotnet@v1</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">with:</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">dotnet-version:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">${{</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">env.DOTNET_VERSION</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">}}</span><br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">#include-prerelease: true</span><br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> <span class="hljs-bullet" style="box-sizing: inherit; color: #1c00cf;">-</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">name:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Build</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">projects</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">run:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">|<br style="box-sizing: inherit;" /> dotnet build src/DemoAPI/DemoAPI.sln --configuration Release<br style="box-sizing: inherit;" /></span> <br style="box-sizing: inherit;" /> <span class="hljs-bullet" style="box-sizing: inherit; color: #1c00cf;">-</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">name:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Publish</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Project</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">run:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">|<br style="box-sizing: inherit;" /> dotnet publish src/DemoAPI/DemoAPI.csproj -c Release -o ${{env.DOTNET_ROOT}}/myapp<br style="box-sizing: inherit;" /></span> <br style="box-sizing: inherit;" /> <span class="hljs-bullet" style="box-sizing: inherit; color: #1c00cf;">-</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">name:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Build</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">projects</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">run:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">|<br style="box-sizing: inherit;" /> dotnet build webjob/DemoTask/DemoTask.sln --configuration Release<br style="box-sizing: inherit;" /></span> <br style="box-sizing: inherit;" /> <span class="hljs-bullet" style="box-sizing: inherit; color: #1c00cf;">-</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">name:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Publish</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Project</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">run:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">|<br style="box-sizing: inherit;" /> dotnet publish webjob/DemoTask/DemoTask.csproj -c Release -o ${{env.DOTNET_ROOT}}/myapp/App_Data/Jobs/Triggered/${{ env.webJobName }}<br style="box-sizing: inherit;" /></span><br style="box-sizing: inherit;" /> <span class="hljs-bullet" style="box-sizing: inherit; color: #1c00cf;">-</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">name:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Upload</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">artifact</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">for</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">deployment</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">job</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">uses:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">actions/upload-artifact@v2</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">with:</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">name:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">.net-app</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">path:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">./myapp</span></span></pre><p class="pw-post-body-paragraph hv hw hm hx b hy hz ia ib ic id ie if ig ih ii ij ik il im in io ip iq ir is hf bj" data-selectable-paragraph="" id="2b13" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In the above code, if you observed, the background task is being published in a specific folder as “${{env.DOTNET_ROOT}}/myapp/App_Data/Jobs/Triggered/${{ env.webJobName }}”</p><p class="pw-post-body-paragraph hv hw hm hx b hy hz ia ib ic id ie if ig ih ii ij ik il im in io ip iq ir is hf bj" data-selectable-paragraph="" id="95d8" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">So this is the only catch that, your background task must be in App_Data/Jobs/Triggered/{job_name} inside wwwroot which is the base path.</p><p class="pw-post-body-paragraph hv hw hm hx b hy hz ia ib ic id ie if ig ih ii ij ik il im in io ip iq ir is hf bj" data-selectable-paragraph="" id="d993" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Thats all. We are done and this is how the folder structure will look like in Azure App Service.</p><figure class="jb jc jd je fu js fi fj paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="jt ju dj jv bg jw" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 680px; z-index: auto;" tabindex="0"><div class="fi fj jr" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 461px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 461px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*JMxYLP0BZUaJiPPa3pxxNQ.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*JMxYLP0BZUaJiPPa3pxxNQ.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*JMxYLP0BZUaJiPPa3pxxNQ.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*JMxYLP0BZUaJiPPa3pxxNQ.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*JMxYLP0BZUaJiPPa3pxxNQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*JMxYLP0BZUaJiPPa3pxxNQ.png 1100w, https://miro.medium.com/v2/resize:fit:922/format:webp/1*JMxYLP0BZUaJiPPa3pxxNQ.png 922w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 461px" srcset="https://miro.medium.com/v2/resize:fit:640/1*JMxYLP0BZUaJiPPa3pxxNQ.png 640w, https://miro.medium.com/v2/resize:fit:720/1*JMxYLP0BZUaJiPPa3pxxNQ.png 720w, https://miro.medium.com/v2/resize:fit:750/1*JMxYLP0BZUaJiPPa3pxxNQ.png 750w, https://miro.medium.com/v2/resize:fit:786/1*JMxYLP0BZUaJiPPa3pxxNQ.png 786w, https://miro.medium.com/v2/resize:fit:828/1*JMxYLP0BZUaJiPPa3pxxNQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*JMxYLP0BZUaJiPPa3pxxNQ.png 1100w, https://miro.medium.com/v2/resize:fit:922/1*JMxYLP0BZUaJiPPa3pxxNQ.png 922w" style="box-sizing: inherit;"></source><img alt="" class="bg jx jy c" height="512" loading="lazy" role="presentation" src="https://miro.medium.com/v2/resize:fit:692/1*JMxYLP0BZUaJiPPa3pxxNQ.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 461px;" width="461" /></picture></div></div></figure><p class="pw-post-body-paragraph hv hw hm hx b hy hz ia ib ic id ie if ig ih ii ij ik il im in io ip iq ir is hf bj" data-selectable-paragraph="" id="189f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">To configure your background task schedule and all, either you can do it directly from the portal Or you can do it through code using web job sdk. Check out the details here: <a class="af it" href="https://learn.microsoft.com/en-us/azure/app-service/webjobs-sdk-how-to" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://learn.microsoft.com/en-us/azure/app-service/webjobs-sdk-how-to</a></p><p class="pw-post-body-paragraph hv hw hm hx b hy hz ia ib ic id ie if ig ih ii ij ik il im in io ip iq ir is hf bj" data-selectable-paragraph="" id="189f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span style="font-weight: 700; letter-spacing: -0.06px;">Hope you enjoyed the content, follow me for more like this, and please don’t forget to LIKE it. Happy programming.</span></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-27849744626686577142023-01-23T21:34:00.006+05:302023-01-23T21:36:08.558+05:30API load testing using k6<p> <span face="source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif" style="background-color: white; color: #292929; font-size: 20px; letter-spacing: -0.003em;">Grafana k6 is an open-source load testing tool. K6 allows you to test the reliability and performance of your APIs and catch performance regressions and problems earlier.</span></p><figure class="jc jd je jf fs jg fg fh paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="jh ji di jj bf jk" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 680px; z-index: auto;" tabindex="0"><div class="fg fh jb" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1110px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/max/640/0*f-n8mYjmNKg-hnXn 640w, https://miro.medium.com/max/720/0*f-n8mYjmNKg-hnXn 720w, https://miro.medium.com/max/750/0*f-n8mYjmNKg-hnXn 750w, https://miro.medium.com/max/786/0*f-n8mYjmNKg-hnXn 786w, https://miro.medium.com/max/828/0*f-n8mYjmNKg-hnXn 828w, https://miro.medium.com/max/1100/0*f-n8mYjmNKg-hnXn 1100w, https://miro.medium.com/max/1400/0*f-n8mYjmNKg-hnXn 1400w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/max/640/0*f-n8mYjmNKg-hnXn 640w, https://miro.medium.com/max/720/0*f-n8mYjmNKg-hnXn 720w, https://miro.medium.com/max/750/0*f-n8mYjmNKg-hnXn 750w, https://miro.medium.com/max/786/0*f-n8mYjmNKg-hnXn 786w, https://miro.medium.com/max/828/0*f-n8mYjmNKg-hnXn 828w, https://miro.medium.com/max/1100/0*f-n8mYjmNKg-hnXn 1100w, https://miro.medium.com/max/1400/0*f-n8mYjmNKg-hnXn 1400w" style="box-sizing: inherit;"></source><img alt="" class="bf jl jm c" height="505" loading="eager" role="presentation" src="https://miro.medium.com/max/700/0*f-n8mYjmNKg-hnXn" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 680px;" width="700" /></picture></div></div></figure><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="7865" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">By reading this article, you will learn how to perform load testing on RESTful APIs using K6.</p><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="1408" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="if hh" style="box-sizing: inherit; font-weight: 700;">Setup<br style="box-sizing: inherit;" /></span>K6 has a standalone installer/package for Linux, macOS, and Windows and also supports a docker container.</p><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="629f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="if hh" style="box-sizing: inherit; font-weight: 700;">Windows</span><br style="box-sizing: inherit;" />For Windows users, please use the Choco (chocolatey package manager) or Winget (Window package manager, which default comes with Windows OS).<br style="box-sizing: inherit;" />To install open a command prompt and run the command as</p><pre class="jc jd je jf fs jn jo jp bn jq jr bi" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="js jt hg jo b be ju jv l jw jx" data-selectable-paragraph="" id="d01a" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">--<span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">for</span> choco<br style="box-sizing: inherit;" />choco install k6<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" />--<span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">for</span> winget<br style="box-sizing: inherit;" />winget install k6</span></pre><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="7fb9" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Alternatively, you can download and run <a class="ae jy" href="https://dl.k6.io/msi/k6-latest-amd64.msi" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">the latest official installer</a>.</p><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="aff3" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">If you are using Visual Studio Code, you can use the extension “k6 for Visual Studio Code” to execute your script directly from visual studio code.</p><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="37cc" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="if hh" style="box-sizing: inherit; font-weight: 700;">Linux</span><br style="box-sizing: inherit;" />For Linux Users, use the command below to install the k6.</p><pre class="jc jd je jf fs jn jo jp bn jq jr bi" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="js jt hg jo b be ju jv l jw jx" data-selectable-paragraph="" id="0494" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">--<span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">for</span> Debian/Ubuntu<br style="box-sizing: inherit;" />sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69<br style="box-sizing: inherit;" /><span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">echo</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main"</span> | sudo <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">tee</span> /etc/apt/sources.list.d/k6.list<br style="box-sizing: inherit;" />sudo apt-get update<br style="box-sizing: inherit;" />sudo apt-get install k6<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" />--<span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">for</span> Fedora/CentOS<br style="box-sizing: inherit;" />sudo dnf install https://dl.k6.io/rpm/repo.rpm<br style="box-sizing: inherit;" />sudo dnf install k6</span></pre><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="c427" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="if hh" style="box-sizing: inherit; font-weight: 700;">MacOS</span><br style="box-sizing: inherit;" />For MacOS users, install K6 using the Homebrew package installer.</p><pre class="jc jd je jf fs jn jo jp bn jq jr bi" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="js jt hg jo b be ju jv l jw jx" data-selectable-paragraph="" id="6a36" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">brew install k6</span></pre><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="c39f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">For Window users, After installing the k6 package open a command prompt and type k6. If you get below output then you are ready.</p><figure class="jc jd je jf fs jg fg fh paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="jh ji di jj bf jk" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 680px; z-index: auto;" tabindex="0"><div class="fg fh jz" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1345px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/max/640/1*rhyKbKcc0F_u3_4Cut7g2g.webp 640w, https://miro.medium.com/max/720/1*rhyKbKcc0F_u3_4Cut7g2g.webp 720w, https://miro.medium.com/max/750/1*rhyKbKcc0F_u3_4Cut7g2g.webp 750w, https://miro.medium.com/max/786/1*rhyKbKcc0F_u3_4Cut7g2g.webp 786w, https://miro.medium.com/max/828/1*rhyKbKcc0F_u3_4Cut7g2g.webp 828w, https://miro.medium.com/max/1100/1*rhyKbKcc0F_u3_4Cut7g2g.webp 1100w, https://miro.medium.com/max/1400/1*rhyKbKcc0F_u3_4Cut7g2g.webp 1400w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/max/640/1*rhyKbKcc0F_u3_4Cut7g2g.png 640w, https://miro.medium.com/max/720/1*rhyKbKcc0F_u3_4Cut7g2g.png 720w, https://miro.medium.com/max/750/1*rhyKbKcc0F_u3_4Cut7g2g.png 750w, https://miro.medium.com/max/786/1*rhyKbKcc0F_u3_4Cut7g2g.png 786w, https://miro.medium.com/max/828/1*rhyKbKcc0F_u3_4Cut7g2g.png 828w, https://miro.medium.com/max/1100/1*rhyKbKcc0F_u3_4Cut7g2g.png 1100w, https://miro.medium.com/max/1400/1*rhyKbKcc0F_u3_4Cut7g2g.png 1400w" style="box-sizing: inherit;"></source><img alt="" class="bf jl jm c" height="397" loading="lazy" role="presentation" src="https://miro.medium.com/max/700/1*rhyKbKcc0F_u3_4Cut7g2g.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 680px;" width="700" /></picture></div></div></figure><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="df2a" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="if hh" style="box-sizing: inherit; font-weight: 700;">Test Lifecycle<br style="box-sizing: inherit;" /></span>K6 test lifecycle has four stages and each stage runs in the same order.</p><ol style="background-color: white; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; list-style: none none; margin: 0px; padding: 0px;"><li class="ka kb hg if b ig ih ik il io kc is kd iw ke ja kf kg kh ki bi" data-selectable-paragraph="" id="0041" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 2.14em; padding-left: 0px;">init context: The init context runs once per VU and is generally used for tasks such as, loading local files, importing modules, declaring lifecycle functions etc. It is required.</li></ol><pre class="jc jd je jf fs jn jo jp bn jq jr bi" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="js jt hg jo b be ju jv l jw jx" data-selectable-paragraph="" id="6f60" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//1. init code</span></span></pre><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="a38b" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">2. setup function: setup function runs once in the entire lifecycle of the test and is generally used for data setups for tests. It is optional.</p><pre class="jc jd je jf fs jn jo jp bn jq jr bi" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="js jt hg jo b be ju jv l jw jx" data-selectable-paragraph="" id="b004" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">export</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">function</span> <span class="hljs-title.function" style="box-sizing: inherit;">setup</span>() {<br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">// 2. setup code</span><br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="ac75" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">3. default function: default function depicts the test scenario, in short this is your test method. It is required.</p><pre class="jc jd je jf fs jn jo jp bn jq jr bi" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="js jt hg jo b be ju jv l jw jx" data-selectable-paragraph="" id="4be5" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">export</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">default</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">function</span> (<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">data</span>) {<br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">// 3. VU code</span><br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="63aa" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">4. teardown function: Like setup, teardown function also runs once in the entire lifecycle and is generally used for cleanup or postprocessing data stuff. It is optional.</p><blockquote class="kj kk kl" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="id ie km if b ig ih ii ij ik il im in kn ip iq ir ko it iu iv kp ix iy iz ja gz bi" data-selectable-paragraph="" id="9ac5" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">If the Setup function ends abnormally (e.g throws an error), the teardown() function isn’t called. Consider adding logic to the setup() function to handle errors and ensure proper cleanup.</p></blockquote><pre class="jc jd je jf fs jn jo jp bn jq jr bi" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="js jt hg jo b be ju jv l jw jx" data-selectable-paragraph="" id="c3a2" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">export</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">function</span> <span class="hljs-title.function" style="box-sizing: inherit;">teardown</span>(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">data</span>) {<br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">// 4. teardown code</span><br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="1cad" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now let's write a test for REST API. For my tests here, I’m using Httpx library which is available here: <a class="ae jy" href="https://jslib.k6.io/httpx/0.0.1/index.js" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://jslib.k6.io/httpx/0.0.1/index.js</a></p><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="f20c" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="if hh" style="box-sizing: inherit; font-weight: 700;">HTTP Get Request<br style="box-sizing: inherit;" /></span>Create your first script to test a Get REST request. To do this create a js file, for example k6-testscripts.js</p><pre class="jc jd je jf fs jn jo jp bn jq jr bi" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="js jt hg jo b be ju jv l jw jx" data-selectable-paragraph="" id="ed23" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//import modules</span><br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">import</span> { <span class="hljs-title.class" style="box-sizing: inherit;">Httpx</span> } <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">from</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'https://jslib.k6.io/httpx/0.0.1/index.js'</span>;<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">import</span> { check } <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">from</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"k6"</span>;<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">import</span> { <span class="hljs-title.class" style="box-sizing: inherit;">Rate</span> } <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">from</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'k6/metrics'</span>;<br style="box-sizing: inherit;" /><span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//Error Rate is an object for representing a custom metric keeping track of </span><br style="box-sizing: inherit;" /><span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//the failures</span><br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">export</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> errorRate = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> <span class="hljs-title.class" style="box-sizing: inherit;">Rate</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'errors'</span>);<br style="box-sizing: inherit;" /><span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//create httpx session</span><br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">const</span> session = <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> <span class="hljs-title.class" style="box-sizing: inherit;">Httpx</span>({ <br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">baseURL</span>: {baseurl i.<span class="hljs-property" style="box-sizing: inherit;">e</span>. <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">http</span>:<span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//localhost:80/},</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">timeout</span>: <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">10000</span> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">// 10s timeout. </span><br style="box-sizing: inherit;" /> });<br style="box-sizing: inherit;" /><span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//set headers</span><br style="box-sizing: inherit;" />session.<span class="hljs-title.function" style="box-sizing: inherit;">addHeaders</span>(<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'Authorization'</span>: <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'Bearer {token}'</span>, <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//auth token</span><br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'User-Agent'</span>: <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'My k6 custom user agent'</span>, <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//user agent, any suitable name</span><br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'Content-Type'</span>: <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'application/json'</span>,<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />);<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//test method</span><br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">export</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">default</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">function</span> <span class="hljs-title.function" style="box-sizing: inherit;">getUserPermission</span>() {<br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//get request</span><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">let</span> res = session.<span class="hljs-title.function" style="box-sizing: inherit;">get</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"user/permission?userid=binod"</span>);<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//check response for 200 and response within 1000ms</span><br style="box-sizing: inherit;" /> <span class="hljs-title.function" style="box-sizing: inherit;">check</span>(res, {<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Is Status 200"</span>: <span class="hljs-function" style="box-sizing: inherit;">(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">r</span>) =></span> r.<span class="hljs-property" style="box-sizing: inherit;">status</span> === <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">200</span>,<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Getting User Permission response time"</span>: <span class="hljs-function" style="box-sizing: inherit;">(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">r</span>) =></span> r.<span class="hljs-property" style="box-sizing: inherit;">timings</span>.<span class="hljs-property" style="box-sizing: inherit;">duration</span> < <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">1000</span>,<br style="box-sizing: inherit;" /> }) || errorRate.<span class="hljs-title.function" style="box-sizing: inherit;">add</span>(<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">1</span>);<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span> (res.<span class="hljs-property" style="box-sizing: inherit;">status</span> === <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">200</span>) {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">let</span> resp = <span class="hljs-title.class" style="box-sizing: inherit;">JSON</span>.<span class="hljs-title.function" style="box-sizing: inherit;">parse</span>(res.<span class="hljs-property" style="box-sizing: inherit;">body</span>);<br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">console</span>.<span class="hljs-title.function" style="box-sizing: inherit;">log</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"response:"</span>, <span class="hljs-title.class" style="box-sizing: inherit;">JSON</span>.<span class="hljs-title.function" style="box-sizing: inherit;">stringify</span>(resp));<span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//prints the result, optional</span><br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">else</span><br style="box-sizing: inherit;" /> <span class="hljs-variable.language" style="box-sizing: inherit;">console</span>.<span class="hljs-title.function" style="box-sizing: inherit;">log</span>(res.<span class="hljs-property" style="box-sizing: inherit;">body</span>);<span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//this will help to know the error details on console. optional</span><br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="dc3f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now let’s run the below script in the command prompt to execute the script:</p><pre class="jc jd je jf fs jn jo jp bn jq jr bi" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="js jt hg jo b be ju jv l jw jx" data-selectable-paragraph="" id="f7f6" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">k6 run <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">C</span>:\<span class="hljs-title.class" style="box-sizing: inherit;">TestScripts</span>\k6-testscripts.<span class="hljs-property" style="box-sizing: inherit;">js</span></span></pre><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="b5cd" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">If all is well, the result of the above scripts would be as:</p><figure class="jc jd je jf fs jg fg fh paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="jh ji di jj bf jk" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 680px; z-index: auto;" tabindex="0"><div class="fg fh kq" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1462px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/max/640/1*9-O1zhbazMAfSzGj2TEA3g.webp 640w, https://miro.medium.com/max/720/1*9-O1zhbazMAfSzGj2TEA3g.webp 720w, https://miro.medium.com/max/750/1*9-O1zhbazMAfSzGj2TEA3g.webp 750w, https://miro.medium.com/max/786/1*9-O1zhbazMAfSzGj2TEA3g.webp 786w, https://miro.medium.com/max/828/1*9-O1zhbazMAfSzGj2TEA3g.webp 828w, https://miro.medium.com/max/1100/1*9-O1zhbazMAfSzGj2TEA3g.webp 1100w, https://miro.medium.com/max/1400/1*9-O1zhbazMAfSzGj2TEA3g.webp 1400w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/max/640/1*9-O1zhbazMAfSzGj2TEA3g.png 640w, https://miro.medium.com/max/720/1*9-O1zhbazMAfSzGj2TEA3g.png 720w, https://miro.medium.com/max/750/1*9-O1zhbazMAfSzGj2TEA3g.png 750w, https://miro.medium.com/max/786/1*9-O1zhbazMAfSzGj2TEA3g.png 786w, https://miro.medium.com/max/828/1*9-O1zhbazMAfSzGj2TEA3g.png 828w, https://miro.medium.com/max/1100/1*9-O1zhbazMAfSzGj2TEA3g.png 1100w, https://miro.medium.com/max/1400/1*9-O1zhbazMAfSzGj2TEA3g.png 1400w" style="box-sizing: inherit;"></source><img alt="" class="bf jl jm c" height="280" loading="lazy" role="presentation" src="https://miro.medium.com/max/700/1*9-O1zhbazMAfSzGj2TEA3g.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 680px;" width="700" /></picture></div></div></figure><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="bd3d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">The above result says, the Get request took 427.15ms (http_req_duration) to complete, and took 34.97ms to connect (http_req_connecting) for one HTTP request. (http_reqs).</p><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="0f52" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now the same Get request will continuously for 30 seconds and 30 VUs.</p><pre class="jc jd je jf fs jn jo jp bn jq jr bi" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="js jt hg jo b be ju jv l jw jx" data-selectable-paragraph="" id="7a5c" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">k6 run -d 30s -u <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">30</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">C</span>:\<span class="hljs-title.class" style="box-sizing: inherit;">TestScripts</span>\k6-testscripts.<span class="hljs-property" style="box-sizing: inherit;">js</span></span></pre><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="48ab" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In my case, the above command results:</p><figure class="jc jd je jf fs jg fg fh paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="jh ji di jj bf jk" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 680px; z-index: auto;" tabindex="0"><div class="fg fh kr" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1455px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/max/640/1*50tLgc2th7YwY3SxgJArWQ.webp 640w, https://miro.medium.com/max/720/1*50tLgc2th7YwY3SxgJArWQ.webp 720w, https://miro.medium.com/max/750/1*50tLgc2th7YwY3SxgJArWQ.webp 750w, https://miro.medium.com/max/786/1*50tLgc2th7YwY3SxgJArWQ.webp 786w, https://miro.medium.com/max/828/1*50tLgc2th7YwY3SxgJArWQ.webp 828w, https://miro.medium.com/max/1100/1*50tLgc2th7YwY3SxgJArWQ.webp 1100w, https://miro.medium.com/max/1400/1*50tLgc2th7YwY3SxgJArWQ.webp 1400w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/max/640/1*50tLgc2th7YwY3SxgJArWQ.png 640w, https://miro.medium.com/max/720/1*50tLgc2th7YwY3SxgJArWQ.png 720w, https://miro.medium.com/max/750/1*50tLgc2th7YwY3SxgJArWQ.png 750w, https://miro.medium.com/max/786/1*50tLgc2th7YwY3SxgJArWQ.png 786w, https://miro.medium.com/max/828/1*50tLgc2th7YwY3SxgJArWQ.png 828w, https://miro.medium.com/max/1100/1*50tLgc2th7YwY3SxgJArWQ.png 1100w, https://miro.medium.com/max/1400/1*50tLgc2th7YwY3SxgJArWQ.png 1400w" style="box-sizing: inherit;"></source><img alt="" class="bf jl jm c" height="306" loading="lazy" role="presentation" src="https://miro.medium.com/max/700/1*50tLgc2th7YwY3SxgJArWQ.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 680px;" width="700" /></picture></div></div></figure><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="165a" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Based on the above results, a total of 319 requests (http_reqs) have been made and out of 319 requests, response time checks failed for 30 requests as it took more than 1000ms but all succeeded successfully as far as success response concerns.</p><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="bede" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="if hh" style="box-sizing: inherit; font-weight: 700;">HTTP Post request</span><br style="box-sizing: inherit;" />For post request the test scripts would be as:</p><pre class="jc jd je jf fs jn jo jp bn jq jr bi" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="js jt hg jo b be ju jv l jw jx" data-selectable-paragraph="" id="2018" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">export</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">default</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">function</span> <span class="hljs-title.function" style="box-sizing: inherit;">registerUser</span>() {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">let</span> res = session.<span class="hljs-title.function" style="box-sizing: inherit;">post</span>(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">`/user/register/`</span>, {<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">first_name</span>: <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'Binod'</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">last_name</span>: <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'Mahto'</span>,<br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">username</span>: <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'binod'</span>,<br style="box-sizing: inherit;" /> });<br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">//check response for 201 and response within 1000ms</span><br style="box-sizing: inherit;" /> <span class="hljs-title.function" style="box-sizing: inherit;">check</span>(res, {<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Is Status 201"</span>: <span class="hljs-function" style="box-sizing: inherit;">(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">r</span>) =></span> r.<span class="hljs-property" style="box-sizing: inherit;">status</span> === <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">201</span>,<br style="box-sizing: inherit;" /> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Registering User response time"</span>: <span class="hljs-function" style="box-sizing: inherit;">(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">r</span>) =></span> r.<span class="hljs-property" style="box-sizing: inherit;">timings</span>.<span class="hljs-property" style="box-sizing: inherit;">duration</span> < <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">1000</span>,<br style="box-sizing: inherit;" /> })<br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="7a60" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><b>Complete Result output summary</b><br style="box-sizing: inherit;" />Here are the complete lists of summaries generated from your request execution.</p><ol style="background-color: white; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; list-style: none none; margin: 0px; padding: 0px;"><li class="ka kb hg if b ig ih ik il io kc is kd iw ke ja kf kg kh ki bi" data-selectable-paragraph="" id="65d1" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 2.14em; padding-left: 0px;">checks: rate of successful checks percentage from total no. of checks, it also includes the no. of checks passed and failed.</li><li class="ka kb hg if b ig ks ik kt io ku is kv iw kw ja kf kg kh ki bi" data-selectable-paragraph="" id="ef7d" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">data_received: the amount of data received.</li><li class="ka kb hg if b ig ks ik kt io ku is kv iw kw ja kf kg kh ki bi" data-selectable-paragraph="" id="0abc" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">data_sent: the amount of data sent.</li><li class="ka kb hg if b ig ks ik kt io ku is kv iw kw ja kf kg kh ki bi" data-selectable-paragraph="" id="f8cf" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">errors: rate of error percentage for failure checks.</li><li class="ka kb hg if b ig ks ik kt io ku is kv iw kw ja kf kg kh ki bi" data-selectable-paragraph="" id="4def" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">http_req_blocked : average time spent waiting for TCP connection</li><li class="ka kb hg if b ig ks ik kt io ku is kv iw kw ja kf kg kh ki bi" data-selectable-paragraph="" id="5da1" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">http_req_connecting : average time spent establishing a TCP connection</li><li class="ka kb hg if b ig ks ik kt io ku is kv iw kw ja kf kg kh ki bi" data-selectable-paragraph="" id="04e7" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">http_req_duration: average total time for the request. It’s calculated based on http_req_sending + http_req_waiting + http_req_receiving.</li><li class="ka kb hg if b ig ks ik kt io ku is kv iw kw ja kf kg kh ki bi" data-selectable-paragraph="" id="0f7d" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">http_req_failed: percentage of failed requests. in our case 0 (0.00%) failed out of 319 requests.</li><li class="ka kb hg if b ig ks ik kt io ku is kv iw kw ja kf kg kh ki bi" data-selectable-paragraph="" id="7bbe" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">http_req_receiving : average time spent on data receiving</li><li class="ka kb hg if b ig ks ik kt io ku is kv iw kw ja kf kg kh ki bi" data-selectable-paragraph="" id="205a" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">http_req_sending: average time spent on data sending</li><li class="ka kb hg if b ig ks ik kt io ku is kv iw kw ja kf kg kh ki bi" data-selectable-paragraph="" id="2ecc" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">http_req_tls_handshaking : average time spent on TLS handshaking</li><li class="ka kb hg if b ig ks ik kt io ku is kv iw kw ja kf kg kh ki bi" data-selectable-paragraph="" id="28ff" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">http_req_waiting: average time spent on waiting for a response from the remote host</li><li class="ka kb hg if b ig ks ik kt io ku is kv iw kw ja kf kg kh ki bi" data-selectable-paragraph="" id="0abb" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">http_reqs : total number of requests</li><li class="ka kb hg if b ig ks ik kt io ku is kv iw kw ja kf kg kh ki bi" data-selectable-paragraph="" id="8b7f" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">iteration_duration: average time it took to execute the default function for each iteration.</li><li class="ka kb hg if b ig ks ik kt io ku is kv iw kw ja kf kg kh ki bi" data-selectable-paragraph="" id="5d9b" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">iterations: total no. of iterations to execute default function (test method)</li><li class="ka kb hg if b ig ks ik kt io ku is kv iw kw ja kf kg kh ki bi" data-selectable-paragraph="" id="4825" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">vus: number of virtual users. It is also represented as VU.</li><li class="ka kb hg if b ig ks ik kt io ku is kv iw kw ja kf kg kh ki bi" data-selectable-paragraph="" id="ada8" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">vus_max: maximum no. of virtual users allocated for the test execution.</li></ol><p class="pw-post-body-paragraph id ie hg if b ig ih ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja gz bi" data-selectable-paragraph="" id="8b2c" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="if hh" style="box-sizing: inherit; font-weight: 700;">httpx library</span><br style="box-sizing: inherit;" />To know more about the httpx library to for other HTTP request as Put, Patch, Delete etc, please refer the doc here: <a class="ae jy" href="https://k6.io/docs/javascript-api/jslib/httpx/post/" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://k6.io/docs/javascript-api/jslib/httpx/post/</a><br /><br /><span style="font-weight: 700; letter-spacing: -0.06px;">Hope you enjoyed the content, follow me for more like this, and please don’t forget to LIKE it. Happy programming.</span></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-49036463655801507562022-12-11T20:08:00.003+05:302023-04-26T16:30:48.123+05:30Generic Attributes in C#11<p> <img alt="" class="bg id ie c" height="395" loading="eager" role="presentation" src="https://miro.medium.com/max/700/0*9ZwiCw6enB4vSG1z.png" style="background-color: white; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; height: auto; max-width: 100%; vertical-align: middle; width: 680px;" width="700" /></p><p class="pw-post-body-paragraph if ig gx ih b ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc gq bj" data-selectable-paragraph="" id="b06b" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In C# 11 comes with .Net 7, Attribute is enhanced to use with generic type. This feature provides a convenient way for attributes to avoid System.Type constructor parameter (the old way).</p><blockquote class="jd je jf" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="if ig jg ih b ii ij ik il im in io ip jh ir is it ji iv iw ix jj iz ja jb jc gq bj" data-selectable-paragraph="" id="00d9" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Attributes are metadata extensions that give additional information to the compiler about the elements in the program code at runtime. Attributes are used to impose conditions or to increase the efficiency of a piece of code.</p></blockquote><p class="pw-post-body-paragraph if ig gx ih b ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc gq bj" data-selectable-paragraph="" id="b51d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Being a programmer I love this. Here I will try to explain to you how to define Attributes with generic types. To understand the enhancement, let's see how we used to do the Attributes with type in C# 10 or before.</p><p class="pw-post-body-paragraph if ig gx ih b ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc gq bj" data-selectable-paragraph="" id="3f2d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">For example, we will create an Asp.Net core web API project template with the target framework net7.0 so the same project will be using the demonstration of old and new syntax.</p><p class="pw-post-body-paragraph if ig gx ih b ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc gq bj" data-selectable-paragraph="" id="e676" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Here I will be creating an Action Filter called LoggingFilter and will be logging some info before and after the execution of an action.</p><pre class="jk jl jm jn el jo jp jq bo jr js bj" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="jt ju gx jp b bf jv jw l jx jy" data-selectable-paragraph="" id="8055" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">using</span> Microsoft.AspNetCore.Mvc.Filters;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">namespace</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">CSharp11WebAPIDemo.Infrastructure</span><br style="box-sizing: inherit;" />{<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">LoggingFilter</span> : <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">IAsyncActionFilter</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> ILogger<LoggingFilter> _logger;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">LoggingFilter</span>(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">ILogger<LoggingFilter> logger</span>)</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> _logger = logger;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">async</span> Task <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">OnActionExecutionAsync</span>(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">ActionExecutingContext context, ActionExecutionDelegate next</span>)</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> _logger.LogInformation(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Action starts"</span>);<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">await</span> next();<br style="box-sizing: inherit;" /> _logger.LogInformation(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"Action ends"</span>);<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph if ig gx ih b ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc gq bj" data-selectable-paragraph="" id="2345" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">The above code is straightforward. So now we add this to the service collection.</p><pre class="jk jl jm jn el jo jp jq bo jr js bj" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="jt ju gx jp b bf jv jw l jx jy" data-selectable-paragraph="" id="2885" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">builder.Services.AddSingleton<LoggingFilter>();</span></pre><p class="pw-post-body-paragraph if ig gx ih b ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc gq bj" data-selectable-paragraph="" id="a471" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">To use this action filter with an Action method we will use Microsoft.AspNetCore.Mvc.ServiceFilter attribute which is using the old syntax which takes System.Type as a parameter for the constructor and the definition of ServiceFilterAttribute.</p><p class="pw-post-body-paragraph if ig gx ih b ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc gq bj" data-selectable-paragraph="" id="056f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Next, we will use the action filter with the Get action method of the WeatherForecastController generated from the template.</p><pre class="jk jl jm jn el jo jp jq bo jr js bj" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="jt ju gx jp b bf jv jw l jx jy" data-selectable-paragraph="" id="1bae" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">[<span class="hljs-meta" style="box-sizing: inherit; color: #643820;">HttpGet(Name = <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"GetWeatherForecast"</span>)</span>]<br style="box-sizing: inherit;" />[<span class="hljs-meta" style="box-sizing: inherit; color: #643820;">ServiceFilter(typeof(LoggingFilter))</span>]<br style="box-sizing: inherit;" /><span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> IEnumerable<WeatherForecast> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">Get</span>()</span><br style="box-sizing: inherit;" />{<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">return</span> Enumerable.Range(<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">1</span>, <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">5</span>).Select(index => <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> WeatherForecast<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),<br style="box-sizing: inherit;" /> TemperatureC = Random.Shared.Next(<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">-20</span>, <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">55</span>),<br style="box-sizing: inherit;" /> Summary = Summaries[Random.Shared.Next(Summaries.Length)]<br style="box-sizing: inherit;" /> })<br style="box-sizing: inherit;" /> .ToArray();<br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph if ig gx ih b ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc gq bj" data-selectable-paragraph="" id="221b" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now you run the application and execute the GetWeatherForecast endpoint from the swagger app, you will see the information log in the output window as</p><pre class="jk jl jm jn el jo jp jq bo jr js bj" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="jt ju gx jp b bf jv jw l jx jy" data-selectable-paragraph="" id="ca62" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-section" style="box-sizing: inherit; color: #643820;">CSharp11WebAPIDemo.Infrastructure.LoggingFilter: Information: Action starts</span><br style="box-sizing: inherit;" /><span class="hljs-section" style="box-sizing: inherit; color: #643820;">CSharp11WebAPIDemo.Infrastructure.LoggingFilter: Information: Action ends</span></span></pre><p class="pw-post-body-paragraph if ig gx ih b ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc gq bj" data-selectable-paragraph="" id="6018" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Cool, Everything works great but How about Microsoft would have made the ServiceFilterAttribute generic and avoid the type parameter in the constructor? Well, we will do it and will write better code than Microsoft. :) <span class="ih gy" style="box-sizing: inherit; font-weight: 700;"><em class="jg" style="box-sizing: inherit;">Just kidding</em></span>. Actually, this is the enhancement done in C#11, <span class="ih gy" style="box-sizing: inherit; font-weight: 700;"><em class="jg" style="box-sizing: inherit;">thanks to Microsoft for that.</em></span></p><p class="pw-post-body-paragraph if ig gx ih b ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc gq bj" data-selectable-paragraph="" id="bc67" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">To redefine the ServiceFilterAttribute using the Generic Attribute feature, let’s see the ServiceFilterAttribute code which is available under <span class="ih gy" style="box-sizing: inherit; font-weight: 700;">Microsoft.AspNetCore.Mvc</span> namespace:</p><pre class="jk jl jm jn el jo jp jq bo jr js bj" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="jt ju gx jp b bf jv jw l jx jy" data-selectable-paragraph="" id="dfb0" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">[<span class="hljs-meta" style="box-sizing: inherit; color: #643820;">AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)</span>]<br style="box-sizing: inherit;" />[<span class="hljs-meta" style="box-sizing: inherit; color: #643820;">DebuggerDisplay(<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"ServiceFilter: Type={ServiceType} Order={Order}"</span>)</span>]<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">ServiceFilterAttribute</span> : <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">Attribute</span>, <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">IFilterFactory</span>, <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">IOrderedFilter</span><br style="box-sizing: inherit;" />{<br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;"><span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;">///</span> <span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;"><summary></span></span><br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;"><span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;">///</span> Instantiates a new <span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;"><see cref="ServiceFilterAttribute"/></span> instance.</span><br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;"><span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;">///</span> <span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;"></summary></span></span><br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;"><span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;">///</span> <span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;"><param name="type"></span>The <span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;"><see cref="Type"/></span> of filter to find.<span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;"></param></span></span><br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">ServiceFilterAttribute</span>(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">Type type</span>)</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> ServiceType = type ?? <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">throw</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> ArgumentNullException(<span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">nameof</span>(type));<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;"><span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;">///</span> <span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;"><inheritdoc /></span></span><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">int</span> Order { <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">get</span>; <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">set</span>; }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;"><span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;">///</span> <span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;"><summary></span></span><br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;"><span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;">///</span> Gets the <span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;"><see cref="Type"/></span> of filter to find.</span><br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;"><span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;">///</span> <span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;"></summary></span></span><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> Type ServiceType { <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">get</span>; }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;"><span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;">///</span> <span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;"><inheritdoc /></span></span><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">bool</span> IsReusable { <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">get</span>; <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">set</span>; }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;"><span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;">///</span> <span class="hljs-doctag" style="box-sizing: inherit; font-weight: bold;"><inheritdoc /></span></span><br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> IFilterMetadata <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">CreateInstance</span>(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">IServiceProvider serviceProvider</span>)</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span> (serviceProvider == <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">null</span>)<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">throw</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> ArgumentNullException(<span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">nameof</span>(serviceProvider));<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">var</span> filter = (IFilterMetadata)serviceProvider.GetRequiredService(ServiceType);<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span> (filter <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">is</span> IFilterFactory filterFactory)<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">// Unwrap filter factories</span><br style="box-sizing: inherit;" /> filter = filterFactory.CreateInstance(serviceProvider);<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">return</span> filter;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph if ig gx ih b ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc gq bj" data-selectable-paragraph="" id="45eb" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">As per the above Microsoft code here, ServiceFilter takes Type as a parameter in the constructor which we pass as <span class="ih gy" style="box-sizing: inherit; font-weight: 700;">typeof(LoggingFilter)</span> in the action method. So now we will recreate the ServiceFilterAttribute by defining a generic attribute and the syntax would be as:</p><p class="pw-post-body-paragraph if ig gx ih b ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc gq bj" data-selectable-paragraph="" id="059a" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ih gy" style="box-sizing: inherit; font-weight: 700;">public class MyServiceFilterAttribute<T> : Attribute</span></p><p class="pw-post-body-paragraph if ig gx ih b ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc gq bj" data-selectable-paragraph="" id="4bdd" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">and the code as:</p><pre class="jk jl jm jn el jo jp jq bo jr js bj" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="jt ju gx jp b bf jv jw l jx jy" data-selectable-paragraph="" id="3ae6" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">using</span> Microsoft.AspNetCore.Mvc.Filters;<br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">using</span> System.Diagnostics;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">namespace</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">CSharp11WebAPIDemo.Infrastructure</span><br style="box-sizing: inherit;" />{<br style="box-sizing: inherit;" /> [<span class="hljs-meta" style="box-sizing: inherit; color: #643820;">AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)</span>]<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">class</span> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">MyServiceFilterAttribute</span><<span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">T</span>> : <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">Attribute</span>, <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">IFilterFactory</span>, <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">IOrderedFilter</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">int</span> Order { <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">get</span>; <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">set</span>; }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> <span class="hljs-built_in" style="box-sizing: inherit; color: #5c2699;">bool</span> IsReusable { <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">get</span>; <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">set</span>; }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> IFilterMetadata <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">CreateInstance</span>(<span class="hljs-params" style="box-sizing: inherit; color: #5c2699;">IServiceProvider serviceProvider</span>)</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span> (serviceProvider == <span class="hljs-literal" style="box-sizing: inherit; color: #aa0d91;">null</span>)<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">throw</span> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> ArgumentNullException(<span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">nameof</span>(serviceProvider));<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">var</span> filter = (IFilterMetadata)serviceProvider.GetRequiredService(<span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">typeof</span>(T));<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">if</span> (filter <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">is</span> IFilterFactory filterFactory)<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> filter = filterFactory.CreateInstance(serviceProvider);<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">return</span> filter;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph if ig gx ih b ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc gq bj" data-selectable-paragraph="" id="9e46" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Wow, no more type parameters and a very convenient way of making the attribute class generic.</p><pre class="jk jl jm jn el jo jp jq bo jr js bj" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="jt ju gx jp b bf jv jw l jx jy" data-selectable-paragraph="" id="11dc" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;">[<span class="hljs-meta" style="box-sizing: inherit; color: #643820;">HttpGet(Name = <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"GetWeatherForecast"</span>)</span>]<br style="box-sizing: inherit;" />[<span class="hljs-meta" style="box-sizing: inherit; color: #643820;">MyServiceFilter<LoggingFilter></span>]<br style="box-sizing: inherit;" /><span class="hljs-function" style="box-sizing: inherit;"><span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">public</span> IEnumerable<WeatherForecast> <span class="hljs-title" style="box-sizing: inherit; color: #1c00cf;">Get</span>()</span><br style="box-sizing: inherit;" />{<br style="box-sizing: inherit;" /> <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">return</span> Enumerable.Range(<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">1</span>, <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">5</span>).Select(index => <span class="hljs-keyword" style="box-sizing: inherit; color: #aa0d91;">new</span> WeatherForecast<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),<br style="box-sizing: inherit;" /> TemperatureC = Random.Shared.Next(<span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">-20</span>, <span class="hljs-number" style="box-sizing: inherit; color: #1c00cf;">55</span>),<br style="box-sizing: inherit;" /> Summary = Summaries[Random.Shared.Next(Summaries.Length)]<br style="box-sizing: inherit;" /> })<br style="box-sizing: inherit;" /> .ToArray();<br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph if ig gx ih b ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc gq bj" data-selectable-paragraph="" id="524d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Again if you run the application, the logs will be displayed in the output window as with the earlier code.</p><pre class="jk jl jm jn el jo jp jq bo jr js bj" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="jt ju gx jp b bf jv jw l jx jy" data-selectable-paragraph="" id="2ffe" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-section" style="box-sizing: inherit; color: #643820;">CSharp11WebAPIDemo.Infrastructure.LoggingFilter: Information: Action starts</span><br style="box-sizing: inherit;" /><span class="hljs-section" style="box-sizing: inherit; color: #643820;">CSharp11WebAPIDemo.Infrastructure.LoggingFilter: Information: Action ends</span></span></pre><p class="pw-post-body-paragraph if ig gx ih b ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc gq bj" data-selectable-paragraph="" id="3c10" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">No difference in functionality but a huge difference in terms of better code.</p><p class="pw-post-body-paragraph if ig gx ih b ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc gq bj" data-selectable-paragraph="" id="4183" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Here is the full code used for this example:<br style="box-sizing: inherit;" /><a class="af jz" href="https://github.com/binodmahto/FunProjects/tree/main/CSharp11WebAPIDemo" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://github.com/binodmahto/FunProjects/tree/main/CSharp11WebAPIDemo</a></p><p class="pw-post-body-paragraph if ig gx ih b ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc gq bj" data-selectable-paragraph="" id="00fb" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">To know more about C#11 new features please read through:<br style="box-sizing: inherit;" /><a class="af jz" href="https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-11" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-11</a></p><p class="pw-post-body-paragraph if ig gx ih b ii ij ik il im in io ip iq ir is it iu iv iw ix iy iz ja jb jc gq bj" data-selectable-paragraph="" id="fe28" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ih gy" style="box-sizing: inherit; font-weight: 700;">Hope you enjoyed the content, follow me for more like this, and please don’t forget to LIKE it. Happy programming.</span></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-46755169713291836922022-12-05T11:30:00.002+05:302022-12-05T11:33:55.479+05:30CICD best practices<p> <span face="source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif" style="background-color: white; color: #292929; font-size: 20px; letter-spacing: -0.003em;">CICD is the process of automating the building, testing & deploying of your application.</span></p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="43cb" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">CICD is no more a novelty instead it’s a need for every development team. Over the past few weeks, I got a chance to spend huge time implementing CICD from scratch, and based on my experience I suggest six best practices required for any DevOps team, and these are:</p><ol style="background-color: white; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; list-style: none none; margin: 0px; padding: 0px;"><li class="kb kc ig jf b jg jh jk jl jo kd js ke jw kf ka kg kh ki kj gh" data-selectable-paragraph="" id="2168" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 2.14em; padding-left: 0px;"><em class="kk" style="box-sizing: inherit;">Plan your repo</em></li><li class="kb kc ig jf b jg kl jk km jo kn js ko jw kp ka kg kh ki kj gh" data-selectable-paragraph="" id="ea7f" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;"><em class="kk" style="box-sizing: inherit;">Choose your tools</em></li><li class="kb kc ig jf b jg kl jk km jo kn js ko jw kp ka kg kh ki kj gh" data-selectable-paragraph="" id="fc86" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;"><em class="kk" style="box-sizing: inherit;">Plan your Tests automation</em></li><li class="kb kc ig jf b jg kl jk km jo kn js ko jw kp ka kg kh ki kj gh" data-selectable-paragraph="" id="f050" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;"><em class="kk" style="box-sizing: inherit;">Secure your pipelines and secrets</em></li><li class="kb kc ig jf b jg kl jk km jo kn js ko jw kp ka kg kh ki kj gh" data-selectable-paragraph="" id="67ad" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;"><em class="kk" style="box-sizing: inherit;">Pipelines for early-stage verification and deployment</em></li><li class="kb kc ig jf b jg kl jk km jo kn js ko jw kp ka kg kh ki kj gh" data-selectable-paragraph="" id="a67b" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;"><em class="kk" style="box-sizing: inherit;">Involve the Team.</em></li></ol><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="f4d4" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jf ih" style="box-sizing: inherit; font-weight: 700;">Plan your repo</span><br style="box-sizing: inherit;" />Your code repository is extremely important to avoid mess working with small/big teams. A wise decision is always to avoid direct push to the main branch or a release branch, hence the recommendation would be to have branches like this:</p><figure class="kr ks kt ku fy kv fm fn paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="fm fn kq" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 625px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 625px" srcset="https://miro.medium.com/max/640/1*JsqlXHFsNlo35Oo2fq-fvA.webp 640w, https://miro.medium.com/max/720/1*JsqlXHFsNlo35Oo2fq-fvA.webp 720w, https://miro.medium.com/max/750/1*JsqlXHFsNlo35Oo2fq-fvA.webp 750w, https://miro.medium.com/max/786/1*JsqlXHFsNlo35Oo2fq-fvA.webp 786w, https://miro.medium.com/max/828/1*JsqlXHFsNlo35Oo2fq-fvA.webp 828w, https://miro.medium.com/max/1100/1*JsqlXHFsNlo35Oo2fq-fvA.webp 1100w, https://miro.medium.com/max/1250/1*JsqlXHFsNlo35Oo2fq-fvA.webp 1250w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 625px" srcset="https://miro.medium.com/max/640/1*JsqlXHFsNlo35Oo2fq-fvA.png 640w, https://miro.medium.com/max/720/1*JsqlXHFsNlo35Oo2fq-fvA.png 720w, https://miro.medium.com/max/750/1*JsqlXHFsNlo35Oo2fq-fvA.png 750w, https://miro.medium.com/max/786/1*JsqlXHFsNlo35Oo2fq-fvA.png 786w, https://miro.medium.com/max/828/1*JsqlXHFsNlo35Oo2fq-fvA.png 828w, https://miro.medium.com/max/1100/1*JsqlXHFsNlo35Oo2fq-fvA.png 1100w, https://miro.medium.com/max/1250/1*JsqlXHFsNlo35Oo2fq-fvA.png 1250w" style="box-sizing: inherit;"></source><img alt="" class="ce kw kx c" height="370" loading="lazy" role="presentation" src="https://miro.medium.com/max/625/1*JsqlXHFsNlo35Oo2fq-fvA.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 625px;" width="625" /></picture></div></figure><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="3166" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In this case, the Feature branch will be the branch that will be synced to the Main for any changes and all developers should be worked with Feature Branch to avoid any accidental/unwanted changes to the Main.</p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="826c" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Also, the most important task here is to restrict access to the Main & Release branch for direct push, Pull Request approval, etc.</p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="43cd" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jf ih" style="box-sizing: inherit; font-weight: 700;">Choose your tools</span><br style="box-sizing: inherit;" />It is always important to scan the code being pushed to the branches in terms of security & vulnerabilities. To do this there are plenty of tools available like SonarQube, Blackduck, etc.</p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="28e4" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">These scanning tools help you to make sure your code going safely on in the internet ocean.</p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="5bf3" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jf ih" style="box-sizing: inherit; font-weight: 700;">Plan your Tests automation<br style="box-sizing: inherit;" /></span>Unit Tests or Integration Tests are important to make sure no breaking changes are being pushed and your application is healthy but can be relied on running the tests on local/dev machines only, Oh No, that would be a big mistake.</p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="894d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">So make sure you have a pipeline to trigger with every pull request to your concern branch which builds the project and runs the tests and PR should be accepted only with the successful execution of these pipelines.</p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="5cfb" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">i.e. check this out:<br style="box-sizing: inherit;" /><a class="au ky" href="https://binodmahto.blogspot.com/2022/12/cicd-with-github-actions-pipeline-to.html" rel="noopener" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;">CI/CD with GitHub Actions pipeline to run the .Net unit test and publish results</a></p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="20d9" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jf ih" style="box-sizing: inherit; font-weight: 700;">Secure your pipelines and secrets</span><br style="box-sizing: inherit;" />Make sure your pipeline is secured. If you are on GitHub please go through this link:<br style="box-sizing: inherit;" /><a class="au ky" href="https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions</a></p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="983b" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">For securing your application secrets, you can use cloud Key Vault services with restricted access i.e. Azure Key Vault</p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="d849" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jf ih" style="box-sizing: inherit; font-weight: 700;">Pipelines for early-stage verification and deployment<br style="box-sizing: inherit;" /></span>Issues in application code are like diseases in your body so as early it is caught, it can be treated well.</p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="6c44" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">So plan your pipeline like Code scanning (SonarQube, Blackduck, etc), Test execution, dev/test deployment, etc in the early stages like with each PR of the feature branch and main branch.</p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="a021" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jf ih" style="box-sizing: inherit; font-weight: 700;">Involve the Team<br style="box-sizing: inherit;" /></span>Last but not the least, Team involvement is very much required as DevOps activity is not one person's responsibility. Whether it is writing tests or observing the pipeline's progress/failure, everyone’s responsibility is equal to making sure the pipeline goes end-to-end green.</p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="ec44" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jf ih" style="box-sizing: inherit; font-weight: 700;">Hope you enjoyed the content, follow me for more like this, and please don’t forget to LIKE it. Happy programming.</span></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-18307692916083569432022-12-05T11:28:00.003+05:302022-12-05T11:33:16.617+05:30CI/CD with GitHub Actions pipeline to run the .Net unit test and publish results<p> <span face="source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif" style="background-color: white; color: #292929; font-size: 20px; letter-spacing: -0.003em;">Writing Tests (Unit Tests, Integration Tests) is not only the best practice but also essential to ensure quality code.</span></p><article style="background-color: white; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;"><div class="y" style="box-sizing: inherit;"><div class="y" style="box-sizing: inherit;"><section style="box-sizing: inherit;"><div style="box-sizing: inherit;"><div class="pj vn xq xr xs" style="box-sizing: inherit; overflow-wrap: break-word; word-break: break-word;"><p class="pw-post-body-paragraph yq yr xu so b ys yt ut yu yv yw uw yx yy yz za zb zc zd ze zf zg zh zi zj zk pj by" data-selectable-paragraph="" id="bcb5" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">From the DevOps side, it is essential to put a gate to check for successful unit test execution with each pull request or push. So in this article, we will see how to implement a pipeline to run the unit tests and publish the results.</p><p class="pw-post-body-paragraph yq yr xu so b ys yt ut yu yv yw uw yx yy yz za zb zc zd ze zf zg zh zi zj zk pj by" data-selectable-paragraph="" id="d0ce" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">What do we need?</p><ol style="box-sizing: inherit; list-style: none none; margin: 0px; padding: 0px;"><li class="zl zm xu so b ys yt yv yw yy zn zc zo zg zp zk zq zr zs ea by" data-selectable-paragraph="" id="2048" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 2.14em; padding-left: 0px;">We need a pipeline to be triggered with every pull request for your code repo.</li><li class="zl zm xu so b ys zt yv zu yy zv zc zw zg zx zk zq zr zs ea by" data-selectable-paragraph="" id="c649" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">Jobs to run the unit tests and publish the results.</li></ol><p class="pw-post-body-paragraph yq yr xu so b ys yt ut yu yv yw uw yx yy yz za zb zc zd ze zf zg zh zi zj zk pj by" data-selectable-paragraph="" id="3b43" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Please follow my other articles to learn more about GitHub Actions: <a class="ay zy" href="https://binodmahto.blogspot.com/2022/08/cicd-with-github-actions.html" rel="noopener" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;">CI/CD with GitHub Actions</a>, <a class="ay zy" href="https://binodmahto.blogspot.com/2022/08/cicd-with-github-actions-to-deploy.html" rel="noopener" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;">CI/CD with GitHub Actions to deploy Applications to Azure App Service</a>, <a class="ay zy" href="https://binodmahto.blogspot.com/2022/10/cicd-with-github-actions-to-deploy.html" rel="noopener" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;">CI/CD with GitHub Actions to deploy Application to Azure Kubernetes Cluster</a></p><p class="pw-post-body-paragraph yq yr xu so b ys yt ut yu yv yw uw yx yy yz za zb zc zd ze zf zg zh zi zj zk pj by" data-selectable-paragraph="" id="7231" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Let’s create our pipeline for unit test execution. To do this add a yaml/yml file as .github/workflows/buildAndRunTest.yml in the root project folder and then starts with defining the name & triggering action.</p><pre class="zz aba abb abc wv abd abe eh gm abf abg by" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="abh abi xu abe b bw abj abk y abl abm" data-selectable-paragraph="" id="7646" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">name:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Build</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">and</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">run</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">tests</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">env:</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">DOTNET_VERSION:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'6.0'</span> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;"># set this to the .NET Core version to use</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">WORKING_DIRECTORY:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">'./src'</span> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">#define the root folder path</span><br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /><span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">on:</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">workflow_dispatch:</span> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">#for manual trigger</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">pull_request:</span> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">#trigger action with pull request</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">branches:</span><br style="box-sizing: inherit;" /> <span class="hljs-bullet" style="box-sizing: inherit; color: #1c00cf;">-</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">main</span> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">#your branch name</span></span></pre><p class="pw-post-body-paragraph yq yr xu so b ys yt ut yu yv yw uw yx yy yz za zb zc zd ze zf zg zh zi zj zk pj by" data-selectable-paragraph="" id="a009" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Next step, we will define the job and mention the target machine (Linux/windows) then perform the necessary steps for code checkout and setting .net core</p><pre class="zz aba abb abc wv abd abe eh gm abf abg by" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="abh abi xu abe b bw abj abk y abl abm" data-selectable-paragraph="" id="095d" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">jobs:</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">build:</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">runs-on:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">ubuntu-latest</span> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">#target machine is ubuntu</span><br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">steps:</span><br style="box-sizing: inherit;" /> <span class="hljs-bullet" style="box-sizing: inherit; color: #1c00cf;">-</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">uses:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">actions/checkout@v2</span><br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> <span class="hljs-bullet" style="box-sizing: inherit; color: #1c00cf;">-</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">name:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Setup</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">.NET</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Core</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">uses:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">actions/setup-dotnet@v1</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">with:</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">dotnet-version:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">${{</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">env.DOTNET_VERSION</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">}}</span> <span class="hljs-comment" style="box-sizing: inherit; color: #007400;">#reading it from env variable defined above</span></span></pre><p class="pw-post-body-paragraph yq yr xu so b ys yt ut yu yv yw uw yx yy yz za zb zc zd ze zf zg zh zi zj zk pj by" data-selectable-paragraph="" id="3f5b" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">I’m using “EnricoMi/publish-unit-test-result-action” action from the marketplace with JUnit logger hence we need to install the related package for each test project as the next step.</p><blockquote class="abn abo abp" style="box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="yq yr abq so b ys yt ut yu yv yw uw yx abr yz za zb abs zd ze zf abt zh zi zj zk pj by" data-selectable-paragraph="" id="64f3" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Xml logger for JUnit v5 compliant xml report when test is running with “dotnet test” or “dotnet vstest”.</p></blockquote><pre class="zz aba abb abc wv abd abe eh gm abf abg by" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="abh abi xu abe b bw abj abk y abl abm" data-selectable-paragraph="" id="4446" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-bullet" style="box-sizing: inherit; color: #1c00cf;">-</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">name:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Setup</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">test</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">loggers</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">shell:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">pwsh</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">run:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">|<br style="box-sizing: inherit;" /> foreach ($file in Get-ChildItem -Path .src/tests/*Tests.csproj -Recurse)<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> dotnet add $file package JunitXml.TestLogger --source 'https://api.nuget.org/v3/index.json'<br style="box-sizing: inherit;" /> }</span></span></pre><p class="pw-post-body-paragraph yq yr xu so b ys yt ut yu yv yw uw yx yy yz za zb zc zd ze zf zg zh zi zj zk pj by" data-selectable-paragraph="" id="6525" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">From the above code, looping through all test projects inside the src/tests folder.</p><p class="pw-post-body-paragraph yq yr xu so b ys yt ut yu yv yw uw yx yy yz za zb zc zd ze zf zg zh zi zj zk pj by" data-selectable-paragraph="" id="25fb" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Next step we will execute the tests with dotnet command.</p><pre class="zz aba abb abc wv abd abe eh gm abf abg by" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="abh abi xu abe b bw abj abk y abl abm" data-selectable-paragraph="" id="3950" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-bullet" style="box-sizing: inherit; color: #1c00cf;">-</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">name:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Run</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">unit</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">tests</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">shell:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">bash</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">working-directory:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">./src</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">run:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">|<br style="box-sizing: inherit;" /> dotnet test myDemoApp.sln --logger 'junit;LogFileName=TestResults.xml' \<br style="box-sizing: inherit;" /> --verbosity normal --results-directory ./_test-results</span></span></pre><p class="pw-post-body-paragraph yq yr xu so b ys yt ut yu yv yw uw yx yy yz za zb zc zd ze zf zg zh zi zj zk pj by" data-selectable-paragraph="" id="7df5" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">The above code will run all the unit tests in the project and save the result inside the src/_test-results/TestResults.xml file.</p><blockquote class="abn abo abp" style="box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="yq yr abq so b ys yt ut yu yv yw uw yx abr yz za zb abs zd ze zf abt zh zi zj zk pj by" data-selectable-paragraph="" id="2d3c" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">If you have categorized tests then you can use the filter option with dotnet test as:<br style="box-sizing: inherit;" /><span class="so pf" style="box-sizing: inherit; font-weight: 700;">dotnet test — filter “TestCategory=CategoryA”</span></p></blockquote><p class="pw-post-body-paragraph yq yr xu so b ys yt ut yu yv yw uw yx yy yz za zb zc zd ze zf zg zh zi zj zk pj by" data-selectable-paragraph="" id="896b" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Finally will publish the results using “EnricoMi/publish-unit-test-result-action” from the marketplace.</p><pre class="zz aba abb abc wv abd abe eh gm abf abg by" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(107, 107, 107); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="abh abi xu abe b bw abj abk y abl abm" data-selectable-paragraph="" id="0730" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"> <span class="hljs-bullet" style="box-sizing: inherit; color: #1c00cf;">-</span> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">name:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Publish</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Unit</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Test</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">Results</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">uses:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">EnricoMi/publish-unit-test-result-action@v2</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">if:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">always()</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">with:</span><br style="box-sizing: inherit;" /> <span class="hljs-attr" style="box-sizing: inherit; color: #836c28;">junit_files:</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">./src/_test-results/*.xml</span></span></pre><p class="pw-post-body-paragraph yq yr xu so b ys yt ut yu yv yw uw yx yy yz za zb zc zd ze zf zg zh zi zj zk pj by" data-selectable-paragraph="" id="5044" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">We are done so With this if you the actions pipeline you will see the results as:</p><figure class="zz aba abb abc wv abv qv qw paragraph-image" style="box-sizing: inherit; clear: both; margin: 56px auto 0px;"><div class="abw abx cu aby ae abz" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 692px; z-index: auto;" tabindex="0"><div class="qv qw abu" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 776px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/max/640/1*chG9tszlRjCj_4LGdNevEQ.webp 640w, https://miro.medium.com/max/720/1*chG9tszlRjCj_4LGdNevEQ.webp 720w, https://miro.medium.com/max/750/1*chG9tszlRjCj_4LGdNevEQ.webp 750w, https://miro.medium.com/max/786/1*chG9tszlRjCj_4LGdNevEQ.webp 786w, https://miro.medium.com/max/828/1*chG9tszlRjCj_4LGdNevEQ.webp 828w, https://miro.medium.com/max/1100/1*chG9tszlRjCj_4LGdNevEQ.webp 1100w, https://miro.medium.com/max/1400/1*chG9tszlRjCj_4LGdNevEQ.webp 1400w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" srcset="https://miro.medium.com/max/640/1*chG9tszlRjCj_4LGdNevEQ.png 640w, https://miro.medium.com/max/720/1*chG9tszlRjCj_4LGdNevEQ.png 720w, https://miro.medium.com/max/750/1*chG9tszlRjCj_4LGdNevEQ.png 750w, https://miro.medium.com/max/786/1*chG9tszlRjCj_4LGdNevEQ.png 786w, https://miro.medium.com/max/828/1*chG9tszlRjCj_4LGdNevEQ.png 828w, https://miro.medium.com/max/1100/1*chG9tszlRjCj_4LGdNevEQ.png 1100w, https://miro.medium.com/max/1400/1*chG9tszlRjCj_4LGdNevEQ.png 1400w" style="box-sizing: inherit;"></source><img alt="" class="ae aca acb c" height="395" loading="lazy" role="presentation" src="https://miro.medium.com/max/700/1*chG9tszlRjCj_4LGdNevEQ.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 692px;" width="700" /></picture></div></div></figure><p class="pw-post-body-paragraph yq yr xu so b ys yt ut yu yv yw uw yx yy yz za zb zc zd ze zf zg zh zi zj zk pj by acc" data-selectable-paragraph="" id="7fba" style="box-sizing: inherit; clear: left; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="y acd ace acf nc acg ach aci acj ack cu" style="box-sizing: inherit; display: block; float: left; font-size: 66px; line-height: 0.83; margin-right: 12px; padding-top: 7px; position: relative;">N</span>ote: There are various actions available in the GitHub marketplace to publish your test results, please explore them too.</p><p class="pw-post-body-paragraph yq yr xu so b ys yt ut yu yv yw uw yx yy yz za zb zc zd ze zf zg zh zi zj zk pj by" data-selectable-paragraph="" id="d07e" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="so pf" style="box-sizing: inherit; font-weight: 700;">Hope you enjoyed the content, follow me for more like this, and please don’t forget to LIKE it. Happy programming.</span></p><div><span class="so pf" style="box-sizing: inherit; font-weight: 700;"><br /></span></div></div></div></section></div></div></article>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-10566058818403741302022-11-14T11:50:00.004+05:302023-04-04T13:37:46.476+05:30Dockerize VueJS or Angular application<p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEjtvDuCcmTJoC2-MkSFQzhQy7enubuZzt7Ct6P2HVDidCgOYDaiDhH2iGmASp54tPGK0mfxk_fdEVAhRq8NDJVFdlfxuSuqosk7tzeKWqQeTvdoCx4hMPr4uAlaHBIBOS9e7g-KUKvoZx9MpIgKh2Ngkk5Og6ZusbudCskC4l0PdSsf0LujbKSoO8COTQ" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="1126" data-original-width="2320" height="310" src="https://blogger.googleusercontent.com/img/a/AVvXsEjtvDuCcmTJoC2-MkSFQzhQy7enubuZzt7Ct6P2HVDidCgOYDaiDhH2iGmASp54tPGK0mfxk_fdEVAhRq8NDJVFdlfxuSuqosk7tzeKWqQeTvdoCx4hMPr4uAlaHBIBOS9e7g-KUKvoZx9MpIgKh2Ngkk5Og6ZusbudCskC4l0PdSsf0LujbKSoO8COTQ=w640-h310" width="640" /></a></div><br /> <br /><p class="pw-post-body-paragraph im in he io b ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg jh ji jj gx bi" data-selectable-paragraph="" id="be0a" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">For the past couple of months, I spent my time heavily on infrastructure and CICD DevOps activity to host my applications, web, and backend application on Azure Kubernetes Cluster. Also if you follow me, my last few articles were all about a complete setup overview regarding CICD and security.</p><p class="pw-post-body-paragraph im in he io b ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg jh ji jj gx bi" data-selectable-paragraph="" id="2fdd" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">This article is about dockerizing a VueJS or Angular web application, though my web application here was on VueJS, the same technique applies to Angular applications to dockerize the application.</p><p class="pw-post-body-paragraph im in he io b ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg jh ji jj gx bi" data-selectable-paragraph="" id="4590" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Before we begin, we need to take a decision on the server that will serve the application like http-server, Nginx, Apache etc. For development/testing we may use zero-configuration command-line http-server to server our web application but not recommended for production as the documentation says:</p><blockquote class="jk jl jm" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="im in jn io b ip iq ir is it iu iv iw jo iy iz ja jp jc jd je jq jg jh ji jj gx bi" data-selectable-paragraph="" id="4616" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">It is powerful enough for production usage, but it’s simple and hackable enough to be used for testing, local development, and learning.</p></blockquote><p class="pw-post-body-paragraph im in he io b ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg jh ji jj gx bi" data-selectable-paragraph="" id="65aa" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">So, in my case, I decided to use Nginx and this is all you need to do.</p><p class="pw-post-body-paragraph im in he io b ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg jh ji jj gx bi" data-selectable-paragraph="" id="cfe3" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">First, we need to create the DockerFile so add a file name “Dockefile” in your project root folder where package.json or config file exists and add the below code:</p><pre class="jr js jt ju ft jv jw jx bn jy jz bi" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="ka kb he jw b be kc kd l ke kf" data-selectable-paragraph="" id="5978" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">FROM</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">node:16.15.0-alpine</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">as</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">build</span><br style="box-sizing: inherit;" /><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">WORKDIR</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">/app</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">COPY</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">package.*json</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">./</span><br style="box-sizing: inherit;" /><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">COPY</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">.npmrc</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">./</span><br style="box-sizing: inherit;" /><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">COPY</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">.env.production</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">./</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">RUN</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">npm</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">install</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">COPY</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">.</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">.</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">WORKDIR</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">/app</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">RUN</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">npm</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">run</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">build:production</span><br style="box-sizing: inherit;" /><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">RUN</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">rm</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">-f</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">.npmrc</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-comment" style="box-sizing: inherit; color: #007400;"># production</span><br style="box-sizing: inherit;" /><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">FROM</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">nginx:stable-alpine</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">as</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">production</span><br style="box-sizing: inherit;" /><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">COPY</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">./.nginx/nginx.conf</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">/etc/nginx/nginx.conf</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-comment" style="box-sizing: inherit; color: #007400;">## Remove default nginx index page</span><br style="box-sizing: inherit;" /><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">RUN</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">rm</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">-rf</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">/usr/share/nginx/html/*</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">COPY</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">--from=build</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">/app/dist</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">/usr/share/nginx/html</span><br style="box-sizing: inherit;" /><span class="hljs-comment" style="box-sizing: inherit; color: #007400;"># Expose 8030 this is optional</span><br style="box-sizing: inherit;" /><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">CMD</span> [<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"nginx"</span>, <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"-g"</span>, <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"daemon off;"</span>]</span></pre><p class="pw-post-body-paragraph im in he io b ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg jh ji jj gx bi" data-selectable-paragraph="" id="acf9" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">From the above file, first, we mention the build server as Node. In my case, I’m using a specific version of Node which you may change based on your need. Next line set the working folder as app, where the dist folder along with other config files will be created.</p><p class="pw-post-body-paragraph im in he io b ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg jh ji jj gx bi" data-selectable-paragraph="" id="52c9" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">in the next step, we copied our required config files as package.*json (also includes package.lock.json), .npmrc (which contains token to connect and pull dependencies from my repo), .env files. You may add all your config files needed here to keep the code related to copying config files in one place otherwise in the next step (npm install), only package.json and .npmrc files are required.</p><p class="pw-post-body-paragraph im in he io b ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg jh ji jj gx bi" data-selectable-paragraph="" id="9c6c" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">So next we did, npm install and copied all (which include dist folder) to the working directory app folder.</p><p class="pw-post-body-paragraph im in he io b ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg jh ji jj gx bi" data-selectable-paragraph="" id="2daa" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In the next step, we build the application using the <span class="io hf" style="box-sizing: inherit; font-weight: 700;">npm run build</span> command and delete the .npmrc file copied from the first step required for the npm install.</p><p class="pw-post-body-paragraph im in he io b ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg jh ji jj gx bi" data-selectable-paragraph="" id="c269" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now we need to set the web server and we set it here as “<span class="io hf" style="box-sizing: inherit; font-weight: 700;">nginx:stable-alpine</span>”, you may choose other versions too based on your need. Here we need the Nginx configuration file to tell the Nginx server where to start i.e. root, port, no. of worker process, etc. We have not created this file yet so let’s do it by creating a file name <span class="io hf" style="box-sizing: inherit; font-weight: 700;">nginx.conf</span> with the below code inside the .nginx folder in your project root path as <span class="io hf" style="box-sizing: inherit; font-weight: 700;">.nginx=>nginx.conf</span>.</p><pre class="jr js jt ju ft jv jw jx bn jy jz bi" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="ka kb he jw b be kc kd l kg kf" data-selectable-paragraph="" id="3a5b" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content; white-space: pre-wrap;">worker_processes 4;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" />events { worker_connections 1024; }<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" />http {<br style="box-sizing: inherit;" /> server {<br style="box-sizing: inherit;" /> # <span class="jw hf" style="box-sizing: inherit; font-weight: 700;">listen 80</span>; this is optional, it will be default to 80<br style="box-sizing: inherit;" /> <span class="jw hf" style="box-sizing: inherit; font-weight: 700;">root /usr/share/nginx/html;</span><br style="box-sizing: inherit;" /> include /etc/nginx/mime.types;<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /> location /appui {<br style="box-sizing: inherit;" /> try_files $uri /index.html;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph im in he io b ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg jh ji jj gx bi" data-selectable-paragraph="" id="a84d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now we will go back to the Dockerfile and copy this nginx.conf file to the Nginx server inside an etc folder and also remove the default index page from the location usr/share/nginx/html/*</p><pre class="jr js jt ju ft jv jw jx bn jy jz bi" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="ka kb he jw b be kc kd l ke kf" data-selectable-paragraph="" id="058e" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">FROM</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">nginx:stable-alpine</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">as</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">production</span><br style="box-sizing: inherit;" /><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">COPY</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">./.nginx/nginx.conf</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">/etc/nginx/nginx.conf</span><br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" /><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">RUN</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">rm</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">-rf</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">/usr/share/nginx/html/*</span></span></pre><p class="pw-post-body-paragraph im in he io b ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg jh ji jj gx bi" data-selectable-paragraph="" id="7577" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">and then we copy all the contents of the dist folder from the build server to Nginx server inside <span class="io hf" style="box-sizing: inherit; font-weight: 700;">/usr/share/nginx/html </span>and mention the command mentioned below to start the nginx.</p><pre class="jr js jt ju ft jv jw jx bn jy jz bi" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="ka kb he jw b be kc kd l ke kf" data-selectable-paragraph="" id="37b3" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content;"><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">COPY</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">--from=build</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">/app/dist</span> <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">/usr/share/nginx/html</span><br style="box-sizing: inherit;" /><span class="hljs-comment" style="box-sizing: inherit; color: #007400;"># Expose 8030</span><br style="box-sizing: inherit;" /><span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">CMD</span> [<span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"nginx"</span>, <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"-g"</span>, <span class="hljs-string" style="box-sizing: inherit; color: #c41a16;">"daemon off;"</span>]</span></pre><h2 class="kh kb he bd ki kj kk kl km kn ko kp kq ix kr ks kt jb ku kv kw jf kx ky kz la bi" data-selectable-paragraph="" id="6759" style="background-color: white; box-sizing: inherit; color: #292929; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 20px; line-height: 24px; margin: 2.37em 0px -0.31em;"><span class="ak" style="box-sizing: inherit; font-weight: inherit;">Testing</span></h2><p class="pw-post-body-paragraph im in he io b ip lb ir is it lc iv iw ix ld iz ja jb le jd je jf lf jh ji jj gx bi" data-selectable-paragraph="" id="c09c" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 0.86em 0px -0.46em; word-break: break-word;">If you have a docker desktop installed, follow the steps below to test.</p><p class="pw-post-body-paragraph im in he io b ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg jh ji jj gx bi" data-selectable-paragraph="" id="667f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">step 1: run the below command using the command prompt from your project root folder where the package.json file exists.</p><pre class="jr js jt ju ft jv jw jx bn jy jz bi" style="background: rgb(249, 249, 249); border-radius: 4px; border: 1px solid rgb(229, 229, 229); box-sizing: inherit; color: #292929; font-family: source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 32px;"><span class="ka kb he jw b be kc kd l kg kf" data-selectable-paragraph="" id="98ee" style="box-sizing: inherit; display: block; font-size: 14px; letter-spacing: -0.022em; line-height: 1.4; margin-bottom: -0.2em; margin-top: -0.2em; min-width: fit-content; white-space: pre-wrap;"><span class="jw hf" style="box-sizing: inherit; font-weight: 700;">docker build -t test/webapp_v1 .</span></span></pre><p class="pw-post-body-paragraph im in he io b ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg jh ji jj gx bi" data-selectable-paragraph="" id="641c" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">After the successful execution of the above command, you will see the image created in the docker desktop under <span class="io hf" style="box-sizing: inherit; font-weight: 700;">Images</span>.</p><p class="pw-post-body-paragraph im in he io b ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg jh ji jj gx bi" data-selectable-paragraph="" id="921c" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">step 2: Click on Run and change the port setting from the host server and container as per our docker file and nginx.conf file where our container is exposed through port 8030 and the host server is at port 80. Please refer to the below screenshot:</p><figure class="jr js jt ju ft if fh fi paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="fh fi lg" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 560px;"><picture style="box-sizing: inherit;"><source sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 560px" srcset="https://miro.medium.com/v2/resize:fit:640/format:webp/1*OPVG2UXctLtRqXcy0yLTgw.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*OPVG2UXctLtRqXcy0yLTgw.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*OPVG2UXctLtRqXcy0yLTgw.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*OPVG2UXctLtRqXcy0yLTgw.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*OPVG2UXctLtRqXcy0yLTgw.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*OPVG2UXctLtRqXcy0yLTgw.png 1100w, https://miro.medium.com/v2/resize:fit:1120/format:webp/1*OPVG2UXctLtRqXcy0yLTgw.png 1120w" style="box-sizing: inherit;" type="image/webp"></source><source data-testid="og" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 560px" srcset="https://miro.medium.com/v2/resize:fit:640/1*OPVG2UXctLtRqXcy0yLTgw.png 640w, https://miro.medium.com/v2/resize:fit:720/1*OPVG2UXctLtRqXcy0yLTgw.png 720w, https://miro.medium.com/v2/resize:fit:750/1*OPVG2UXctLtRqXcy0yLTgw.png 750w, https://miro.medium.com/v2/resize:fit:786/1*OPVG2UXctLtRqXcy0yLTgw.png 786w, https://miro.medium.com/v2/resize:fit:828/1*OPVG2UXctLtRqXcy0yLTgw.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*OPVG2UXctLtRqXcy0yLTgw.png 1100w, https://miro.medium.com/v2/resize:fit:1120/1*OPVG2UXctLtRqXcy0yLTgw.png 1120w" style="box-sizing: inherit;"></source><img alt="" class="bf ik il c" height="379" loading="lazy" role="presentation" src="https://miro.medium.com/v2/resize:fit:560/1*OPVG2UXctLtRqXcy0yLTgw.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 560px;" width="560" /></picture></div></figure><p class="pw-post-body-paragraph im in he io b ip iq ir is it iu iv iw ix iy iz ja jb jc jd je jf jg jh ji jj gx bi" data-selectable-paragraph="" id="3f0d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now open the browser and type <a class="ae lh" href="http://localhost/" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank"><span class="io hf" style="box-sizing: inherit; font-weight: 700;">http://localhost:8090/</span></a> to browse the application and your web app is up.</p><h2 class="kx kr ig bm ky kz la lb lc ld le lf lg jo lh li lj js lk ll lm jw ln lo lp lq gh" data-selectable-paragraph="" id="55d3" style="background-color: white; box-sizing: inherit; color: #292929; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 20px; line-height: 24px; margin: 2.37em 0px -0.31em;">Bonus</h2><p class="pw-post-body-paragraph jd je ig jf b jg lr ji jj jk ls jm jn jo lt jq jr js lu ju jv jw lv jy jz ka hz gh" data-selectable-paragraph="" id="381c" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 0.86em 0px -0.46em; word-break: break-word;">Please follow my previous articles to push this image to Azure Container Registery and deploy it on Azure Kubernetes Cluster using GitHub Actions. Though these articles are for hosting .net core app but the steps remain the same with little modification as per the web app.</p><ol style="background-color: white; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; list-style: none none; margin: 0px; padding: 0px;"><li class="mb mc ig jf b jg jh jk jl jo md js me jw mf ka mg mh mi mj gh" data-selectable-paragraph="" id="18cc" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 2.14em; padding-left: 0px;"><a class="au ma" href="https://binodmahto.blogspot.com/2022/10/cicd-with-github-actions-to-deploy.html" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">CI/CD with GitHub Actions to deploy Applications to Azure Kubernetes Cluster</a></li><li class="mb mc ig jf b jg mk jk ml jo mm js mn jw mo ka mg mh mi mj gh" data-selectable-paragraph="" id="3a5e" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;"><a class="au ma" href="https://binodmahto.blogspot.com/2022/10/securing-secrets-with-azure-key-vault.html" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">Securing secrets with Azure Key Vault for GitHub Actions</a></li></ol><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="5a75" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jf ih" style="box-sizing: inherit; font-weight: 700;">Hope you enjoyed the content, follow me for more like this, and please don’t forget to clap for it. Happy programming.</span></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-61580560130143209332022-10-28T10:06:00.006+05:302022-10-28T10:12:26.715+05:30Serilog logging with .Net Core — Are we configuring it correctly?<p> <span face="source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif" style="background-color: white; color: #292929; font-size: 20px; letter-spacing: -0.003em;">Like many other libraries for .NET, Serilog provides diagnostic logging to files, the console, and elsewhere. It is easy to set up, has a clean API, and is portable between recent .NET platforms.</span></p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="77c7" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">It is very easy to setup but question is Are we doing it correctly?</p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="2500" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">To start with Serilog with .net core, we need to do two important tasks:</p><ol style="background-color: white; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; list-style: none none; margin: 0px; padding: 0px;"><li class="kb kc ig jf b jg jh jk jl jo kd js ke jw kf ka kg kh ki kj gh" data-selectable-paragraph="" id="a752" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 2.14em; padding-left: 0px;">Configure the settings for Serilog through config file.</li></ol><pre class="kk kl km kn fy ko bs kp kq dz kr" style="background: rgb(242, 242, 242); border-radius: 0px; border: none; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gh ks kt ig kr b dm ku kv l kw kx" data-selectable-paragraph="" id="c590" style="box-sizing: inherit; color: #292929; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; min-width: fit-content; white-space: pre-wrap;">"Serilog": {<br style="box-sizing: inherit;" /> "Using": [<br style="box-sizing: inherit;" /> "Serilog.Sinks.Console"<br style="box-sizing: inherit;" /> ],<br style="box-sizing: inherit;" /> "MinimumLevel": {<br style="box-sizing: inherit;" /> "Default": "Information",<br style="box-sizing: inherit;" /> "Override": {<br style="box-sizing: inherit;" /> "Host": "Error",<br style="box-sizing: inherit;" /> "Microsoft": "Error",<br style="box-sizing: inherit;" /> "System": "Error",<br style="box-sizing: inherit;" /> "Microsoft.AspNetCore": "Error"<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> "WriteTo": [<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> "Name": "Async",<br style="box-sizing: inherit;" /> "Args": {<br style="box-sizing: inherit;" /> "configure": [<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> "Name": "Console",<br style="box-sizing: inherit;" /> "Args": {<br style="box-sizing: inherit;" /> "formatter": "Serilog.Formatting.Compact.RenderedCompactJsonFormatter, Serilog.Formatting.Compact"<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> ]<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> ]<br style="box-sizing: inherit;" /> }</span></pre><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="061f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In above setting we configure three important steps,<br style="box-sizing: inherit;" />a: Definethe sink<br style="box-sizing: inherit;" />- <em class="ky" style="box-sizing: inherit;">sinks</em> are for writing log events to storage in various formats. Here are the complete list of sinks provided by Serilog:<br style="box-sizing: inherit;" /><a class="au kz" href="https://github.com/serilog/serilog/wiki/Provided-Sinks" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://github.com/serilog/serilog/wiki/Provided-Sinks</a></p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="d8fc" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">b: Configure the minimum log level which we overriding to Error for Host, System and framework errors.</p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="7d3f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">c: Define the WriteTo format for the log events. You can define your custom format of the data being logged here. i.e.</p><pre class="kk kl km kn fy ko bs kp kq dz kr" style="background: rgb(242, 242, 242); border-radius: 0px; border: none; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gh ks kt ig kr b dm ku kv l kw kx" data-selectable-paragraph="" id="ff92" style="box-sizing: inherit; color: #292929; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; min-width: fit-content; white-space: pre-wrap;">"WriteTo": [<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> "Name": "Console",<br style="box-sizing: inherit;" /> "Args": {<br style="box-sizing: inherit;" /> <span class="kr ih" style="box-sizing: inherit; font-weight: 700;">"outputTemplate": "[{Timestamp:HH:mm:ss} {SourceContext} [{Level}] {Message}{NewLine}{Exception}",</span><br style="box-sizing: inherit;" /> <span class="kr ih" style="box-sizing: inherit; font-weight: 700;"> "theme": "Serilog.Sinks.SystemConsole.Themes.SystemConsoleTheme::Grayscale, Serilog.Sinks.Console"</span><br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> ]</span></pre><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="ac69" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">2. Initialize serilog as loggingProvider in Program.cs</p><pre class="kk kl km kn fy ko bs kp kq dz kr" style="background: rgb(242, 242, 242); border-radius: 0px; border: none; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gh ks kt ig kr b dm ku kv l kw kx" data-selectable-paragraph="" id="42b8" style="box-sizing: inherit; color: #292929; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; min-width: fit-content; white-space: pre-wrap;">var logger = new LoggerConfiguration().ReadFrom.Configuration(builder.Configuration).CreateLogger();<br style="box-sizing: inherit;" />builder.Host.UseSerilog(logger, dispose: true);</span></pre><blockquote class="la lb lc" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="jd je ky jf b jg jh ji jj jk jl jm jn ld jp jq jr le jt ju jv lf jx jy jz ka hz gh" data-selectable-paragraph="" id="7feb" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Wait, are we doing it correctly. <span class="jf ih" style="box-sizing: inherit; font-weight: 700;">Of course Not!</span> Above code has a security issue and it has led in the past to the following vulnerabilities:<br style="box-sizing: inherit;" />CVE-2018–0285<br style="box-sizing: inherit;" />CVE-2000–1127<br style="box-sizing: inherit;" />CVE-2017–15113<br style="box-sizing: inherit;" />CVE-2015–5742</p></blockquote><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="93ea" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">So how we correct it then. well, this is how you can correctly initialize the serilog as logging provider through the Action method parameter, instead of creating a new instance of LoggerConfiguration. Here is the code:</p><pre class="kk kl km kn fy ko bs kp kq dz kr" style="background: rgb(242, 242, 242); border-radius: 0px; border: none; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gh ks kt ig kr b dm ku kv l kw kx" data-selectable-paragraph="" id="0537" style="box-sizing: inherit; color: #292929; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; min-width: fit-content; white-space: pre-wrap;">builder.Host.UseSerilog((hostingContext, loggerConfiguration) =><br style="box-sizing: inherit;" />{<br style="box-sizing: inherit;" /> loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration);<br style="box-sizing: inherit;" />});</span></pre><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="b6b1" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In this case, .Net Core infrastructure will take care of loggerConfiguration through dependency resolver internally based on your config setting which is secured.</p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="3eea" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Finally Here is the complete code to properly initialize serilog as logging provider by reading config from appsettings.{your_environment}.json files.</p><pre class="kk kl km kn fy ko bs kp kq dz kr" style="background: rgb(242, 242, 242); border-radius: 0px; border: none; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gh ks kt ig kr b dm ku kv l kw kx" data-selectable-paragraph="" id="a3ee" style="box-sizing: inherit; color: #292929; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; min-width: fit-content; white-space: pre-wrap;">using Serilog;
var builder = WebApplication.CreateBuilder(args);</span><span class="gh ks kt ig kr b dm lg kv l kw kx" data-selectable-paragraph="" id="411d" style="box-sizing: inherit; color: #292929; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 0.91em; min-width: fit-content; white-space: pre-wrap;">// read configuration information from appsettings.enviorment.json </span><span class="gh ks kt ig kr b dm lg kv l kw kx" data-selectable-paragraph="" id="8b33" style="box-sizing: inherit; color: #292929; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 0.91em; min-width: fit-content; white-space: pre-wrap;">builder.Host.ConfigureAppConfiguration((hostingContext, config) =><br style="box-sizing: inherit;" />{<br style="box-sizing: inherit;" /> var env = hostingContext.HostingEnvironment;<br style="box-sizing: inherit;" /> config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)<br style="box-sizing: inherit;" /> .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);<br style="box-sizing: inherit;" /> config.AddEnvironmentVariables();<br style="box-sizing: inherit;" />});</span><span class="gh ks kt ig kr b dm lg kv l kw kx" data-selectable-paragraph="" id="0cac" style="box-sizing: inherit; color: #292929; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 0.91em; min-width: fit-content; white-space: pre-wrap;"><span class="kr ih" style="box-sizing: inherit; font-weight: 700;">builder.Host.UseSerilog((hostingContext, loggerConfiguration) =><br style="box-sizing: inherit;" />{<br style="box-sizing: inherit;" /> loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration);<br style="box-sizing: inherit;" />});</span></span></pre><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="dcaf" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jf ih" style="box-sizing: inherit; font-weight: 700;">Hope you enjoyed the content, follow me for more like this and please don’t forget to like/comment for it. Happy programming.</span></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-90378916298542546542022-10-27T11:51:00.004+05:302022-10-27T11:59:57.625+05:30Securing secrets with Azure Key Vault for GitHub Actions<p> <span face="source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif" style="background-color: white; color: #292929; font-size: 20px; letter-spacing: -0.003em;">If you are following me, I have published two articles before, about</span><span face="source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif" style="background-color: white; color: #292929; font-size: 20px; letter-spacing: -0.003em;"> </span><a class="au kb" href="https://binodmahto.blogspot.com/2022/08/cicd-with-github-actions-to-deploy.html" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;" target="_blank">CI/CD with GitHub Actions to deploy Application to Azure App Service</a><span face="source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif" style="background-color: white; color: #292929; font-size: 20px; letter-spacing: -0.003em;"> </span><span face="source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif" style="background-color: white; color: #292929; font-size: 20px; letter-spacing: -0.003em;">and</span><span face="source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif" style="background-color: white; color: #292929; font-size: 20px; letter-spacing: -0.003em;"> </span><a class="au kb" href="https://binodmahto.blogspot.com/2022/10/cicd-with-github-actions-to-deploy.html" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;" target="_blank">CI/CD with GitHub Actions to deploy Application to Azure Kubernetes Cluster</a><span face="source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif" style="background-color: white; color: #292929; font-size: 20px; letter-spacing: -0.003em;">.</span></p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="4e83" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In both the articles I gave the example of keeping secrets in GitHub Environments but what if you want to store your secrets in Azure Key Vaults which has the advantage over Github secrets. Like, You can verify the secrets value in azure key vault and can be upgraded programmatically too to new version if needed and also you can control the access permission based on need.<br style="box-sizing: inherit;" />So here is the example to prepare your appsettings.production.js or other config files by reading secrets from Azure Key Vaults. Follow the steps here to do so:</p><ol style="background-color: white; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; list-style: none none; margin: 0px; padding: 0px;"><li class="kc kd ig jf b jg jh jk jl jo ke js kf jw kg ka kh ki kj kk gh" data-selectable-paragraph="" id="5f6b" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 2.14em; padding-left: 0px;">First thing we would need is, Connectivity to Azure so that pipeline can do the azure login and for this purpose I suggest always to use service principal instead of user id & password. This is the only settings which you need to store as part of GitHub Secrets so that using this you can do the Azure login.<br />Here is command to generate the service principal .</li></ol><pre class="kl km kn ko fy kp bs kq kr dz ks" style="background: rgb(242, 242, 242); border-radius: 0px; border: none; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gh kt ku ig ks b dm kv kw l kx ky" data-selectable-paragraph="" id="0039" style="box-sizing: inherit; color: #292929; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; min-width: fit-content; white-space: pre-wrap;">az ad sp create-for-rbac --name "{your_service<span style="letter-spacing: -0.022em;">principal</span><span style="letter-spacing: -0.022em;">_name}" --scope /subscriptions/{subscription_id}/resourceGroups/{</span><span color="rgba(0, 0, 0, 0.8)" style="letter-spacing: -0.022em;">resourceGroupName</span><span style="letter-spacing: -0.022em;">} --role Contributor --sdk-auth</span></span></pre><blockquote class="kz la lb" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="jd je lc jf b jg jh ji jj jk jl jm jn ld jp jq jr le jt ju jv lf jx jy jz ka hz gh" data-selectable-paragraph="" id="2573" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Note: I’m creating service principal with contributor role at resource group level for my need, but I would recommend the role to be downgraded for access based on your need.</p></blockquote><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="fa4c" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">2. Next we need to provide the access to above created service <span style="background-color: transparent;">principal </span><span style="letter-spacing: -0.003em;">for accessing the secrets from key vault and for this please login to the azure portal and navigate to your Key Vault => Access policies and click on +Create.</span></p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">From the <span class="jf ih" style="box-sizing: inherit; font-weight: 700;">Permission </span>tab: select Get, List, Decrypt of Key Permissions and Get, List of Secret Permissions and Certificate Permissions.<br style="box-sizing: inherit;" />From the <span class="jf ih" style="box-sizing: inherit; font-weight: 700;">Principal </span>tab: search your service principal and select.</p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="ae75" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">3. Set up is done, now do the code in Github action to read the secrets from Azure Key Vault.</p><pre class="kl km kn ko fy kp bs kq kr dz ks" style="background: rgb(242, 242, 242); border-radius: 0px; border: none; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gh kt ku ig ks b dm kv kw l kx ky" data-selectable-paragraph="" id="20bc" style="box-sizing: inherit; color: #292929; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; min-width: fit-content; white-space: pre-wrap;">steps:<br style="box-sizing: inherit;" /> - uses: <span class="ks ih" style="box-sizing: inherit; font-weight: 700;">actions/checkout@v2</span></span><span class="gh kt ku ig ks b dm lg kw l kx ky" data-selectable-paragraph="" id="f62b" style="box-sizing: inherit; color: #292929; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 0.91em; min-width: fit-content; white-space: pre-wrap;"> - uses: <span class="ks ih" style="box-sizing: inherit; font-weight: 700;">Azure/login@v1</span><br style="box-sizing: inherit;" /> with:<br style="box-sizing: inherit;" /> creds: ${{ secrets.YourServicePrincipal }}</span><span class="gh kt ku ig ks b dm lg kw l kx ky" data-selectable-paragraph="" id="4b95" style="box-sizing: inherit; color: #292929; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 0.91em; min-width: fit-content; white-space: pre-wrap;"> - uses: <span class="ks ih" style="box-sizing: inherit; font-weight: 700;">Azure/get-keyvault-secrets@v1</span><br style="box-sizing: inherit;" /> with: <br style="box-sizing: inherit;" /> keyvault: "{Your_KeyVaultName}"<br style="box-sizing: inherit;" /> secrets: 'CONNECTIONSTRING'<br style="box-sizing: inherit;" /> id: azKeyVaultSecretAction</span><span class="gh kt ku ig ks b dm lg kw l kx ky" data-selectable-paragraph="" id="d338" style="box-sizing: inherit; color: #292929; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 0.91em; min-width: fit-content; white-space: pre-wrap;"> - name: Replace token for appsettings.Production.json<br style="box-sizing: inherit;" /> uses: <span class="ks ih" style="box-sizing: inherit; font-weight: 700;">cschleiden/replace-tokens@v1.1</span><br style="box-sizing: inherit;" /> with:<br style="box-sizing: inherit;" /> files: '["src/MyDemoApp/appsettings.Production.json"]'<br style="box-sizing: inherit;" /> env:<br style="box-sizing: inherit;" /> ConnectionString: ${{ steps.azKeyVaultSecretAction.outputs.CONNECTIONSTRING }}</span></pre><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="ae25" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">From the above code,<br style="box-sizing: inherit;" />a. first we are doing code checkout for the code repository,<br style="box-sizing: inherit;" />b. Logging in to the Azure and ‘YourServicePrincipa’ is the secrets stored on GitHub environment which you created from 1st step here. ,<br style="box-sizing: inherit;" />c. Reading secret ‘CONNECTIONSTRING’ from Azure Key Vault. and finally<br style="box-sizing: inherit;" />d. Using the secrets ‘ConnectionString’ to replace in appsettings.Production.json.</p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="90ec" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Note: In case of multiple secrets reading, please mention all your secrets name with comma separated i.e.</p><pre class="kl km kn ko fy kp bs kq kr dz ks" style="background: rgb(242, 242, 242); border-radius: 0px; border: none; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: Menlo, Monaco, "Courier New", Courier, monospace; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gh kt ku ig ks b dm kv kw l kx ky" data-selectable-paragraph="" id="4005" style="box-sizing: inherit; color: #292929; display: block; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; min-width: fit-content; white-space: pre-wrap;">secrets: 'CONNECTIONSTRING, OTHERSECRETS1, OTHERSECRETS2'</span></pre><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="2b86" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">and We are done! Please refer my previously published articles for complete end-to-end GitHub actions.</p><p class="pw-post-body-paragraph jd je ig jf b jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka hz gh" data-selectable-paragraph="" id="7fd3" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jf ih" style="box-sizing: inherit; font-weight: 700;">Hope you enjoyed the content, follow me for more like this and please don’t forget to like/comment for it. Happy programming.</span></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-2252427233113178612022-10-06T16:30:00.003+05:302022-10-27T12:02:36.351+05:30CI/CD with GitHub Actions to deploy Application to Azure Kubernetes Cluster<p> <span face="source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif" style="background-color: white; color: #292929; font-size: 20px; letter-spacing: -0.003em;">This article here is going to be bit lengthy but if you stay with me, I’m sure it would be one stop learning for your application to automate the deployment on Azure Kubernete Service.</span></p><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="9475" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">I assume, you know the basics about Kubernetes cluster and here we will be using Azure Kuberenete Service to orchestrate my kubernete cluster. We would need Ingress Controller to expose the pod for public access and in this example I’ll be using Azure Application Gateway to expose the service running in pods.</p><figure class="jw jx jy jz ge ka fs ft paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="kb kc do kd ce ke" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 692px; z-index: auto;" tabindex="0"><div class="fs ft jv" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 861px;"><img alt="" class="ce kf kg c" height="422" loading="eager" role="presentation" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" src="https://miro.medium.com/max/1400/0*LK1-_AS4ubNxjwev.png" srcset="https://miro.medium.com/max/640/0*LK1-_AS4ubNxjwev.png 640w, https://miro.medium.com/max/720/0*LK1-_AS4ubNxjwev.png 720w, https://miro.medium.com/max/750/0*LK1-_AS4ubNxjwev.png 750w, https://miro.medium.com/max/786/0*LK1-_AS4ubNxjwev.png 786w, https://miro.medium.com/max/828/0*LK1-_AS4ubNxjwev.png 828w, https://miro.medium.com/max/1100/0*LK1-_AS4ubNxjwev.png 1100w, https://miro.medium.com/max/1400/0*LK1-_AS4ubNxjwev.png 1400w" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 692px;" width="700" /></div></div></figure><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="c642" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">AGIC is Azure Gateway Ingress Controller which allows Azure Application Gateway to be used as the ingress for the AKS Cluster.</p><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="35e0" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="iz ib" style="box-sizing: inherit; font-weight: 700;">Prerequisites</span>:</p><ol style="background-color: white; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; list-style: none none; margin: 0px; padding: 0px;"><li class="kh ki ia iz b ja jb je jf ji kj jm kk jq kl ju km kn ko kp gn" data-selectable-paragraph="" id="76ef" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 2.14em; padding-left: 0px;">Azure Kubernetes Cluster with Azure Container Registry.<br />Reference: <a class="au lk" href="https://learn.microsoft.com/en-us/azure/aks/learn/quick-kubernetes-deploy-portal?tabs=azure-cli" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit; letter-spacing: -0.06px;" target="_blank">https://learn.microsoft.com/en-us/azure/aks/learn/quick-kubernetes-deploy-portal?tabs=azure-cli</a></li><li class="kh ki ia iz b ja kq je kr ji ks jm kt jq ku ju km kn ko kp gn" data-selectable-paragraph="" id="4da8" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">kubernete Service Namespaces where all our services and ingress will be created. You can use the default namespace too.</li><li class="kh ki ia iz b ja kq je kr ji ks jm kt jq ku ju km kn ko kp gn" data-selectable-paragraph="" id="cef0" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">Azure Application Gateway with a public IP. If your Azure Application Gateway and AKS Cluster both are in different VNet then don’t forget the pair them both for seamless connectivity between pods and app gateway.<br />Reference: <a class="au lk" href="https://learn.microsoft.com/en-us/azure/application-gateway/tutorial-ingress-controller-add-on-existing" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit; letter-spacing: -0.06px;" target="_blank">https://learn.microsoft.com/en-us/azure/application-gateway/tutorial-ingress-controller-add-on-existing</a></li></ol><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="3299" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now lets create github action to deploy the application to the cluster and expose it through the Azure Application Gateway and to do so follow the steps below:</p><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="07bb" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="iz ib" style="box-sizing: inherit; font-weight: 700;">Step 1: </span>First thing we need to create a docker container of our application to host on kubernetes cluster and to do so add the dockerFile to your main project and save it as Dockerfile.</p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="6a5f" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS base<br style="box-sizing: inherit;" />WORKDIR /app<br style="box-sizing: inherit;" />EXPOSE 8080</span><span class="gn kx ky ia kz b dm ld le lf lg lh lb l lc" data-selectable-paragraph="" id="ed7b" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">ENV ASPNETCORE_URLS=<a class="au li" href="http://+:8080/" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">http://+:8080</a></span><span class="gn kx ky ia kz b dm ld le lf lg lh lb l lc" data-selectable-paragraph="" id="45f9" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine AS build<br style="box-sizing: inherit;" />COPY . .<br style="box-sizing: inherit;" />WORKDIR "./MyApp"<br style="box-sizing: inherit;" />RUN dotnet build "MyApp.csproj" -c Release -o /app/build</span><span class="gn kx ky ia kz b dm ld le lf lg lh lb l lc" data-selectable-paragraph="" id="904f" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">FROM build AS publish<br style="box-sizing: inherit;" />RUN dotnet publish "MyApp.csproj" -c Release -o /app/publish</span><span class="gn kx ky ia kz b dm ld le lf lg lh lb l lc" data-selectable-paragraph="" id="e68e" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">FROM base AS final<br style="box-sizing: inherit;" />WORKDIR /app<br style="box-sizing: inherit;" />COPY --from=publish /app/publish .<br style="box-sizing: inherit;" />ENTRYPOINT ["dotnet", "MyApp.dll"]</span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="2b80" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In the above docker file, I’m copying everything to build server and setting the work directory as MyApp where MyApp.csproj is available then do the build & publish.</p><blockquote class="lj lk ll" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="ix iy lm iz b ja jb jc jd je jf jg jh ln jj jk jl lo jn jo jp lp jr js jt ju ht gn" data-selectable-paragraph="" id="160a" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Note: You can also generate the docker file through Visual Studio if you enable the docker support Or through Visual Studio Code if you have docker extension installed. If Yes, the just pres ctrl+shift+p in visual studio code and type command >docker</p></blockquote><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="f743" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="iz ib" style="box-sizing: inherit; font-weight: 700;">Step 2:</span> We would need Azure credentials to connect to azure and save it with azure github secret. For this we will generate the credentials by running below command through command prompt.</p><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="9ee2" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In command prompt first do the azure login with: > az login<br style="box-sizing: inherit;" />now run the command to create the credentials:<br style="box-sizing: inherit;" />> az ad sp create-for-rbac — name “MyApp” — scope /subscriptions/{subscription_id}/resourceGroups/{resourceGroupName} — role Contributor — sdk-auth</p><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="bd37" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Above command will output result like below, save it in github environment secret.</p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="7608" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">{<br style="box-sizing: inherit;" /> "clientId": "*********",<br style="box-sizing: inherit;" /> "clientSecret": "*********",<br style="box-sizing: inherit;" /> "subscriptionId": "**********",<br style="box-sizing: inherit;" /> "tenantId": "*********",<br style="box-sizing: inherit;" /> "activeDirectoryEndpointUrl": "<a class="au li" href="https://login.microsoftonline.com/" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://login.microsoftonline.com</a>",<br style="box-sizing: inherit;" /> "resourceManagerEndpointUrl": "<a class="au li" href="https://management.azure.com/" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://management.azure.com/</a>",<br style="box-sizing: inherit;" /> "activeDirectoryGraphResourceId": "<a class="au li" href="https://graph.windows.net/" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://graph.windows.net/</a>",<br style="box-sizing: inherit;" /> "sqlManagementEndpointUrl": "<a class="au li" href="https://management.core.windows.net:8443/" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://management.core.windows.net:8443/</a>",<br style="box-sizing: inherit;" /> "galleryEndpointUrl": "<a class="au li" href="https://gallery.azure.com/" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://gallery.azure.com/</a>",<br style="box-sizing: inherit;" /> "managementEndpointUrl": "<a class="au li" href="https://management.core.windows.net/" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://management.core.windows.net/</a>"<br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="2b0e" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="iz ib" style="box-sizing: inherit; font-weight: 700;">Step 3:</span> To host the application to kubernete cluster we need to create files as deployment.yml (for container deployment to pods), service.yml (to expose the proxy to access application running in pods, it will be internal) and ingress-appgateway.yml (the ingress controller which will expose the application for public access).</p><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="8cb7" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">if you want You merge all these to a single file but for better understanding and seperation I’m keeping them separate. So first I’ll create a folder name as <span class="iz ib" style="box-sizing: inherit; font-weight: 700;">k8s (you can name any) </span>in the parent directory to keep all file. Hence my directory looks like:</p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="181f" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">src<br style="box-sizing: inherit;" /> k8s<br style="box-sizing: inherit;" /> MyApp<br style="box-sizing: inherit;" /> .<br style="box-sizing: inherit;" /> .<br style="box-sizing: inherit;" /> MyApp.csproj</span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="573a" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Here are the files. <span class="iz ib" style="box-sizing: inherit; font-weight: 700;">deployment.yml</span></p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="f927" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">apiVersion: apps/v1<br style="box-sizing: inherit;" />kind: Deployment<br style="box-sizing: inherit;" />metadata:<br style="box-sizing: inherit;" /> name: myappservice<br style="box-sizing: inherit;" />spec:<br style="box-sizing: inherit;" /> <span class="kz ib" style="box-sizing: inherit; font-weight: 700;">selector:<br style="box-sizing: inherit;" /> matchLabels:<br style="box-sizing: inherit;" /> app: myappservice</span><br style="box-sizing: inherit;" /> template:<br style="box-sizing: inherit;" /> metadata:<br style="box-sizing: inherit;" /> labels:<br style="box-sizing: inherit;" /> app: myappservice<br style="box-sizing: inherit;" /> spec:<br style="box-sizing: inherit;" /> containers:<br style="box-sizing: inherit;" /> - name: myappservice<br style="box-sizing: inherit;" /> image: #{CONTAINER_IMAGE}#<br style="box-sizing: inherit;" /> imagePullPolicy: Always<br style="box-sizing: inherit;" /> env:<br style="box-sizing: inherit;" /> - name: ASPNETCORE_ENVIRONMENT<br style="box-sizing: inherit;" /> value: "Production"<br style="box-sizing: inherit;" /> - name: ASPNETCORE_URLS<br style="box-sizing: inherit;" /> value: <a class="au li" href="http://+:8080/" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">http://+:8080</a><br style="box-sizing: inherit;" /> livenessProbe:<br style="box-sizing: inherit;" /> httpGet:<br style="box-sizing: inherit;" /> path: /health/ping<br style="box-sizing: inherit;" /> port: 8080<br style="box-sizing: inherit;" /> initialDelaySeconds: 5<br style="box-sizing: inherit;" /> periodSeconds: 60<br style="box-sizing: inherit;" /> timeoutSeconds: 15<br style="box-sizing: inherit;" /> failureThreshold: 3<br style="box-sizing: inherit;" /> successThreshold: 1<br style="box-sizing: inherit;" /> readinessProbe:<br style="box-sizing: inherit;" /> httpGet:<br style="box-sizing: inherit;" /> path: /health/ping<br style="box-sizing: inherit;" /> port: 8080<br style="box-sizing: inherit;" /> initialDelaySeconds: 5<br style="box-sizing: inherit;" /> periodSeconds: 60<br style="box-sizing: inherit;" /> timeoutSeconds: 15<br style="box-sizing: inherit;" /> failureThreshold: 3<br style="box-sizing: inherit;" /> successThreshold: 1<br style="box-sizing: inherit;" /> ports:<br style="box-sizing: inherit;" /> - containerPort: 8080<br style="box-sizing: inherit;" /> imagePullSecrets:<br style="box-sizing: inherit;" /> - name: #{CONTAINER_REGISTRY_SECRET}#</span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="36f0" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="iz ib" style="box-sizing: inherit; font-weight: 700;">service.yml</span></p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="46c0" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">apiVersion: v1<br style="box-sizing: inherit;" />kind: Service<br style="box-sizing: inherit;" />metadata:<br style="box-sizing: inherit;" /> name: myappservice-service<br style="box-sizing: inherit;" />spec:<br style="box-sizing: inherit;" /> <span class="kz ib" style="box-sizing: inherit; font-weight: 700;">selector:</span><br style="box-sizing: inherit;" /> <span class="kz ib" style="box-sizing: inherit; font-weight: 700;">app: myappservice</span><br style="box-sizing: inherit;" /> ports:<br style="box-sizing: inherit;" /> - protocol: TCP<br style="box-sizing: inherit;" /> port: 80<br style="box-sizing: inherit;" /> targetPort: 8080<br style="box-sizing: inherit;" /> type: ClusterIP</span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="ee70" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="iz ib" style="box-sizing: inherit; font-weight: 700;">ingress-appgateway.yml</span></p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="6403" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">apiVersion: networking.k8s.io/v1<br style="box-sizing: inherit;" />kind: Ingress<br style="box-sizing: inherit;" />metadata:<br style="box-sizing: inherit;" /> name: myappservice-ingress-appgateway<br style="box-sizing: inherit;" /> labels:<br style="box-sizing: inherit;" /> website: myapp<br style="box-sizing: inherit;" /> annotations:<br style="box-sizing: inherit;" /> kubernetes.io/ingress.class: azure/application-gateway</span><span class="gn kx ky ia kz b dm ld le lf lg lh lb l lc" data-selectable-paragraph="" id="55b1" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">spec:<br style="box-sizing: inherit;" /> rules:<br style="box-sizing: inherit;" /> - http:<br style="box-sizing: inherit;" /> paths:<br style="box-sizing: inherit;" /> - path: /(.*)<br style="box-sizing: inherit;" /> pathType: Prefix<br style="box-sizing: inherit;" /> backend:<br style="box-sizing: inherit;" /> <span class="kz ib" style="box-sizing: inherit; font-weight: 700;">service</span>:<br style="box-sizing: inherit;" /> <span class="kz ib" style="box-sizing: inherit; font-weight: 700;">name: myappservice-service</span><br style="box-sizing: inherit;" /> port:<br style="box-sizing: inherit;" /> number: 80<br style="box-sizing: inherit;" /> pathType: Exact</span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="28e5" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Above all three files are self explanatory if are aware of basic concepts of kubernete clusters but still I have highlighted the names string which should match with what you name your deployment app and service.</p><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="ace3" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="iz ib" style="box-sizing: inherit; font-weight: 700;">Step 4:</span> Now lets start creating the github Action pipeline by adding yml file as ./.github/workflows/service-deploy.yml and below code.</p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="2730" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">name: service-deploy</span><span class="gn kx ky ia kz b dm ld le lf lg lh lb l lc" data-selectable-paragraph="" id="c078" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">on:<br style="box-sizing: inherit;" /> workflow_dispatch:<br style="box-sizing: inherit;" /> push:<br style="box-sizing: inherit;" /> branches:<br style="box-sizing: inherit;" /> - master</span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="3e03" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">With above setting, workflow will be executed whenever there is code push in the master branch.</p><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="bb9c" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="iz ib" style="box-sizing: inherit; font-weight: 700;">Step 5:</span> Now we add the first job as ‘<span class="iz ib" style="box-sizing: inherit; font-weight: 700;">build</span>’ to build the project run the tests in yml file.</p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="1db0" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">jobs:<br style="box-sizing: inherit;" /> build:<br style="box-sizing: inherit;" /> runs-on: ubuntu-latest<br style="box-sizing: inherit;" /> steps:<br style="box-sizing: inherit;" /> - uses: actions/checkout@v2<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> - name: Setup .NET Core<br style="box-sizing: inherit;" /> uses: actions/setup-dotnet@v1<br style="box-sizing: inherit;" /> with:<br style="box-sizing: inherit;" /> dotnet-version: 6.0.x</span><span class="gn kx ky ia kz b dm ld le lf lg lh lb l lc" data-selectable-paragraph="" id="e256" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"> - name: Run unit and integration tests<br style="box-sizing: inherit;" /> shell: bash<br style="box-sizing: inherit;" /> working-directory: ./src<br style="box-sizing: inherit;" /> run: dotnet test -c Release</span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="5bae" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="iz ib" style="box-sizing: inherit; font-weight: 700;">Step 6:</span> Now we add the ‘<span class="iz ib" style="box-sizing: inherit; font-weight: 700;">publish</span>’ job. As part of the publish job we will replace the tokens in the appsettings.production.json (or appsettings.json) if any.</p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="c809" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">publish:<br style="box-sizing: inherit;" /> runs-on: ubuntu-latest<br style="box-sizing: inherit;" /> needs: <span class="kz ib" style="box-sizing: inherit; font-weight: 700;">[build]</span><br style="box-sizing: inherit;" /> environment: <span class="kz ib" style="box-sizing: inherit; font-weight: 700;">test</span><br style="box-sizing: inherit;" /> steps:<br style="box-sizing: inherit;" /> - uses: actions/checkout@v2</span><span class="gn kx ky ia kz b dm ld le lf lg lh lb l lc" data-selectable-paragraph="" id="0447" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"> - name: Replace token for appsettings.Production.json<br style="box-sizing: inherit;" /> uses: cschleiden/replace-tokens@v1.1<br style="box-sizing: inherit;" /> with:<br style="box-sizing: inherit;" /> files: '["src/MyApp/appsettings.Production.json"]'<br style="box-sizing: inherit;" /> env:<br style="box-sizing: inherit;" /> ConnectionString: ${{ secrets.CONNECTIONSTRING }}</span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="e463" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">As per the above code, appsettings.production.json file as a token defined as “#{ConnectionString}#” which has to be replaced with the value stored in github environment’s (named ‘<span class="iz ib" style="box-sizing: inherit; font-weight: 700;">test</span>’ ) secret named ‘<span class="iz ib" style="box-sizing: inherit; font-weight: 700;">CONNECTIONSTRING</span>’. Also this job requires [<span class="iz ib" style="box-sizing: inherit; font-weight: 700;">build</span>] job ti run successfully.</p><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="4841" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="iz ib" style="box-sizing: inherit; font-weight: 700;">Step 7:</span> Next we will continue with publish job only and steps to connect to Azure Container Registry and then build & push the container.</p><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="9cf8" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">logging in to the acr with acr url, username & password stored in github environment secret.</p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="1039" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"> - name: Container Registry login<br style="box-sizing: inherit;" /> uses: docker/login-action@v1.10.0<br style="box-sizing: inherit;" /> with:<br style="box-sizing: inherit;" /> registry: ${{ secrets.containerRegistryUrl }}<br style="box-sizing: inherit;" /> username: ${{ secrets.containerUser }}<br style="box-sizing: inherit;" /> password: ${{ secrets.containerToken }}</span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="2920" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now build the container and push it to acr.</p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="4de1" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"> - name: Build and push container<br style="box-sizing: inherit;" /> uses: docker/build-push-action@v2<br style="box-sizing: inherit;" /> with:<br style="box-sizing: inherit;" /> push: true<br style="box-sizing: inherit;" /> tags: ${{ secrets.containerRegistryUrl }}/test/MyApp<br style="box-sizing: inherit;" /> context: ./src<br style="box-sizing: inherit;" /> file: src/MyApp/Dockerfile</span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="7285" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now we will write the container image tag to a file name ‘<span class="iz ib" style="box-sizing: inherit; font-weight: 700;">containerImageTag</span>’ so that we can read this later while pulling the image back.</p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="c7c2" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"> - name: Write container image tag to file<br style="box-sizing: inherit;" /> shell: bash<br style="box-sizing: inherit;" /> working-directory: src/MyApp<br style="box-sizing: inherit;" /> run: echo ${{ secrets.containerRegistry }}/test/MyApp > containerImageTag</span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="669e" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now we publish the artifact which has <span class="iz ib" style="box-sizing: inherit; font-weight: 700;">containerImageTag </span>file and other file requires like kubernetes related files which added in step 3.</p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="5450" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"> - name: Publish as an artifact<br style="box-sizing: inherit;" /> uses: actions/upload-artifact@v3<br style="box-sizing: inherit;" /> with:<br style="box-sizing: inherit;" /> name: myapp<br style="box-sizing: inherit;" /> path: |<br style="box-sizing: inherit;" /> k8s/deployment.yml<br style="box-sizing: inherit;" /> k8s/service.yml<br style="box-sizing: inherit;" /> k8s/ingress-appgateway.yml<br style="box-sizing: inherit;" /> src/MyApp/containerImageTag<br style="box-sizing: inherit;" /> if-no-files-found: error</span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="dbd0" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now till here we are done with the publish and next we need to pull the image from acr and deploy to the kubernete cluster.</p><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="643f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="iz ib" style="box-sizing: inherit; font-weight: 700;">Step 8:</span> Here we will create a new job name as ‘deploy’ which will require ‘publish’ job to be finished successfully.</p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="e3e5" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">deploy:<br style="box-sizing: inherit;" /> runs-on: ubuntu-latest<br style="box-sizing: inherit;" /> needs: [<span class="kz ib" style="box-sizing: inherit; font-weight: 700;">publish</span>]<br style="box-sizing: inherit;" /> environment: test<br style="box-sizing: inherit;" /> steps:<br style="box-sizing: inherit;" /> - uses: actions/checkout@v2</span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="3ca5" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">in ‘deploy’ job, first steps we add to download the artifact. Here the artifact name must match with the name provided in step 7 with publishing artifact steps.</p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="7e50" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"> - name: Downloading artifacts<br style="box-sizing: inherit;" /> uses: actions/download-artifact@v2<br style="box-sizing: inherit;" /> with:<br style="box-sizing: inherit;" /> name: <span class="kz ib" style="box-sizing: inherit; font-weight: 700;">myapp</span><br style="box-sizing: inherit;" /> path: <span class="kz ib" style="box-sizing: inherit; font-weight: 700;">myapp</span></span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="43ee" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">add next step, to extract the image tag from the file added in the artifact.</p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="c57d" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"> - name: Extracting the image tag<br style="box-sizing: inherit;" /> id: image-tag<br style="box-sizing: inherit;" /> shell: bash<br style="box-sizing: inherit;" /> working-directory: myapp<br style="box-sizing: inherit;" /> run: |<br style="box-sizing: inherit;" /> imageTag=$(cat src/test/containerImageTag)<br style="box-sizing: inherit;" /> echo "::set-output name=imageTag::$imageTag"<br style="box-sizing: inherit;" /> echo $imageTag</span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="f4ae" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">add next step, to install the kubectl so that we can run the kubernete related yml files and do the deployment.</p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="574f" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"> - name: kubectl setup<br style="box-sizing: inherit;" /> uses: azure/setup-kubectl@v1<br style="box-sizing: inherit;" /> id: install</span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="c521" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">next, we need to set the aks context where we would azure credentials which we generated in step 2 and stored in github environment secret along with resource group name and cluster name which again we will read it from github environment secret.</p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="140b" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"> - name: Setting aks context<br style="box-sizing: inherit;" /> uses: azure/aks-set-context@v1<br style="box-sizing: inherit;" /> with:<br style="box-sizing: inherit;" /> creds: '${{ <span class="kz ib" style="box-sizing: inherit; font-weight: 700;">secrets.azureCredentials </span>}}'<br style="box-sizing: inherit;" /> resource-group: ${{ <span class="kz ib" style="box-sizing: inherit; font-weight: 700;">secrets.resourceGroupName </span>}}<br style="box-sizing: inherit;" /> cluster-name: ${{ <span class="kz ib" style="box-sizing: inherit; font-weight: 700;">secrets.clusterName</span> }}</span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="9469" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now if you remember the deployment.yml file which we created in the step 3 has two tokens #{{CONTAINER_IMAGE}}# and #{{CONTAINER_REGISTRY_SECRET}}#, hence lets replace them.</p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="142d" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"> - name: replace tokens for kubernete manifest file<br style="box-sizing: inherit;" /> uses: cschleiden/replace-tokens@v1.1<br style="box-sizing: inherit;" /> with:<br style="box-sizing: inherit;" /> files: 'myapp/k8s/deployment.yml'<br style="box-sizing: inherit;" /> env:<br style="box-sizing: inherit;" /> CONTAINER_IMAGE: ${{ steps.image-tag.outputs.imageTag }}<br style="box-sizing: inherit;" /> ASPNETCORE_ENVIRONMENT: Production<br style="box-sizing: inherit;" /> CONTAINER_REGISTRY_SECRET: <span class="kz ib" style="box-sizing: inherit; font-weight: 700;">myapp-image-pull-secret</span></span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="cc60" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">From the above code, CONTAINER_REGISTRY_SECRET is a hardcoded string which you can name it any or defined it as environment input for your workflow and use it.</p><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="7d58" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now in the next step of the job ‘<span class="iz ib" style="box-sizing: inherit; font-weight: 700;">deploy</span>’ we will create the image pull secret which will be used to pull the image by the cluster to create pods and deploy image.</p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="1703" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"> - name: Set Image Pull Secret<br style="box-sizing: inherit;" /> uses: azure/k8s-create-secret@v1<br style="box-sizing: inherit;" /> id: create-secret<br style="box-sizing: inherit;" /> with:<br style="box-sizing: inherit;" /> namespace: ${{ secrets.kubernetesNamespace }}<br style="box-sizing: inherit;" /> container-registry-url: ${{ secrets.containerRegistryUrl }}<br style="box-sizing: inherit;" /> container-registry-username: ${{ secrets.containerUser }}<br style="box-sizing: inherit;" /> container-registry-password: ${{ secrets.containerPassword }}<br style="box-sizing: inherit;" /> secret-name: <span class="kz ib" style="box-sizing: inherit; font-weight: 700;">myapp-image-pull-secret</span></span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="3d6d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">and now the final steps of the deploy jobs is for deploying to the cluster.</p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="bc7e" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"> - name: Deploy to AKS<br style="box-sizing: inherit;" /> id: deploy-aks<br style="box-sizing: inherit;" /> uses: Azure/k8s-deploy@v4<br style="box-sizing: inherit;" /> with:<br style="box-sizing: inherit;" /> namespace: ${{ secrets.kubernetesNamespace }}<br style="box-sizing: inherit;" /> manifests: myapp/k8s/<br style="box-sizing: inherit;" /> imagepullsecrets: <span class="kz ib" style="box-sizing: inherit; font-weight: 700;">myapp-image-pull-secret</span></span></pre><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="2e52" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">and we are done. During the whole process you can get two issues, either azure access issue (which you have to resolve) or wrong file references from artifects(in my case myapp) i.e. manifest file not found or image tag file not found and in this case you can add the below steps here to see the folder structure of your artifact so that you can point the file correctly.</p><pre class="jw jx jy jz ge kv bs kw" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gn kx ky ia kz b dm la lb l lc" data-selectable-paragraph="" id="94a6" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"> - name: Display structure of downloaded files-Debug<br style="box-sizing: inherit;" /> shell: bash<br style="box-sizing: inherit;" /> run: ls -R<br style="box-sizing: inherit;" /> working-directory: ${{ inputs.artifactName }}</span></pre><blockquote class="lj lk ll" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="ix iy lm iz b ja jb jc jd je jf jg jh ln jj jk jl lo jn jo jp lp jr js jt ju ht gn" data-selectable-paragraph="" id="c864" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="iz ib" style="box-sizing: inherit; font-weight: 700;">Note</span>: use this steps only after you downloaded the artifact in deploy job.</p></blockquote><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="801d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now we are done. So if you run the public ip of your application gateway, you will see the application running.</p><blockquote class="lj lk ll" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="ix iy lm iz b ja jb jc jd je jf jg jh ln jj jk jl lo jn jo jp lp jr js jt ju ht gn" data-selectable-paragraph="" id="2264" style="box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="iz ib" style="box-sizing: inherit; font-weight: 700;">Note</span>: If you get any trouble like application is not available with public IP then check the following.<br style="box-sizing: inherit;" />1. Make sure Backend Pools are correctly configured and pointing to your cluster IP with 8080 port. It’s been configured automatically with kubernete deployment when manifest files are executed.<br style="box-sizing: inherit;" />2. Check the kubernete services, ingress and pods are running healthy either through the azure portal or kubectl commands.<br style="box-sizing: inherit;" />3. Check if your image is create healthy and appsettings files are correctly detokenzed. you may used docker extension in visual studio code to do all this or command prompt what you feel comfortable with.</p></blockquote><p class="pw-post-body-paragraph ix iy ia iz b ja jb jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju ht gn" data-selectable-paragraph="" id="7730" style="background-color: white; box-sizing: inherit; color: #292929; font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="iz ib" style="box-sizing: inherit; font-weight: 700;">Hope you enjoyed the content, follow me for more like this and please don’t forget to <span style="letter-spacing: -0.06px;">like/comment </span>for it. Happy programming.</span></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-88948928213006520082022-08-12T10:57:00.005+05:302022-10-27T12:02:58.847+05:30Could not load file or assembly 'System.Runtime, Version 6.0.0.0' with .Net Core<p> It’s the story of couple of days back, where as usual I deployed my application on Azure App Service after testing it locally and then I was surprised when the application was not running as expected.</p><p class="graf graf--p" name="79ce">Since everything works locally so there were no reason to believe of any error on cloud environment too so I just do a google search and found lot of links related to this error but unfortunately none of them related to the problem I had. So with couple of my cool collogues, I started trouble shooting on this issue, and this is what all I did until I was able to drill down to the root cause.</p><figure class="graf graf--figure" name="d53e"><img class="graf-image" data-height="63" data-image-id="1*JJqNKjX59ZoovxXpEYNPZw.png" data-width="815" src="https://cdn-images-1.medium.com/max/800/1*JJqNKjX59ZoovxXpEYNPZw.png" /></figure><ol class="postList"><li class="graf graf--li" name="81a9">Tried to get the actual cause by running the dll from Azure App Service => Console option, and it tells me the error as above screenshot. </li><li class="graf graf--li" name="de31">Deployment of the application to the Azure App Service was happening through CI/CD pipeline So I thought there could be something wrong going in there hence tried the deployment through visual studio to App Service and modified the appsettings.production.json through App Service => App Service Editor option (at the time of this article this feature is on Preview) manually.<br />And result, it works then what the hell is going wrong with CI/CD deployment, and still no clue.</li><li class="graf graf--li" name="28ae">Tried the application to local IIS deployment and it worked here too. Oh my God.</li><li class="graf graf--li" name="9a0e">After spending hours a random thought occurred, With the working application deployed in local IIS, I replaced the appsetting.Production.json file locally by copying it from Azure App Service => App Service Editor option (to use the one deployed to azure and created by CI/CD process).</li></ol><figure class="graf graf--figure" name="52d4"><img class="graf-image" data-height="617" data-image-id="1*Gl6yxQOOvLwaHuF1GFOi4g.png" data-width="1014" src="https://cdn-images-1.medium.com/max/800/1*Gl6yxQOOvLwaHuF1GFOi4g.png" /></figure><p class="graf graf--p" name="9a82">Finally here I got some relief as issue was reproducible with local env and familiar too. Hence started debugging and While debugging I found that the issue was with below code throwing exception due the keyVaultUrl value is set to <strong class="markup--strong markup--p-strong">Empty character</strong>.</p><pre class="graf graf--pre" name="d685">builder.Configuration.AddAzureKeyVault(<br /> new Uri(<strong class="markup--strong markup--pre-strong">keyVaultUrl</strong>),<br /> new DefaultAzureCredential(new DefaultAzureCredentialOptions<br /> {<br /> ...<br /> }),<br /> new PrefixKeyVaultSecretManager(prefix));</pre><p class="graf graf--p" name="74d9">So what was happening here is, In production, application was not using Azure Key Vault but the code was there and tried to build the configuration with AzureKeyValut and ending up throwing exception while starting the application.</p><p class="graf graf--p" name="3c80">CI/CD was creating the appSettings.Production.json and in this process it was replacing the keyvalut related setting to <strong class="markup--strong markup--p-strong">“ “</strong> an empty character and this was the culprit.</p><p class="graf graf--p" name="c1a9">Before I found this issue, it was looking huge but after I found it, I felt like Ahk!what the hell.</p><p class="graf graf--p" name="da72">So if you ever encountered such error with production, My first recommendation would be to run the application locally with the same configuration and appsettings.json or web.config used in deployment/production and save your time. Sometime google also won’t be able to help you unless some people like me share his/her crazy experiences like this.</p><p class="graf graf--p" name="f10d">I too had no plan to share this :) until I got the below feedback from one of my reader for similar crazy issue related to docker networking.</p><figure class="graf graf--figure" name="29d8"><img class="graf-image" data-height="245" data-image-id="1*LthQYZvi0on1QVa0ySAIxQ.png" data-width="414" src="https://cdn-images-1.medium.com/max/800/1*LthQYZvi0on1QVa0ySAIxQ.png" /></figure><p class="graf graf--p" name="181f">Thank You All for such a beautiful feedback which turns as fuel for people like me to share more and more even it seems to be silly sometime.</p><p class="graf graf--p" name="ee47"><strong class="markup--strong markup--p-strong">Hope you enjoyed the content, follow me for more like this and please don’t forget to like/comment for it. Happy programming.</strong></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-17179315807082008652022-08-03T20:17:00.002+05:302022-10-27T12:03:15.965+05:30CI/CD with GitHub Actions to deploy Application to Azure App Service<p> <span style="background-color: white; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">This is a follow up article of my previous article published here as</span><span style="background-color: white; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;"> </span><a class="au kc" href="https://binodmahto.blogspot.com/2022/08/cicd-with-github-actions.html" rel="noopener" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">CI/CD with GitHub Actions</a><span style="background-color: white; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">. There I was talking about basics of creating a GitHub action to automate project build and run tests.</span></p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="62d9" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In this article, I’ll be demonstrating a complete CI/CD to deploy a .net core web api project to Azure App Service.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="86db" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Before jumping on creating a GitHub action to do so, first create a Azure App Service manually (as this is not part of this demonstration) with required configuration as per your .net project need.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="e5d4" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Once Azure App Service has been created follow the below steps.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="ed78" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Step 1:</span> Go to your Azure App Service Overview tab and download the publish profile from ‘Get publish profile’ option.</p><figure class="ke kf kg kh fz ki fn fo paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="kj kk dp kl cf km" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 692px; z-index: auto;" tabindex="0"><div class="fn fo kd" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1882px;"><img alt="" class="cf kn ko" height="57" loading="lazy" role="presentation" src="https://miro.medium.com/max/1400/1*-bQyFNqqFWLPM-luOHPSJQ.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 692px;" width="700" /></div></div></figure><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="bcf6" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Step 2:</span> Go to you GitHub project repo <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Settings </span>tab and create a Action Secrets named as ‘AZURE_WEBAPP_PUBLISH_PROFILE’ and copy paste the entire content of downloaded publish profile file from Azure App Service in the value field.</p><figure class="ke kf kg kh fz ki fn fo paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="kj kk dp kl cf km" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 692px; z-index: auto;" tabindex="0"><div class="fn fo kp" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 916px;"><img alt="" class="cf kn ko" height="522" loading="lazy" role="presentation" src="https://miro.medium.com/max/1400/1*49ZDmKdugn2ZoqfTHRRtjQ.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 692px;" width="700" /></div></div></figure><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="0005" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Step 3:</span> Go back to your Azure App Service Configuration section and add a new Application Settings as</p><figure class="ke kf kg kh fz ki fn fo paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="kj kk dp kl cf km" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 692px; z-index: auto;" tabindex="0"><div class="fn fo kq" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1301px;"><img alt="" class="cf kn ko" height="298" loading="lazy" role="presentation" src="https://miro.medium.com/max/1400/1*lnjxNElod8zwtNp8UrPc0w.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 692px;" width="700" /></div></div></figure><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="fc93" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">This is to tell the App Service to use appsettings.production.json from the build for app settings.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="f45d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Step 4:</span> From previous steps it is clear that, we will be using the appsettings.production.json file which contains the settings required for application.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="3d9e" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">As part of security and good practice, DO NOT hardcode the sensitive data in appsetting.production.json and instead use the tokenized string which will be replaced with correct value from the GitHub CI/CD process. i.e. connection string in appsetting file as:</p><pre class="ke kf kg kh fz kr bt ks" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gi kt ku ih kv b dn kw kx l ky" data-selectable-paragraph="" id="c4f0" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">"ConnectionStrings": {<br style="box-sizing: inherit;" /> "ConnectionString": "#{ConnectionString}#",<br style="box-sizing: inherit;" /> },</span></pre><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="d33d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Step 5:</span> Go to your project GitHub repository’s setting tab and create an Environment against which we will define our secrets like connectionString for prod environment.</p><figure class="ke kf kg kh fz ki fn fo paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="kj kk dp kl cf km" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 692px; z-index: auto;" tabindex="0"><div class="fn fo kz" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1329px;"><img alt="" class="cf kn ko" height="341" loading="lazy" role="presentation" src="https://miro.medium.com/max/1400/1*qzfMRA2SyrVxyn6v0Uvh7w.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 692px;" width="700" /></div></div></figure><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="2ecd" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Step 6:</span> Go inside the create Environment and add secrets with name as “CONNETION_STRING” and in the value field, paste the connection string value required by your application.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="c442" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Step 7: </span>Create your .yml file and define the environment:Production to fetch secrets from prod environment (created in above step) and add a steps to detokenize your appsettings.production.json to replace connection string from secrets.</p><blockquote class="la lb lc" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="je jf ld jg b jh ji jj jk jl jm jn jo le jq jr js lf ju jv jw lg jy jz ka kb ia gi" data-selectable-paragraph="" id="c610" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Note</span>: Please follow my previous article if are new to GitHub Actions.</p></blockquote><pre class="ke kf kg kh fz kr bt ks" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gi kt ku ih kv b dn kw kx l ky" data-selectable-paragraph="" id="1015" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">jobs:<br style="box-sizing: inherit;" /> build:<br style="box-sizing: inherit;" /> runs-on: windows-latest<br style="box-sizing: inherit;" /> environment: Production</span><span class="gi kt ku ih kv b dn lh li lj lk ll kx l ky" data-selectable-paragraph="" id="262c" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">steps:<br style="box-sizing: inherit;" /> - uses: actions/checkout@v2<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> - name: Replace token for appsettings.Production.json<br style="box-sizing: inherit;" /> uses: cschleiden/replace-tokens@v1.1<br style="box-sizing: inherit;" /> with:<br style="box-sizing: inherit;" /> tokenPrefix: '#{'<br style="box-sizing: inherit;" /> tokenSuffix: '}#'<br style="box-sizing: inherit;" /> files: '["src/DemoAPI/appsettings.Production.json"]'<br style="box-sizing: inherit;" /> env:<br style="box-sizing: inherit;" /> <span class="kv ii" style="box-sizing: inherit; font-weight: 700;">ConnectionString</span>: ${{secrets.CONNECTION_STRING}}</span></pre><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="717b" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Make sure, you use the name of the token (left part) as part of env exactly as it is defined your appsetting.production.json. i.e. in my case it is #{<span class="jg ii" style="box-sizing: inherit; font-weight: 700;">ConnectionString</span>}#, and value part (right side) will read the secrets using the key as defined, in my case it is CONNECTION_STRING.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="44a6" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Step 8:</span> Now we will define steps to setup .net core, build project, publish project and finally upload artifacts for deployment as:</p><pre class="ke kf kg kh fz kr bt ks" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gi kt ku ih kv b dn kw kx l ky" data-selectable-paragraph="" id="b4a6" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"> - name: Set up .NET Core<br style="box-sizing: inherit;" /> uses: actions/setup-dotnet@v1<br style="box-sizing: inherit;" /> with:<br style="box-sizing: inherit;" /> dotnet-version: ${{ env.DOTNET_VERSION }}<br style="box-sizing: inherit;" /> #include-prerelease: true<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> - name: Build projects<br style="box-sizing: inherit;" /> run: |<br style="box-sizing: inherit;" /> dotnet build src/DemoAPI/DemoAPI.sln --configuration Release<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> - name: Publish Project<br style="box-sizing: inherit;" /> run: |<br style="box-sizing: inherit;" /> dotnet publish src/DemoAPI/DemoAPI.csproj -c Release -o ${{env.DOTNET_ROOT}}/myapp</span><span class="gi kt ku ih kv b dn lh li lj lk ll kx l ky" data-selectable-paragraph="" id="f11b" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"> - name: Upload artifact for deployment job<br style="box-sizing: inherit;" /> uses: actions/upload-artifact@v2<br style="box-sizing: inherit;" /> with:<br style="box-sizing: inherit;" /> name: <span class="kv ii" style="box-sizing: inherit; font-weight: 700;">.net-app</span><br style="box-sizing: inherit;" /> path: ./myapp</span></pre><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="4642" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">With these steps, our artifact (deployment packaged in zip format) is uploaded to github cloud server used in this build pipeline under ROOT/myapp folder.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="9c9d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Step 9:</span> Add the next job to deploy the package to Azure App Service as:</p><pre class="ke kf kg kh fz kr bt ks" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gi kt ku ih kv b dn kw kx l ky" data-selectable-paragraph="" id="3d43" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">deploy:<br style="box-sizing: inherit;" /> runs-on: windows-latest<br style="box-sizing: inherit;" /> needs: build<br style="box-sizing: inherit;" /> environment:<br style="box-sizing: inherit;" /> name: 'production'<br style="box-sizing: inherit;" /> url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}</span><span class="gi kt ku ih kv b dn lh li lj lk ll kx l ky" data-selectable-paragraph="" id="cd69" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"> steps:<br style="box-sizing: inherit;" /> - name: Download artifact from build job<br style="box-sizing: inherit;" /> uses: actions/download-artifact@v3<br style="box-sizing: inherit;" /> with:<br style="box-sizing: inherit;" /> name: <span class="kv ii" style="box-sizing: inherit; font-weight: 700;">.net-app</span><br style="box-sizing: inherit;" /> path: <span class="kv ii" style="box-sizing: inherit; font-weight: 700;">upload_artifact</span></span><span class="gi kt ku ih kv b dn lh li lj lk ll kx l ky" data-selectable-paragraph="" id="cba4" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"> - name: Deploy to Azure Web App<br style="box-sizing: inherit;" /> id: deploy-to-webapp<br style="box-sizing: inherit;" /> uses: azure/webapps-deploy@v2<br style="box-sizing: inherit;" /> with:<br style="box-sizing: inherit;" /> app-name: 'DemoAPI'<br style="box-sizing: inherit;" /> slot-name: 'production'<br style="box-sizing: inherit;" /> publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}<br style="box-sizing: inherit;" /> package: <span class="kv ii" style="box-sizing: inherit; font-weight: 700;">upload_artifact</span></span></pre><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="3307" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">As part of deploy job, the first step is for downloading the artifact and key thing to take care of is, the <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">name: .net-app</span> should be exactly same as you defined the name while uploading artifact steps from build job.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="3562" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">and the second step is for, deploying the app to Azure App Service (we created) and the key things to notice here are the <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">package </span>name, should be exactly same as you define as part of <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">path </span>in previous step, and second thing is <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">publish-profile</span> value reading correct secrets to connect to Azure App Service (which is downloaded publish profile details).</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="91c9" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">And we are done.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="1ef0" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Hope you enjoyed the content, follow me for more like this and please don’t forget to <span style="font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; letter-spacing: -0.06px;">like/comment </span>for it. Happy programming.</span></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-16641203189743459402022-08-03T19:12:00.005+05:302022-10-27T12:03:30.390+05:30CI/CD with GitHub Actions<p> <span style="background-color: white; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">If you are working with GitHub Actions, you might too get confused with the term Workflow vs Actions. Here I’m gonna explain the difference as well as also giving you example to create your first CI/CD, even if you have never done it before.</span></p><h2 class="kc kd ih bn ke kf kg kh ki kj kk kl km jp kn ko kp jt kq kr ks jx kt ku kv kw gi" data-selectable-paragraph="" id="9fe5" style="background-color: white; box-sizing: inherit; color: #292929; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 20px; line-height: 24px; margin: 2.37em 0px -0.31em;">GitHub Actions</h2><p class="pw-post-body-paragraph je jf ih jg b jh kx jj jk jl ky jn jo jp kz jr js jt la jv jw jx lb jz ka kb ia gi" data-selectable-paragraph="" id="3ddc" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 0.86em 0px -0.46em; word-break: break-word;">In Github, <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Actions </span><em class="lc" style="box-sizing: inherit;">is the entire platform which automate the build, test and deployment pipeline.</em> That means in GitHub, we create an Actions to automate our CI/CD pipeline.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="045e" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">The GitHub Actions consists several components as:</p><ol style="background-color: white; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; list-style: none none; margin: 0px; padding: 0px;"><li class="ld le ih jg b jh ji jl jm jp lf jt lg jx lh kb li lj lk ll gi" data-selectable-paragraph="" id="ac77" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 2.14em; padding-left: 0px;">Events</li><li class="ld le ih jg b jh lm jl ln jp lo jt lp jx lq kb li lj lk ll gi" data-selectable-paragraph="" id="e538" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">Workflows</li><li class="ld le ih jg b jh lm jl ln jp lo jt lp jx lq kb li lj lk ll gi" data-selectable-paragraph="" id="1c85" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">Jobs</li><li class="ld le ih jg b jh lm jl ln jp lo jt lp jx lq kb li lj lk ll gi" data-selectable-paragraph="" id="60b7" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">Actions</li><li class="ld le ih jg b jh lm jl ln jp lo jt lp jx lq kb li lj lk ll gi" data-selectable-paragraph="" id="5838" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">Runners</li></ol><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="384e" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Actions is the component of GitHub Actions, aah this is confusing. Also if you notice in the github UI, you will see as:</p><figure class="ls lt lu lv fz lw fn fo paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="lx ly dp lz cf ma" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 692px; z-index: auto;" tabindex="0"><div class="fn fo lr" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 897px;"><img alt="" class="cf mb mc" height="212" loading="lazy" role="presentation" src="https://miro.medium.com/max/1400/1*OKAwvv_4leLL0dMyxnUJ1w.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 692px;" width="700" /></div></div></figure><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="1257" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Here with the help of a simple GitHub Action which will just build the project and run Tests, we will discuss about above mentioned components and also clear the confusions/doubts too which arises due to naming as we talked.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="cac1" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Our requirement is: Create a GitHub action to build the project and run the test and will call it “Build and Test workflow”. Workflow, because GitHub calls it as workflows which is a GitHub action consisting all components as we defined above.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="c964" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;"><em class="lc" style="box-sizing: inherit;">Since all our GitHub actions are shown under workflows in UI, lets convince our mind to call the action as ‘workflow action’ to avoid confusion </em></span><em class="lc" style="box-sizing: inherit;">(fair enough)</em><span class="jg ii" style="box-sizing: inherit; font-weight: 700;"><em class="lc" style="box-sizing: inherit;"> </em></span>and to do this add a folder named as <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">.github/workflows</span> in your project repository and follow the steps:</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="84b6" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Step 1:</span> Create a .yml/.yaml file in .github/workflows folder and name it as build-and-run-tests.yml.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="82c0" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">.github/workflows/build-and-run-tests.yml</span></p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="1a21" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Step 2</span>: Create the <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">workflow</span>.</p><blockquote class="md me mf" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="je jf lc jg b jh ji jj jk jl jm jn jo mg jq jr js mh ju jv jw mi jy jz ka kb ia gi" data-selectable-paragraph="" id="1810" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Workflow </span>is all the tasks which has to be performed when the event (in our case, push event on the branch repo) occurs.</p></blockquote><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="1306" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In other words these are the pipelines which performs the task like build (build pipeline), Tests (test run pipeline).</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="a66f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">As workflow syntax concerns, it consists of <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">name </span>(name of the workflow), <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">on </span>(event for workflow to trigger) and <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">jobs </span>(tasks to perform).</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="b365" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">For the first, here we create the .yml or .yaml (no other extension is recognized/allowed) and name the workflow.</p><pre class="ls lt lu lv fz mj bt mk" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gi kc kd ih ml b dn mm mn l mo" data-selectable-paragraph="" id="481e" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><span class="ml ii" style="box-sizing: inherit; font-weight: 700;">name</span>: Build and Run tests</span><span class="gi kc kd ih ml b dn mp mq mr ms mt mn l mo" data-selectable-paragraph="" id="5896" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">#define variables<br style="box-sizing: inherit;" />env:<br style="box-sizing: inherit;" /> DOTNET_VERSION:'6.0.x'</span></pre><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="5849" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In this file we name the workflow action as ‘Build and Run tests’ and added a variable available to this .yml file only.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="6087" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Step3:</span> Create an <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Event </span>.</p><blockquote class="md me mf" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="je jf lc jg b jh ji jj jk jl jm jn jo mg jq jr js mh ju jv jw mi jy jz ka kb ia gi" data-selectable-paragraph="" id="0481" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">An <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Event </span>is something that happens in a GitHub repository. i.e. Push, Create, delete, deployment, fork, pull_request, workflow_dispatch etc.</p></blockquote><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="5903" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">This is our first component of GitHub action workflow.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="ff23" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">So now we define the ‘<span class="jg ii" style="box-sizing: inherit; font-weight: 700;">on’ </span>part of the workflow which will trigger the workflow whenever there is push to our GitHub repo:</p><pre class="ls lt lu lv fz mj bt mk" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gi kc kd ih ml b dn mm mn l mo" data-selectable-paragraph="" id="6152" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">name: Build and Run tests</span><span class="gi kc kd ih ml b dn mp mq mr ms mt mn l mo" data-selectable-paragraph="" id="7b86" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">#define variables<br style="box-sizing: inherit;" />env:<br style="box-sizing: inherit;" /> DOTNET_VERSION:'6.0.x'</span><span class="gi kc kd ih ml b dn mp mq mr ms mt mn l mo" data-selectable-paragraph="" id="4a88" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><span class="ml ii" style="box-sizing: inherit; font-weight: 700;">on</span>:<br style="box-sizing: inherit;" /> push:<br style="box-sizing: inherit;" /> branches:<br style="box-sizing: inherit;" /> - master<br style="box-sizing: inherit;" /> workflow_dispatch:</span></pre><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="0e70" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Here we say, whenever <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Push </span>event occurs on <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">master </span>branch trigger the action workflow. I also used the action <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">workflow_dispatch </span>which allows user also to manually trigger the workflow action.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="41cc" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Step 4</span>: Create <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Jobs </span>to perform tasks.</p><blockquote class="md me mf" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="je jf lc jg b jh ji jj jk jl jm jn jo mg jq jr js mh ju jv jw mi jy jz ka kb ia gi" data-selectable-paragraph="" id="2903" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">A <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Job </span>is a series of steps inside the workflow which are executed. Each step is either a script to be executed or an action that would run.</p></blockquote><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi mu" data-selectable-paragraph="" id="8a6f" style="background-color: white; box-sizing: inherit; clear: left; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="l mv mw mx my mz na nb nc nd dp" style="box-sizing: inherit; display: block; float: left; font-size: 66px; line-height: 0.83; margin-right: 12px; padding-top: 7px; position: relative;">N</span><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">ote</span>: Steps are executed exactly in the order they are defined and dependent on the previous step being complete. So if previous step fails and the next step will not be executed.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="2c8f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">So as per our requirement, we will create a job, to build and run tests.</p><pre class="ls lt lu lv fz mj bt mk" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gi kc kd ih ml b dn mm mn l mo" data-selectable-paragraph="" id="01be" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">name: Build and Run tests</span><span class="gi kc kd ih ml b dn mp mq mr ms mt mn l mo" data-selectable-paragraph="" id="b813" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">#define variables<br style="box-sizing: inherit;" />env:<br style="box-sizing: inherit;" /> DOTNET_VERSION:'6.0.x'</span><span class="gi kc kd ih ml b dn mp mq mr ms mt mn l mo" data-selectable-paragraph="" id="7343" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">on:<br style="box-sizing: inherit;" /> push:<br style="box-sizing: inherit;" /> branches:<br style="box-sizing: inherit;" /> - master<br style="box-sizing: inherit;" /> workflow_dispatch:</span><span class="gi kc kd ih ml b dn mp mq mr ms mt mn l mo" data-selectable-paragraph="" id="ebc4" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">jobs:<br style="box-sizing: inherit;" /> build:<br style="box-sizing: inherit;" /> environment: Test</span></pre><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="2ad8" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">in above code, we created a job called <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">build </span>pipeline and defining the environment as ‘Test’ to use to look for secrets if I uses within the pipeline as ${{secrtes.MySecrets1}}, this you can can define from <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">settings </span>tab.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="15c1" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Separating secrets with environment is useful when you have multiple jobs for dev, test and production etc within a single workflow action.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="cd52" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Step 5:</span> Define the <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Runners</span>.</p><blockquote class="md me mf" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="je jf lc jg b jh ji jj jk jl jm jn jo mg jq jr js mh ju jv jw mi jy jz ka kb ia gi" data-selectable-paragraph="" id="7a28" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">The <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Runners </span>are the process on the server that runs the workflow. Runners are hosted in the cloud and we specify the name of the runner for job using <span class="jg ii" style="box-sizing: inherit; font-weight: 700;">runs-on </span>syntax.</p></blockquote><pre class="ls lt lu lv fz mj bt mk" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gi kc kd ih ml b dn mm mn l mo" data-selectable-paragraph="" id="436b" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">name: Build and Run tests</span><span class="gi kc kd ih ml b dn mp mq mr ms mt mn l mo" data-selectable-paragraph="" id="ae47" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">#define variables<br style="box-sizing: inherit;" />env:<br style="box-sizing: inherit;" /> DOTNET_VERSION:'6.0.x'</span><span class="gi kc kd ih ml b dn mp mq mr ms mt mn l mo" data-selectable-paragraph="" id="83cc" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">on:<br style="box-sizing: inherit;" /> push:<br style="box-sizing: inherit;" /> branches:<br style="box-sizing: inherit;" /> - master<br style="box-sizing: inherit;" /> workflow_dispatch:</span><span class="gi kc kd ih ml b dn mp mq mr ms mt mn l mo" data-selectable-paragraph="" id="4c9a" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">jobs:<br style="box-sizing: inherit;" /> build:<br style="box-sizing: inherit;" /> <span class="ml ii" style="box-sizing: inherit; font-weight: 700;"> runs-on: windows-latest</span><br style="box-sizing: inherit;" /> environment: Production</span></pre><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="0c89" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Every job can have only one runners and in our case we specified as ‘windows-latest’ and the rest will be taken care by GitHub engine.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="a735" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">By now, theoretically our workflow action is ready doing nothing. So lets add the step to build the project and run the test as steps of the job ‘<span class="jg ii" style="box-sizing: inherit; font-weight: 700;">build</span>’ as per our example requirement.</p><pre class="ls lt lu lv fz mj bt mk" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gi kc kd ih ml b dn mm mn l mo" data-selectable-paragraph="" id="b012" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">name: Build and Run tests</span><span class="gi kc kd ih ml b dn mp mq mr ms mt mn l mo" data-selectable-paragraph="" id="bc65" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">#define variables<br style="box-sizing: inherit;" />env:<br style="box-sizing: inherit;" /> DOTNET_VERSION:'6.0.x'</span><span class="gi kc kd ih ml b dn mp mq mr ms mt mn l mo" data-selectable-paragraph="" id="04c3" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">on:<br style="box-sizing: inherit;" /> push:<br style="box-sizing: inherit;" /> branches:<br style="box-sizing: inherit;" /> - master<br style="box-sizing: inherit;" /> workflow_dispatch:</span><span class="gi kc kd ih ml b dn mp mq mr ms mt mn l mo" data-selectable-paragraph="" id="d20c" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">jobs:<br style="box-sizing: inherit;" /> build:<br style="box-sizing: inherit;" /> runs-on: windows-latest<br style="box-sizing: inherit;" /> environment: Production</span><span class="gi kc kd ih ml b dn mp mq mr ms mt mn l mo" data-selectable-paragraph="" id="f5f1" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"> steps:<br style="box-sizing: inherit;" /> - uses: actions/checkout@v2</span><span class="gi kc kd ih ml b dn mp mq mr ms mt mn l mo" data-selectable-paragraph="" id="0f96" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"> - name: Set up .NET Core <br style="box-sizing: inherit;" /> uses: actions/setup-dotnet@v1 <br style="box-sizing: inherit;" /> with: <br style="box-sizing: inherit;" /> dotnet-version: ${{ env.DOTNET_VERSION }} </span><span class="gi kc kd ih ml b dn mp mq mr ms mt mn l mo" data-selectable-paragraph="" id="7a90" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"> - name: Build projects<br style="box-sizing: inherit;" /> run: |<br style="box-sizing: inherit;" /> dotnet build --configuration Release</span><span class="gi kc kd ih ml b dn mp mq mr ms mt mn l mo" data-selectable-paragraph="" id="d697" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"> - name: Test with the dotnet CLI<br style="box-sizing: inherit;" /> run: dotnet test</span></pre><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="57b1" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In above code, we have added 4 steps, out of which 1st step is for checkout the git repository and the other steps are as their name says.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi mu" data-selectable-paragraph="" id="1ffe" style="background-color: white; box-sizing: inherit; clear: left; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="l mv mw mx my mz na nb nc nd dp" style="box-sizing: inherit; display: block; float: left; font-size: 66px; line-height: 0.83; margin-right: 12px; padding-top: 7px; position: relative;">N</span><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">ote</span>: Based on your project structure you may have to define path of the .csproj/.sln in your repo for dotnet build and test command to run.</p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="3d3f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">If I need to picturize the whole things, the way it works as:</p><figure class="ls lt lu lv fz lw fn fo paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="lx ly dp lz cf ma" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 692px; z-index: auto;" tabindex="0"><div class="fn fo ne" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 879px;"><img alt="" class="cf mb mc" height="399" loading="lazy" role="presentation" src="https://miro.medium.com/max/1400/1*0jqre1K9JxHzHdo1nAFnKg.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 692px;" width="700" /></div></div></figure><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="45e4" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;">Hope you enjoyed the content, follow me for more like this and please don’t forget to <span style="font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; letter-spacing: -0.06px;">like/comment </span>for it. Happy programming.</span></p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="45e4" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;"><br /></span></p><p class="graf graf--p" name="ac22"><strong class="markup--strong markup--p-strong">Bonus</strong></p><p class="pw-post-body-paragraph je jf ih jg b jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb ia gi" data-selectable-paragraph="" id="45e4" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jg ii" style="box-sizing: inherit; font-weight: 700;"></span></p><p class="graf graf--p" name="7ef5">Follow me here for my next article on <a class="markup--anchor markup--p-anchor" data-href="https://binodmahto.medium.com/ci-cd-with-github-actions-to-deploy-application-to-azure-app-service-16e3005bffc0" href="https://binodmahto.blogspot.com/2022/08/cicd-with-github-actions-to-deploy.html" rel="noopener" target="_blank">CI/CD with GitHub Actions to deploy Application to Azure App Service</a></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-17369936759466939682022-07-12T13:30:00.008+05:302022-10-27T12:03:47.336+05:30Event Bus implementation in Vue<script async="" crossorigin="anonymous" src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-8393865349374200"></script>
<p> <span style="background-color: white; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">In any application data sharing among various components/services are key to maintain data flow. In vue, different data sharing methods are:</span></p><ol style="background-color: white; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; list-style: none none; margin: 0px; padding: 0px;"><li class="kd ke ii jh b ji jj jm jn jq kf ju kg jy kh kc ki kj kk kl gj" data-selectable-paragraph="" id="bc59" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 2.14em; padding-left: 0px;">Props: Allow to pass data from parent to child component.</li><li class="kd ke ii jh b ji km jm kn jq ko ju kp jy kq kc ki kj kk kl gj" data-selectable-paragraph="" id="df2b" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">Emit: Allow to pass data from child to parent component.</li><li class="kd ke ii jh b ji km jm kn jq ko ju kp jy kq kc ki kj kk kl gj" data-selectable-paragraph="" id="cf55" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;">Vuex Store: Allow to share data across components.</li></ol><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="c691" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Apart from above three, there is an another technique to share data across the components is, Event Bus which works on pub-sub model.</p><blockquote class="kr ks kt" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="jf jg ku jh b ji jj jk jl jm jn jo jp kv jr js jt kw jv jw jx kx jz ka kb kc ib gj" data-selectable-paragraph="" id="8795" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Event Bus</span> technique in vue, emits an event from one components (publisher) and other components (subscribers) will listen to the event in real time and act.</p></blockquote><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="b03f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">The event bus implementation in vue is a global instance like vuex store. Lets see this by an example on How to implement it.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="bda9" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In this example I’m using <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Vue@2.7.0</span> and <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">mitt@2.1.0. mitt. </span>mitt is a javascript library helps to achieve event bus implementation.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="f90d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Implementation</span></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="49dd" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 1:</span> First we will be creating a vuejs application and then create an global instance of event bus using mitt. In my case I created a folder named ‘eventbus’ and add the index.ts file.<br style="box-sizing: inherit;" />eventbus => <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">index.ts</span></p><pre class="ky kz la lb ga lc bt ld" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj le lf ii lg b do lh li l lj" data-selectable-paragraph="" id="39e0" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><span class="lg ij" style="box-sizing: inherit; font-weight: 700;">import mitt from 'mitt';<br style="box-sizing: inherit;" />export default mitt();</span></span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="2381" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 2:</span> Now adds three different components, where first component will emit (publish) an event to pass the message and other two components will listen the event and display the message.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="13f5" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">components => <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">HelloMessagePublish.vue</span></p><pre class="ky kz la lb ga lc bt ld" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj le lf ii lg b do lh li l lj" data-selectable-paragraph="" id="242c" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><template><br style="box-sizing: inherit;" /> <div class="hello"><br style="box-sizing: inherit;" /> <span class="lg ij" style="box-sizing: inherit; font-weight: 700;"> <input v-model="message" /><br style="box-sizing: inherit;" /> <button </span><a class="au lk" href="http://twitter.com/click" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank"><span class="lg ij" style="box-sizing: inherit; font-weight: 700;">@click</span></a><span class="lg ij" style="box-sizing: inherit; font-weight: 700;">="onPublish">publish</button></span><br style="box-sizing: inherit;" /> </div><br style="box-sizing: inherit;" /></template></span><span class="gj le lf ii lg b do ll lm ln lo lp li l lj" data-selectable-paragraph="" id="5daa" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><script><br style="box-sizing: inherit;" /><span class="lg ij" style="box-sizing: inherit; font-weight: 700;">import eventbus from "@/eventbus";</span></span><span class="gj le lf ii lg b do ll lm ln lo lp li l lj" data-selectable-paragraph="" id="ecca" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default {<br style="box-sizing: inherit;" /> name: "HelloMessagePublish",<br style="box-sizing: inherit;" /> data() {<br style="box-sizing: inherit;" /> return {<br style="box-sizing: inherit;" /> message: "",<br style="box-sizing: inherit;" /> };<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> methods: {<br style="box-sizing: inherit;" /> <span class="lg ij" style="box-sizing: inherit; font-weight: 700;">onPublish()</span> {<br style="box-sizing: inherit;" /> <span class="lg ij" style="box-sizing: inherit; font-weight: 700;">eventbus.<em class="ku" style="box-sizing: inherit;">emit</em>("getMessage", this.$data.message);</span><br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" />};<br style="box-sizing: inherit;" /></script></span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="fcd9" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Above component has a input control to accept the user input and publish this message through emitting an event ‘<span class="jh ij" style="box-sizing: inherit; font-weight: 700;">getMessage’ </span>on click of publish button here.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="9524" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">components => <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">HelloMessageDisplay.vue</span></p><pre class="ky kz la lb ga lc bt ld" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj le lf ii lg b do lh li l lj" data-selectable-paragraph="" id="fccd" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><template><br style="box-sizing: inherit;" /> <div class="hello"><br style="box-sizing: inherit;" /> <span class="lg ij" style="box-sizing: inherit; font-weight: 700;"><h1>{{ msg }}</h1></span><br style="box-sizing: inherit;" /> </div><br style="box-sizing: inherit;" /></template></span><span class="gj le lf ii lg b do ll lm ln lo lp li l lj" data-selectable-paragraph="" id="b04c" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><script><br style="box-sizing: inherit;" /><span class="lg ij" style="box-sizing: inherit; font-weight: 700;">import eventbus from "@/eventbus";</span></span><span class="gj le lf ii lg b do ll lm ln lo lp li l lj" data-selectable-paragraph="" id="711e" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default {<br style="box-sizing: inherit;" /> name: "HelloMessageDisplay",<br style="box-sizing: inherit;" /> data() {<br style="box-sizing: inherit;" /> return {<br style="box-sizing: inherit;" /> <span class="lg ij" style="box-sizing: inherit; font-weight: 700;">msg</span>: "",<br style="box-sizing: inherit;" /> };<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> mounted() {<br style="box-sizing: inherit;" /> <span class="lg ij" style="box-sizing: inherit; font-weight: 700;"> eventbus.<em class="ku" style="box-sizing: inherit;">on</em>("getMessage", (e) => {<br style="box-sizing: inherit;" /> this.$data.msg = e;<br style="box-sizing: inherit;" /> });</span><br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" />};<br style="box-sizing: inherit;" /></script></span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="b489" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In above component here, component is subscribing the event name ‘getMessage’ inside the mounted hook.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="b5c7" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">similarly will add the third component which is duplicate of above for example purpose only.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="8998" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">components => <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">HelloMessageDisplay2.vue</span></p><pre class="ky kz la lb ga lc bt ld" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj le lf ii lg b do lh li l lj" data-selectable-paragraph="" id="8aef" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><template><br style="box-sizing: inherit;" /> <div class="hello"><br style="box-sizing: inherit;" /> <span class="lg ij" style="box-sizing: inherit; font-weight: 700;"><h1>{{ msg }}</h1></span><br style="box-sizing: inherit;" /> </div><br style="box-sizing: inherit;" /></template></span><span class="gj le lf ii lg b do ll lm ln lo lp li l lj" data-selectable-paragraph="" id="a954" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><script><br style="box-sizing: inherit;" /><span class="lg ij" style="box-sizing: inherit; font-weight: 700;">import eventbus from "@/eventbus";</span></span><span class="gj le lf ii lg b do ll lm ln lo lp li l lj" data-selectable-paragraph="" id="196a" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default {<br style="box-sizing: inherit;" /> name: "HelloMessageDisplay2",<br style="box-sizing: inherit;" /> data() {<br style="box-sizing: inherit;" /> return {<br style="box-sizing: inherit;" /> <span class="lg ij" style="box-sizing: inherit; font-weight: 700;">msg</span>: "",<br style="box-sizing: inherit;" /> };<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> mounted() {<br style="box-sizing: inherit;" /> <span class="lg ij" style="box-sizing: inherit; font-weight: 700;">eventbus.on("getMessage", (e) => {<br style="box-sizing: inherit;" /> this.$data.msg = e;<br style="box-sizing: inherit;" /> });</span><br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" />};<br style="box-sizing: inherit;" /></script></span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="2121" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 3:</span> Register all the components in <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">App.vue</span>.</p><pre class="ky kz la lb ga lc bt ld" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj le lf ii lg b do lh li l lj" data-selectable-paragraph="" id="e3fa" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><template><br style="box-sizing: inherit;" /> <div id="app"><br style="box-sizing: inherit;" /> <span class="lg ij" style="box-sizing: inherit; font-weight: 700;"><HelloMessagePublish /><br style="box-sizing: inherit;" /> <HelloMessageDisplay /><br style="box-sizing: inherit;" /> <HelloMessageDisplay2 /></span><br style="box-sizing: inherit;" /> </div><br style="box-sizing: inherit;" /></template></span><span class="gj le lf ii lg b do ll lm ln lo lp li l lj" data-selectable-paragraph="" id="0c84" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><script><br style="box-sizing: inherit;" /><span class="lg ij" style="box-sizing: inherit; font-weight: 700;">import HelloMessageDisplay from "./components/HelloMessageDisplay";<br style="box-sizing: inherit;" />import HelloMessageDisplay2 from "./components/HelloMessageDisplay2";<br style="box-sizing: inherit;" />import HelloMessagePublish from "./components/HelloMessagePublish";</span></span><span class="gj le lf ii lg b do ll lm ln lo lp li l lj" data-selectable-paragraph="" id="c61d" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default {<br style="box-sizing: inherit;" /> name: "App",<br style="box-sizing: inherit;" /> components: {<br style="box-sizing: inherit;" /> <span class="lg ij" style="box-sizing: inherit; font-weight: 700;">HelloMessageDisplay,<br style="box-sizing: inherit;" /> HelloMessageDisplay2,<br style="box-sizing: inherit;" /> HelloMessagePublish,</span><br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" />};<br style="box-sizing: inherit;" /></script></span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="42c9" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now run the application, type the message in the textbox and click on publish button, message will appear in UI through event bus notification.</p><figure class="ky kz la lb ga lr fo fp paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="ls lt dq lu cf lv" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 692px; z-index: auto;" tabindex="0"><div class="fo fp lq" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 756px;"><img alt="" class="cf lw lx" height="254" loading="lazy" role="presentation" src="https://miro.medium.com/max/1400/1*3h40bNbEl6RmGvRQoyRLSg.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 692px;" width="700" /></div></div></figure><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="777f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">easy-peasy! isn’t it. Hope you enjoyed the content, follow me for more like this and please don’t forget to <span style="font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; letter-spacing: -0.06px;">like/comment</span> for it. Happy programming.</span></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-28623263010622046972022-07-04T17:03:00.006+05:302022-10-27T12:04:04.595+05:30Custom vuex store module<p> <span style="background-color: white; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">If you haven’t read through my previous article here on</span><span style="background-color: white; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;"> </span><a class="au kd" href="https://binodmahto.blogspot.com/2022/06/props-vs-emit-in-vuejs.html" rel="noopener" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">props vs emit in vue.js</a><span style="background-color: white; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">, I would recommend to read it first unless you are aware of props and emit concept of vuejs framework. I also expects, you know the basics already about Vue framework.</span></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="f731" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">So far we have seen the ways to share/transfer data<br style="box-sizing: inherit;" /><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">i.</span> using props : from parent to child.<br style="box-sizing: inherit;" /><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">ii.</span> using emit: from child to parent.<br style="box-sizing: inherit;" />but what if we have to share the data across our vuejs application:<br style="box-sizing: inherit;" /><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">iii.</span> this is where Vuex Store is used.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="beed" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">What is Vuex Store</span></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="b5a4" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Vuex Store is basically a container to hold your application’s state information which will be available throughout the application. Vuex store are reactive, hence if store’s state changes from any component, it will be updated across component reactively.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="5d6a" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Vuex Store uses a single state tree, it means a single object will contain entire application level state. In a big project we would generally need to maintain the state module wise hence here we will be going through an example of creating a custom vuex store submodule to achieve the same.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="8431" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Vuex Store state update happens through <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Vuex mutation</span> but you cannot mutate the store state directly instead you have to commit your mutations to update state hence we nee to use action here to commit mutations.</p><blockquote class="ke kf kg" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="jf jg kh jh b ji jj jk jl jm jn jo jp ki jr js jt kj jv jw jx kk jz ka kb kc ib gj" data-selectable-paragraph="" id="e409" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Vuex mutations are very similar to events: each mutation has a string type and a handler. The handler function is where we perform actual state modifications, and it will receive the state as the first argument and payload (data) is the second argument. This is how vuex store is operated to modify and update the state.</p></blockquote><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="41e8" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Example Scenario</span></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="4803" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">For an example here, we will be creating a custom store submodule to maintain user’s state which will have it’s own mutations, actions and getters to read/write it. Our sub module will be divided into for parts:<br style="box-sizing: inherit;" /><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">i. State:</span> state of the sub module<br style="box-sizing: inherit;" /><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">ii. Getters:</span> gettters to read the state of the sub module.<br style="box-sizing: inherit;" /><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">iii. actions:</span> action to commit the state mutation<br style="box-sizing: inherit;" /><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">iv. mutations:</span> mutate the state.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="76ca" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Action Time: let’s code.</span></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="eb06" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">First we need to create a vue js application and install Vuex package. Store is available from <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Vuex</span>.<br style="box-sizing: inherit;" />In my case I created an vuejs application named “VueJsDemoApp” using the dependencies as of <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">vue@2.7.0</span> and <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">vuex@3.6.2 </span>for the example here.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="9aaf" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Below are the steps we will be following to create the custom vuex store to maintain user state (first name, last name and email). We will call this user state as submodule as vuex store maintain single tree and that is the main module and here we would create a custom vuex sub module and add to the vuex store. Steps are:</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="a57a" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 1:</span> Inside src folder create a folder name ‘<span class="jh ij" style="box-sizing: inherit; font-weight: 700;">interfaces</span>’ to define interfaces common to entire application. In our case, we will be creating a interface type IUser. Hence add two files here as<br style="box-sizing: inherit;" />src=> interfaces =><span class="jh ij" style="box-sizing: inherit; font-weight: 700;"> i-user.ts</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="7f02" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">export default interface IUser {<br style="box-sizing: inherit;" /> firstname: string;<br style="box-sizing: inherit;" /> lastname: string;<br style="box-sizing: inherit;" /> email:string;<br style="box-sizing: inherit;" />};</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="6e43" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">and src=> interfaces => <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">index.ts</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="0261" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">export {default as IUser} from './i-user'</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="e61d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">You may define the interface types into index.ts file only but I did this to separate the interface definition from index.ts file. This will be very useful and needed when you have multiple interface types and you want to maintain the code clean.</p><blockquote class="ke kf kg" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="jf jg kh jh b ji jj jk jl jm jn jo jp ki jr js jt kj jv jw jx kk jz ka kb kc ib gj" data-selectable-paragraph="" id="a598" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Note: <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">index.ts</span> file is the file which vue framework will look from for imports.</p></blockquote><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="7879" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 2:</span> within <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">src </span>folder create a folder with name as ‘<span class="jh ij" style="box-sizing: inherit; font-weight: 700;">store</span>’.<br style="box-sizing: inherit;" />All our code related to store module will go here.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="bece" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 3:</span> Within store folder create three folders named as ‘<span class="jh ij" style="box-sizing: inherit; font-weight: 700;">config</span>’, ‘<span class="jh ij" style="box-sizing: inherit; font-weight: 700;">interfaces</span>’ and ‘<span class="jh ij" style="box-sizing: inherit; font-weight: 700;">modules</span>’.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="92c5" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 4:</span> within interfaces folder, create an generic interface called IRootState.<br style="box-sizing: inherit;" /><br style="box-sizing: inherit;" />src=> store => interfaces => <span class="jh ij" style="box-sizing: inherit; font-weight: 700;"><em class="kh" style="box-sizing: inherit;">i-root-state.ts</em> :</span> which defines the IRootState interface.</p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="6218" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">// our root state is empty because we make use of modules,<br style="box-sizing: inherit;" />// however we do need it for generic arguments and thus we declare it<br style="box-sizing: inherit;" />export default interface IRootState { };</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="7ffa" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">and src=> store => interfaces =><span class="jh ij" style="box-sizing: inherit; font-weight: 700;"><em class="kh" style="box-sizing: inherit;">index.ts</em> :</span> to export the type</p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="04ee" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">export { default as IRootState } from './i-root-state';</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="b561" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 5:</span> create the generic store options config in <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">index.ts</span> file inside <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">config </span>folder as:</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="c9b9" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">src=> store => config =><span class="jh ij" style="box-sizing: inherit; font-weight: 700;"> index.ts</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="c8f1" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><span class="kt ij" style="box-sizing: inherit; font-weight: 700;">import { StoreOptions } from 'vuex';</span><br style="box-sizing: inherit;" />import { IRootState } from '../interfaces';<br style="box-sizing: inherit;" />import modules from '../modules';</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="9e9a" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">const config: <span class="kt ij" style="box-sizing: inherit; font-weight: 700;">StoreOptions</span><IRootState> = {<br style="box-sizing: inherit;" /> strict: true,<br style="box-sizing: inherit;" /> state() { },<br style="box-sizing: inherit;" /> mutations: {},<br style="box-sizing: inherit;" /> actions: {},<br style="box-sizing: inherit;" /> modules,<br style="box-sizing: inherit;" />};</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="2bfa" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default config;</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="68a0" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 6:</span> Create the <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">index.ts </span>inside <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">store folder </span>to define the store object which is based on our generic state type as IRootState.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="0148" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">src=> store => <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">index.ts</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="b9e3" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><span class="kt ij" style="box-sizing: inherit; font-weight: 700;">import Vue from 'vue';<br style="box-sizing: inherit;" />import Vuex from 'vuex';<br style="box-sizing: inherit;" />import config from './config';<br style="box-sizing: inherit;" />import { IRootState } from './interfaces';</span></span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="d866" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><span class="kt ij" style="box-sizing: inherit; font-weight: 700;">Vue.use(Vuex);</span></span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="4b67" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><span class="kt ij" style="box-sizing: inherit; font-weight: 700;">const store = new Vuex.Store<IRootState>(config);</span></span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="72d2" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default store;</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="53b5" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 7:</span> Import the store module into the <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">App.vue</span> (application).</p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="f105" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><template><br style="box-sizing: inherit;" /> <div id="app"><br style="box-sizing: inherit;" /> <Home/><br style="box-sizing: inherit;" /> <StoreData/><br style="box-sizing: inherit;" /> </div><br style="box-sizing: inherit;" /></template></span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="bdcb" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><script lang="ts"><br style="box-sizing: inherit;" /> import Home from './components/Home.vue';<br style="box-sizing: inherit;" /> import StoreData from './components/StoreData.vue'<br style="box-sizing: inherit;" /> <span class="kt ij" style="box-sizing: inherit; font-weight: 700;"> import store from "@/store";</span></span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="9cc0" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default {<br style="box-sizing: inherit;" /> components: {<br style="box-sizing: inherit;" /> Home,<br style="box-sizing: inherit;" /> StoreData<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> <span class="kt ij" style="box-sizing: inherit; font-weight: 700;"> store</span><br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /></script></span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="d4ab" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><style><br style="box-sizing: inherit;" /></style></span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="3091" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">As of now, you can focus on highlighted code in bold only and rest you will understand when we create defined components late in this example, but this will be our full code for App.Vue.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="2daa" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now will create our submodules (i.e. user in this case) inside modules folder.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="c704" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 8:</span> Create a ‘<span class="jh ij" style="box-sizing: inherit; font-weight: 700;">user</span>’ sub module by creating a folder name ‘<span class="jh ij" style="box-sizing: inherit; font-weight: 700;">user</span>’<span class="jh ij" style="box-sizing: inherit; font-weight: 700;"> inside modules folder</span>.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="7ef5" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 9:</span> Within user folder create a folder called ‘<span class="jh ij" style="box-sizing: inherit; font-weight: 700;">static</span>’ (you can name it something else if you want)where we define IUserState interface type to hold IUser as state and enums to avoid hard coded names for action, mutations and getters etc. Add the respective files inside src=> store => modules=> user => static as:</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="e1e9" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">i. global-user-action-enum.ts</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="7341" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">export enum GlobalUserActionEnum{<br style="box-sizing: inherit;" /> SET_USER = "setUser"<br style="box-sizing: inherit;" />}</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="2d34" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default GlobalUserActionEnum;</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="1519" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">ii. global-user-getters-enum.ts</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="f8f1" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">import IUser from "@/interfaces/i-user";</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="5876" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export enum GlobalUserGetterEnum {<br style="box-sizing: inherit;" /> GET_USER = 'getUser'<br style="box-sizing: inherit;" />}</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="2bf6" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default GlobalUserGetterEnum;</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="4ed1" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">iii. global-user-mutation-enum.ts</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="f3bd" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">enum GlobalUserMutationEnum {<br style="box-sizing: inherit;" /> Mutate_USER = 'MUTATE_USER',<br style="box-sizing: inherit;" />}</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="35ff" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default GlobalUserMutationEnum;</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="e2e8" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">iv. global-user-namespace.ts</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="ddd6" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">export const NAMESPACE = 'user';</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="13f2" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default NAMESPACE;</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="2186" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">v. global-user-payload.ts</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="7ea4" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">import IUser from "@/interfaces/i-user";</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="9fbc" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export type IGlobalUserPayload = Partial<IUser>;</span></pre><blockquote class="ke kf kg" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="jf jg kh jh b ji jj jk jl jm jn jo jp ki jr js jt kj jv jw jx kk jz ka kb kc ib gj" data-selectable-paragraph="" id="bde7" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Note: State payload type created as Partial<IUser> so that the state doesn’t force to update all the properties of IUser always instead you can commit partial update of IUser too.</p></blockquote><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="487f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">vi. i-state-user.ts</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="c478" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">import IUser from "@/interfaces/i-user";</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="9722" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default interface IUserState {<br style="box-sizing: inherit;" /> user: IUser;<br style="box-sizing: inherit;" />};</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="ab52" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">state type object which will available in the store state tree.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="a69a" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">vii. index.ts</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="b260" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">export { default as GlobalUserActionEnum} from './global-user-action-enum';<br style="box-sizing: inherit;" />export { default as GlobalUserMutationEnum } from './global-user-mutation-enum';<br style="box-sizing: inherit;" />export { default as GlobalUserGetterEnum} from './global-user-getters-enum';<br style="box-sizing: inherit;" />export { NAMESPACE } from './global-user-namespace';<br style="box-sizing: inherit;" />export {default as IUSerState } from './i-state-user';</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="f99c" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">export all types defined above inside user =>static folder.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="6f5a" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 10:</span> Define the state in the user folder</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="fbe2" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">user => <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">state.ts</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="159a" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">import IUserState from "./static/i-state-user";</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="7541" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export const userState: () => <span class="kt ij" style="box-sizing: inherit; font-weight: 700;">IUserState </span>= () => ({<br style="box-sizing: inherit;" /> user : {<br style="box-sizing: inherit;" /> firstname: '',<br style="box-sizing: inherit;" /> lastname: '',<br style="box-sizing: inherit;" /> email:''<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />});</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="ff24" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 11:</span> Define the mutations to save the user state in the store</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="0c05" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">src=> store => modules=> user => <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">mutations.ts</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="8202" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">import { MutationTree } from 'vuex';<br style="box-sizing: inherit;" />import { GlobalUserMutationEnum } from './static';<br style="box-sizing: inherit;" />import IUserState from "./static/i-state-user";<br style="box-sizing: inherit;" />import { IGlobalUserPayload } from './static/global-user-payload';</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="6d08" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export const userMutations: <span class="kt ij" style="box-sizing: inherit; font-weight: 700;">MutationTree<IUserState> </span>= {<br style="box-sizing: inherit;" /> <span class="kt ij" style="box-sizing: inherit; font-weight: 700;"> [GlobalUserMutationEnum.Mutate_USER](state, payload: IGlobalUserPayload) {<br style="box-sizing: inherit;" /> Object.assign(state.user, payload);<br style="box-sizing: inherit;" /> },</span><br style="box-sizing: inherit;" />};</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="d0a2" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default userMutations;</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="69d0" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 12:</span> Define the action to commit the mutations</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="905b" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">src=> store => modules=> user => <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">action.ts</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="6652" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">import { ActionTree } from 'vuex';<br style="box-sizing: inherit;" />import { GlobalUserActionEnum, GlobalUserMutationEnum } from './static';<br style="box-sizing: inherit;" />import IUserState from './static/i-state-user';<br style="box-sizing: inherit;" />import { IRootState } from '../../interfaces';<br style="box-sizing: inherit;" />import { IGlobalUserPayload } from './static/global-user-payload';</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="4ce4" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export const userActions: <span class="kt ij" style="box-sizing: inherit; font-weight: 700;">ActionTree<IUserState, IRootState></span> = {</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="b6bc" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><span class="kt ij" style="box-sizing: inherit; font-weight: 700;">[GlobalUserActionEnum.SET_USER]({ commit }, payload: IGlobalUserPayload) {<br style="box-sizing: inherit;" /> commit(GlobalUserMutationEnum.Mutate_USER, payload);<br style="box-sizing: inherit;" /> },</span><br style="box-sizing: inherit;" />};</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="a773" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default userActions;</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="5f4f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 13:</span> Define getters to read the IUser from the store state of user module.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="41bf" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">src=> store => modules=> user => getters.ts</p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="175d" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">import { GetterTree } from 'vuex';<br style="box-sizing: inherit;" />import { IRootState } from '../../interfaces';<br style="box-sizing: inherit;" />import IUser from "@/interfaces/i-user";<br style="box-sizing: inherit;" />import IUserState from './static/i-state-user';<br style="box-sizing: inherit;" />import GlobalUserGetterEnum from './static/global-user-getters-enum';</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="c46c" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export const userGetters: <span class="kt ij" style="box-sizing: inherit; font-weight: 700;">GetterTree<IUserState, IRootState> </span>= {</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="c53e" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><span class="kt ij" style="box-sizing: inherit; font-weight: 700;">[GlobalUserGetterEnum.GET_USER](state): IUser {<br style="box-sizing: inherit;" /> return state.user;<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" />};</span></span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="aade" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default userGetters;</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="b572" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 14:</span> Define the user state module</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="39ab" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">src=> store => modules=> user => <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">index.ts</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="ea18" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">import { Module } from 'vuex';<br style="box-sizing: inherit;" />import { IRootState } from '../../interfaces';<br style="box-sizing: inherit;" />import IUserState from "./static/i-state-user";<br style="box-sizing: inherit;" />import { userGetters } from './getters';<br style="box-sizing: inherit;" />import userMutations from './mutations';<br style="box-sizing: inherit;" />import { userActions } from './action';<br style="box-sizing: inherit;" />import { userState } from './state';</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="b811" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">const globalUser: <span class="kt ij" style="box-sizing: inherit; font-weight: 700;">Module<IUserState, IRootState></span> = {</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="8077" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"> <span class="kt ij" style="box-sizing: inherit; font-weight: 700;">namespaced: true,<br style="box-sizing: inherit;" /> state: userState,<br style="box-sizing: inherit;" /> getters: userGetters,<br style="box-sizing: inherit;" /> mutations: userMutations,<br style="box-sizing: inherit;" /> actions: userActions,</span><br style="box-sizing: inherit;" /> };</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="e367" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default globalUser;</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="bc0e" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Step 15: Finally export the module. Create a index.ts file inside modules folder.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="6b31" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">src=> store => modules=> <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">index.ts</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="779e" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">import user from './user'</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="dedb" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default{<br style="box-sizing: inherit;" /> user<br style="box-sizing: inherit;" />};</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="4205" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">and we are done. Our user store submodule is ready to be used and consumed.<br style="box-sizing: inherit;" />To demonstrate the consumption I’m creating two components inside components folder here as:</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="f20f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">src => components => <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Home.vue</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="4940" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><template><br style="box-sizing: inherit;" /> <div class="home"><br style="box-sizing: inherit;" /> First Name: <input v-model="user.firstname" /><br style="box-sizing: inherit;" /> <br /><br style="box-sizing: inherit;" /> Last Name: <input v-model="user.lastname" /><br style="box-sizing: inherit;" /> <br /><br style="box-sizing: inherit;" /> Email: <input v-model="user.email" /><br style="box-sizing: inherit;" /> <br /><br style="box-sizing: inherit;" /> <button <a class="au kd" href="http://twitter.com/click" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">@click</a>="onSave()">Update User in Store</button><br style="box-sizing: inherit;" /> <br /><br style="box-sizing: inherit;" /> </div><br style="box-sizing: inherit;" /></template></span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="2d61" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><script lang="ts"><br style="box-sizing: inherit;" />import Vue from "vue";<br style="box-sizing: inherit;" />import { IUser } from "@/interfaces";<br style="box-sizing: inherit;" /><span class="kt ij" style="box-sizing: inherit; font-weight: 700;">import { mapActions, mapGetters } from "vuex";</span><br style="box-sizing: inherit;" /><span class="kt ij" style="box-sizing: inherit; font-weight: 700;">import {<br style="box-sizing: inherit;" /> GlobalUserActionEnum,<br style="box-sizing: inherit;" /> GlobalUserGetterEnum,<br style="box-sizing: inherit;" /> NAMESPACE,<br style="box-sizing: inherit;" />} from "../store/modules/user/static";</span></span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="edc7" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default Vue.component('Home', {<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> data() {<br style="box-sizing: inherit;" /> return {<br style="box-sizing: inherit;" /> user : {<br style="box-sizing: inherit;" /> firstname: "",<br style="box-sizing: inherit;" /> lastname: "",<br style="box-sizing: inherit;" /> email: "",<br style="box-sizing: inherit;" /> } as IUser,<br style="box-sizing: inherit;" /> };<br style="box-sizing: inherit;" /> },</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="5d8d" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">methods:{<br style="box-sizing: inherit;" /> onSave(){<br style="box-sizing: inherit;" /> this.setUser({<br style="box-sizing: inherit;" /> firstname: this.$data.user.firstname,<br style="box-sizing: inherit;" /> lastname: this.$data.user.lastname,<br style="box-sizing: inherit;" /> email: this.$data.user.email,<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> );<br style="box-sizing: inherit;" /> alert('User details are saved to store.')<br style="box-sizing: inherit;" /> },</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="92e1" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><span class="kt ij" style="box-sizing: inherit; font-weight: 700;">...mapActions(NAMESPACE, {<br style="box-sizing: inherit;" /> setUser: GlobalUserActionEnum.SET_USER,<br style="box-sizing: inherit;" /> }),</span></span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="3329" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><span class="kt ij" style="box-sizing: inherit; font-weight: 700;">},</span></span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="6dd1" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">computed:{<br style="box-sizing: inherit;" /> <span class="kt ij" style="box-sizing: inherit; font-weight: 700;"> ...mapGetters(NAMESPACE, {<br style="box-sizing: inherit;" /> getUser: GlobalUserGetterEnum.GET_USER,<br style="box-sizing: inherit;" /> }),</span><br style="box-sizing: inherit;" /> },</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="7c27" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">created(){<br style="box-sizing: inherit;" /> //Don<br style="box-sizing: inherit;" /> this.$data.user.firstname = this.getUser.firstname;<br style="box-sizing: inherit;" /> this.$data.user.lastname = this.getUser.lastname;<br style="box-sizing: inherit;" /> this.$data.user.email = this.getUser.email;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> })</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="d8eb" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"></script></span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="6d88" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Here we are using <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">mapGetters </span>and <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">mapActions</span> feature of vuex to map the action and getters of our user store submodule which is mapped with the action and getters using the enum as we defined earlier to avoid hardcoded names.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="dbbb" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">As per this component here, there are three text boxes which will take user’s first name, last name and email as input and update the same to store on click of the button.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="7d50" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">As we learn, Vuex is reactive in nature hence to demonstrate this let’s create another component as:</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="664b" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">src=> components => <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">StoreData.vue</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="66a9" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><template><br style="box-sizing: inherit;" /> <div><br style="box-sizing: inherit;" /> <br /><br /><br style="box-sizing: inherit;" /> <span class="kt ij" style="box-sizing: inherit; font-weight: 700;"> <h1>User Data (update on click) : {{ userData }}</h1><br style="box-sizing: inherit;" /> <h1>User Data (reactive update) : {{ userComputedData }}</h1><br style="box-sizing: inherit;" /> <button </span><a class="au kd" href="http://twitter.com/click" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank"><span class="kt ij" style="box-sizing: inherit; font-weight: 700;">@click</span></a><span class="kt ij" style="box-sizing: inherit; font-weight: 700;">="onFetch()">Read User from Store</button></span><br style="box-sizing: inherit;" /> <br /><br style="box-sizing: inherit;" /> </div><br style="box-sizing: inherit;" /></template></span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="f68f" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><script lang="ts"><br style="box-sizing: inherit;" />import Vue from "vue";<br style="box-sizing: inherit;" />import { mapGetters } from "vuex";<br style="box-sizing: inherit;" />import {<br style="box-sizing: inherit;" /> GlobalUserGetterEnum,<br style="box-sizing: inherit;" /> NAMESPACE,<br style="box-sizing: inherit;" />} from "../store/modules/user/static";</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="cbfd" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default Vue.component('StoreData', {<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> data() {<br style="box-sizing: inherit;" /> return {<br style="box-sizing: inherit;" /> userData: String,<br style="box-sizing: inherit;" /> };<br style="box-sizing: inherit;" /> },</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="51fd" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">methods:{<br style="box-sizing: inherit;" /> <span class="kt ij" style="box-sizing: inherit; font-weight: 700;">onFetch(){<br style="box-sizing: inherit;" /> this.$data.userData = this.getUser.firstname + ' ' + this.getUser.lastname + ', '+ this.getUser.email;<br style="box-sizing: inherit;" /> },</span><br style="box-sizing: inherit;" /> },</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="1cdd" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">computed:{<br style="box-sizing: inherit;" /> <span class="kt ij" style="box-sizing: inherit; font-weight: 700;">...mapGetters(NAMESPACE, {<br style="box-sizing: inherit;" /> getUser: GlobalUserGetterEnum.GET_USER,<br style="box-sizing: inherit;" /> }),</span></span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="afa8" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><span class="kt ij" style="box-sizing: inherit; font-weight: 700;">userComputedData(){<br style="box-sizing: inherit;" /> return this.getUser.firstname + ' ' + this.getUser.lastname + ', '+ this.getUser.email;<br style="box-sizing: inherit;" /> }</span><br style="box-sizing: inherit;" /> },</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="d15f" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">created(){<br style="box-sizing: inherit;" /> this.onFetch();<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> })</span><span class="gj kr ks ii kt b do kx ky kz la lb kv l kw" data-selectable-paragraph="" id="25c4" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"></script></span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="b28a" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Here, I have two h1 tags where first one display the user info from store by reading it through getters map whereas the second h1 tag display/updates automatically due to reactive action as soon as store is update for user.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="df95" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">If you run the application now, you will see the UI output as:</p><figure class="kl km kn ko ga ld fo fp paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="le lf dq lg cf lh" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 692px; z-index: auto;" tabindex="0"><div class="fo fp lc" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1930px;"><img alt="" class="cf li lj" height="306" loading="lazy" role="presentation" src="https://miro.medium.com/max/1400/1*PTKfeSti-E7kfaVPwpkIxg.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 692px;" width="700" /></div></div></figure><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="8918" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In above screen shot other half (right side) of the picture is of <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">vue.js dev tools</span> extension of chrome browser which is a great tool for vuejs development. Download and enjoy.</p><blockquote class="ke kf kg" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="jf jg kh jh b ji jj jk jl jm jn jo jp ki jr js jt kj jv jw jx kk jz ka kb kc ib gj" data-selectable-paragraph="" id="966d" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Note: with this approach you will be able to create as many store submodules you want. Simple approach would be to just copy paste the entire user folder and change the name as of your module name.</p></blockquote><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="c0d7" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;"><em class="kh" style="box-sizing: inherit;">Code is available here:</em></span><br style="box-sizing: inherit;" /><a class="au kd" href="https://github.com/binodmahto/webfrontendprojects/tree/main/VuejsDemoApp" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://github.com/binodmahto/webfrontendprojects/tree/main/VuejsDemoApp</a></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="bfba" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">That’s all. Hope you enjoyed the content, follow me for more like this and please don’t forget to <span style="font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; letter-spacing: -0.06px;">like/comment </span>for it. Happy programming.</span></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="c2ca" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Reference:</span></p><div class="lk ll fw fy lm ln" style="background-color: white; box-shadow: rgb(230, 230, 230) 0px 0px 0px 1px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin-top: 32px;"><a href="https://vuex.vuejs.org/guide/state.html" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit; text-decoration-line: none;" target="_blank"><div class="lo o hi" style="box-sizing: inherit; display: flex; flex: 0 0 auto; padding: 0px;"><div class="lp o db dz ep lq" style="box-sizing: inherit; display: flex; flex-direction: column; flex: 1 1 auto; justify-content: center; padding: 16px 20px;"><h2 class="bn ij do bp lr ls lt lu lv lw lx ih gj" style="-webkit-box-orient: vertical; -webkit-line-clamp: 2; box-sizing: inherit; color: #292929; display: -webkit-box; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 16px; letter-spacing: 0px; line-height: 20px; margin: 0px; max-height: 40px; overflow: hidden; text-overflow: ellipsis;">State | Vuex</h2><div class="ly l" style="box-sizing: inherit; margin-top: 8px;"><h3 class="bn b do bp lr ls lt lu lv lw lx co" style="-webkit-box-orient: vertical; -webkit-line-clamp: 2; box-sizing: inherit; color: #757575; display: -webkit-box; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 400; line-height: 20px; margin: 0px; max-height: 40px; overflow: hidden; text-overflow: ellipsis;">Vuex uses a single state tree - that is, this single object contains all your application level state and serves as the…</h3></div><div class="lz l" style="box-sizing: inherit; margin-top: 12px;"><p class="bn b gr bp lr ls lt lu lv lw lx co" style="-webkit-box-orient: vertical; -webkit-line-clamp: 2; box-sizing: inherit; color: #757575; display: -webkit-box; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; line-height: 20px; margin: 0px; max-height: 40px; overflow: hidden; text-overflow: ellipsis;">vuex.vuejs.org</p></div></div></div></a></div><div class="lk ll fw fy lm ln" style="background-color: white; box-shadow: rgb(230, 230, 230) 0px 0px 0px 1px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin-top: 32px;"><a href="https://vuex.vuejs.org/guide/modules.html#namespacing" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit; text-decoration-line: none;" target="_blank"><div class="lo o hi" style="box-sizing: inherit; display: flex; flex: 0 0 auto; padding: 0px;"><div class="lp o db dz ep lq" style="box-sizing: inherit; display: flex; flex-direction: column; flex: 1 1 auto; justify-content: center; padding: 16px 20px;"><h2 class="bn ij do bp lr ls lt lu lv lw lx ih gj" style="-webkit-box-orient: vertical; -webkit-line-clamp: 2; box-sizing: inherit; color: #292929; display: -webkit-box; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 16px; letter-spacing: 0px; line-height: 20px; margin: 0px; max-height: 40px; overflow: hidden; text-overflow: ellipsis;">Modules | Vuex</h2><div class="ly l" style="box-sizing: inherit; margin-top: 8px;"><h3 class="bn b do bp lr ls lt lu lv lw lx co" style="-webkit-box-orient: vertical; -webkit-line-clamp: 2; box-sizing: inherit; color: #757575; display: -webkit-box; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 400; line-height: 20px; margin: 0px; max-height: 40px; overflow: hidden; text-overflow: ellipsis;">Due to using a single state tree, all states of our application are contained inside one big object. However, as our…</h3></div><div class="lz l" style="box-sizing: inherit; margin-top: 12px;"><p class="bn b gr bp lr ls lt lu lv lw lx co" style="-webkit-box-orient: vertical; -webkit-line-clamp: 2; box-sizing: inherit; color: #757575; display: -webkit-box; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; line-height: 20px; margin: 0px; max-height: 40px; overflow: hidden; text-overflow: ellipsis;">vuex.vuejs.org</p></div></div></div></a></div>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-55708305611486958022022-06-27T22:15:00.006+05:302022-10-27T12:04:59.262+05:30ASP.NET Core Integration test using Moq Framework<p> <span style="background-color: white; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">Testing coverage is the key part of any project development and Testing coverage is not only about the unit testing instead Integration Testing is extremely important to make sure entire system is unbroken & bug free with any change or subsequent enhancement.</span></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="e6d5" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">When we talk about integration testing, mocking dependencies are the oxygen to cover the integration testing. You may create a replica of your services as mock to work with integration testing but do we really need to do that, when <a class="au kd" href="https://www.nuget.org/packages/Moq" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">Moq </a>framework is doing the same for us and we can save lot of time & effort from writing unnecessary codes.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="0baf" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">So lets see How to achieve Integration Testing for ASP.NET Core using Moq framework. My intention here is to only show the integration testing using Moq hence I’m doing a simple ASP.NET Core Web API project which has a service endpoint to return the weather forecast and goal is to test the end-to-end flow of api call by mocking the service which calculates the forecast.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="8354" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">I’m using .Net core 6, xUnit for testing and Moq for mocking.</span></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="056d" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now, first we will be creating a blank solution named ‘MoqDemoSol.sln” and add a .net core 6 class library project named <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">CoreWebAPIMoqDemo.Services</span> and two files as :<br style="box-sizing: inherit;" /><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">IWeatherForecastService.cs :</span> interface for business service to calculate weather forecast</p><pre class="ke kf kg kh ga ki bt kj" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kk kl ii km b do kn ko l kp" data-selectable-paragraph="" id="7612" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">namespace CoreWebAPIMoqDemo.Services<br style="box-sizing: inherit;" />{<br style="box-sizing: inherit;" /> public interface <span class="km ij" style="box-sizing: inherit; font-weight: 700;">IWeatherForecastService</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="km ij" style="box-sizing: inherit; font-weight: 700;">Task<WeatherForecast[]> GetWeatherForecast();</span><br style="box-sizing: inherit;" /> }</span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="c8c8" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">public record WeatherForecast(DateTime Date, int TemperatureC, string? Summary)<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="9a91" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">and</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="12c0" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">WeatherForecastService.cs </span>: implementation of business service to calculate weather forecast</p><pre class="ke kf kg kh ga ki bt kj" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kk kl ii km b do kn ko l kp" data-selectable-paragraph="" id="a502" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">namespace CoreWebAPIMoqDemo.Services<br style="box-sizing: inherit;" />{<br style="box-sizing: inherit;" /> public class WeatherForecastService : IWeatherForecastService<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> string[] summaries = new string[]<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"<br style="box-sizing: inherit;" /> };<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> <span class="km ij" style="box-sizing: inherit; font-weight: 700;"> public async Task<WeatherForecast[]> GetWeatherForecast()</span><br style="box-sizing: inherit;" /> <span class="km ij" style="box-sizing: inherit; font-weight: 700;">{<br style="box-sizing: inherit;" /> var forecast = Enumerable.Range(1, 5).Select(index =><br style="box-sizing: inherit;" /> new WeatherForecast<br style="box-sizing: inherit;" /> (<br style="box-sizing: inherit;" /> DateTime.Now.AddDays(index),<br style="box-sizing: inherit;" /> Random.Shared.Next(-20, 55),<br style="box-sizing: inherit;" /> summaries[Random.Shared.Next(summaries.Length)]<br style="box-sizing: inherit;" /> )).ToArray();<br style="box-sizing: inherit;" /> return forecast;<br style="box-sizing: inherit;" /> }</span><br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="744b" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Our business layer service which calculates the weather forecast is ready.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="008b" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now let’s create a .net core 6 web api project named as ‘<span class="jh ij" style="box-sizing: inherit; font-weight: 700;">CoreWebAPIMoqDemo</span>’ using the template and replace the code in <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Program.cs</span> as:</p><pre class="ke kf kg kh ga ki bt kj" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kk kl ii km b do kn ko l kp" data-selectable-paragraph="" id="8d3e" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">using CoreWebAPIMoqDemo.Services;</span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="cfb9" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">var builder = WebApplication.CreateBuilder(args);</span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="f13e" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">// Add services to the container.<br style="box-sizing: inherit;" />// Learn more about configuring Swagger/OpenAPI at <a class="au kd" href="https://aka.ms/aspnetcore/swashbuckle" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://aka.ms/aspnetcore/swashbuckle</a><br style="box-sizing: inherit;" />builder.Services.AddEndpointsApiExplorer();<br style="box-sizing: inherit;" />builder.Services.AddSwaggerGen();<br style="box-sizing: inherit;" /><span class="km ij" style="box-sizing: inherit; font-weight: 700;">builder.Services.AddSingleton<IWeatherForecastService, WeatherForecastService>();</span></span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="abac" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">var app = builder.Build();</span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="9e4c" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">// Configure the HTTP request pipeline.<br style="box-sizing: inherit;" />if (app.Environment.IsDevelopment())<br style="box-sizing: inherit;" />{<br style="box-sizing: inherit;" /> app.UseSwagger();<br style="box-sizing: inherit;" /> app.UseSwaggerUI();<br style="box-sizing: inherit;" />}</span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="6bab" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">app.UseHttpsRedirection();</span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="f946" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><span class="km ij" style="box-sizing: inherit; font-weight: 700;">app.MapGet("/weatherforecast", async (IWeatherForecastService service) => <br style="box-sizing: inherit;" />{<br style="box-sizing: inherit;" /> return await service.GetWeatherForecast();<br style="box-sizing: inherit;" />})<br style="box-sizing: inherit;" />.WithName("GetWeatherForecast");</span></span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="974a" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">app.Run();</span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="8a5b" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><span class="km ij" style="box-sizing: inherit; font-weight: 700;">public partial class Program { }</span></span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="05f5" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Highlighted(in bold) codes are the modified code from the actual template Program.cs, Now if you run this you will see the service in swagger UI as:</p><figure class="ke kf kg kh ga kw fo fp paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="kx ky dq kz cf la" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 692px; z-index: auto;" tabindex="0"><div class="fo fp kv" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1884px;"><img alt="" class="cf lb lc" height="319" loading="lazy" role="presentation" src="https://miro.medium.com/max/1400/1*otAZ_R2lOO0s-RCF1F9uyA.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 692px;" width="700" /></div></div></figure><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="ed57" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now our application is ready, hence we will be moving forward to do the integration testing to test end-to-end flow of /weatherforecast service by mocking the service dependency of <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">CoreWebAPIMoqDemo.Services.IWeatherForecastService .</span></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="0979" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">why we are doing this is, assume this is a third party service call and we can’t get this in our testing environment. Now lets add the unit test project (of your choice i.e. MSTest, nUnit, xUnit etc, in my case it is xUnit) named as ‘<span class="jh ij" style="box-sizing: inherit; font-weight: 700;">CoreWebAPIMoqDemo.Tests</span>’ and install the package related to your unit test framework.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="07a0" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Next, since we will be using Moq framework for mocking hence install the Moq package through nuget package manager. In my case it is:</p><pre class="ke kf kg kh ga ki bt kj" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kk kl ii km b do kn ko l kp" data-selectable-paragraph="" id="4a0e" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><span class="km ij" style="box-sizing: inherit; font-weight: 700;"><PackageReference Include="Moq" Version="4.18.1" /></span></span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="094e" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">I’ll be keeping mocked service at once place hence adding a class named ‘<span class="jh ij" style="box-sizing: inherit; font-weight: 700;">MockServices.cs</span>’ which will have the Mocked services as well as a method (which uses reflection) to return list of all mocked service’s interface type and mock object defined here. Code is:</p><pre class="ke kf kg kh ga ki bt kj" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kk kl ii km b do kn ko l kp" data-selectable-paragraph="" id="f0d1" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">using Moq;<br style="box-sizing: inherit;" />using CoreWebAPIMoqDemo.Services;<br style="box-sizing: inherit;" />using System.Reflection;</span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="5713" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">namespace CoreWebAPIMoqDemo.Tests<br style="box-sizing: inherit;" />{<br style="box-sizing: inherit;" /> internal class MockServices<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="km ij" style="box-sizing: inherit; font-weight: 700;"> public Mock<IWeatherForecastService> WeatherForecastServiceMock { get; init; }</span></span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="d6ba" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">public MockServices()<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="km ij" style="box-sizing: inherit; font-weight: 700;">WeatherForecastServiceMock = new Mock<IWeatherForecastService>();</span><br style="box-sizing: inherit;" /> }</span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="c410" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">/// <summary><br style="box-sizing: inherit;" /> /// This returns the collection of all mock service's interface type and the mock object, defined here i.e. <see cref="WeatherForecastServiceMock"/>.<br style="box-sizing: inherit;" /> /// </summary><br style="box-sizing: inherit;" /> /// <returns></returns><br style="box-sizing: inherit;" /> <span class="km ij" style="box-sizing: inherit; font-weight: 700;"> public IEnumerable<(Type, object)> GetMocks()</span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> return GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)<br style="box-sizing: inherit;" /> .Select(x =><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> var interfaceType = x.PropertyType.GetGenericArguments()[0];<br style="box-sizing: inherit;" /> var value = x.GetValue(this) as Mock;</span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="b6e0" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">return (interfaceType, value.Object);<br style="box-sizing: inherit;" /> })<br style="box-sizing: inherit;" /> .ToArray();<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="07c0" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">The purpose of doing this is, to keep all mocked services at one place and then GetMocks() which help me get all the mocked object and interface type so that I’ll be able to inject this with .net core dependency container collection <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">IServiceCollection </span>to use during unit test execution.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="bc5f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Next adding a class named ‘<span class="jh ij" style="box-sizing: inherit; font-weight: 700;">TestMoqPOCApplication.cs</span>’ which inherits <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">WebApplicationFactory<Program></span> to override <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">CreateHost() </span>method to prepare the IServiceCollection for integration tests. code is:</p><pre class="ke kf kg kh ga ki bt kj" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kk kl ii km b do kn ko l kp" data-selectable-paragraph="" id="c0b4" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">using Microsoft.AspNetCore.Mvc.Testing;<br style="box-sizing: inherit;" />using Microsoft.Extensions.DependencyInjection;<br style="box-sizing: inherit;" />using Microsoft.Extensions.Hosting;<br style="box-sizing: inherit;" />using CoreWebAPIMoqDemo.Services;</span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="01c9" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">namespace CoreWebAPIMoqDemo.Tests<br style="box-sizing: inherit;" />{<br style="box-sizing: inherit;" /> internal class TestMoqPOCApplication : WebApplicationFactory<Program><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> private readonly MockServices _mockServices;<br style="box-sizing: inherit;" /> public TestMoqPOCApplication(<span class="km ij" style="box-sizing: inherit; font-weight: 700;">MockServices mockServices</span>)<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> _mockServices = mockServices;<br style="box-sizing: inherit;" /> }</span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="89ac" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">protected override IHost CreateHost(IHostBuilder builder)<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> builder.ConfigureServices(services => {<br style="box-sizing: inherit;" /> <span class="km ij" style="box-sizing: inherit; font-weight: 700;">foreach ((var interfaceType, var serviceMock) in _mockServices.<em class="ld" style="box-sizing: inherit;">GetMocks</em>())<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> services.Remove(services.SingleOrDefault(d => d.ServiceType == interfaceType));<br style="box-sizing: inherit;" /> services.AddSingleton(typeof(IWeatherForecastService), serviceMock);<br style="box-sizing: inherit;" /> }</span><br style="box-sizing: inherit;" /> });<br style="box-sizing: inherit;" /> return base.CreateHost(builder);<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> }</span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="c5ce" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"> }<br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="cd93" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">in above highlighted code, our MockServices instance is available through constructor and then inside CreateHost method looping through each mock services we defined in the MockService class and putting into dependency container by removing the existing one which will be having actual business implementation of <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">IWeatherForecastService</span>.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="a898" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">By this we are ready with mocking and now add the code for the integration test for <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">/weatherforecast api</span> call. Add a class <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">WeatherForecastTests.cs</span> and add the code into it as:</p><pre class="ke kf kg kh ga ki bt kj" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kk kl ii km b do kn ko l kp" data-selectable-paragraph="" id="8e00" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">using Moq;<br style="box-sizing: inherit;" />using CoreWebAPIMoqDemo.Services;<br style="box-sizing: inherit;" />using Newtonsoft.Json;</span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="e6a8" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">namespace CoreWebAPIMoqDemo.Tests<br style="box-sizing: inherit;" />{<br style="box-sizing: inherit;" /> public class WeatherForecastTests<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> private readonly TestMoqPOCApplication _testMoqPOCApplication;<br style="box-sizing: inherit;" /> private readonly MockServices _mockServices;<br style="box-sizing: inherit;" /> public readonly HttpClient _client;<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> public WeatherForecastTests()<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> _mockServices = new MockServices();<br style="box-sizing: inherit;" /> //instantiating TestMoqPOCApplication<br style="box-sizing: inherit;" /> <span class="km ij" style="box-sizing: inherit; font-weight: 700;">_testMoqPOCApplication = new TestMoqPOCApplication(_mockServices);</span><br style="box-sizing: inherit;" /> //creating client for api call<br style="box-sizing: inherit;" /> <span class="km ij" style="box-sizing: inherit; font-weight: 700;"> _client = _testMoqPOCApplication.CreateClient();</span><br style="box-sizing: inherit;" /> }</span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="fb99" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">[Fact]<br style="box-sizing: inherit;" /> public async void GetWeatherForecastTest()<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> //mocking the business service's GetWeatherForecast() method to return result as below <br style="box-sizing: inherit;" /> <span class="km ij" style="box-sizing: inherit; font-weight: 700;">var expResult = new WeatherForecast[]<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> new WeatherForecast(DateTime.Now, 26, "Bengaluru")<br style="box-sizing: inherit;" /> };</span><br style="box-sizing: inherit;" /> //mocking the business service's GetWeatherForecast()<br style="box-sizing: inherit;" /> <span class="km ij" style="box-sizing: inherit; font-weight: 700;"> _mockServices.WeatherForecastServiceMock.Setup(m => m.GetWeatherForecast()).ReturnsAsync(expResult);</span></span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="5a27" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">//calling the api<br style="box-sizing: inherit;" /> <span class="km ij" style="box-sizing: inherit; font-weight: 700;">var response = await _client.GetAsync("/weatherforecast");</span><br style="box-sizing: inherit;" /> <span class="km ij" style="box-sizing: inherit; font-weight: 700;"> string jsonString = await response.Content.ReadAsStringAsync();<br style="box-sizing: inherit;" /> var result = JsonConvert.DeserializeObject<WeatherForecast[]>(jsonString);</span></span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="223e" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">//testing the response<br style="box-sizing: inherit;" /> <span class="km ij" style="box-sizing: inherit; font-weight: 700;"> Assert.Equal(response.StatusCode, System.Net.HttpStatusCode.OK);<br style="box-sizing: inherit;" /> Assert.Equal(expResult, result);</span></span><span class="gj kk kl ii km b do kq kr ks kt ku ko l kp" data-selectable-paragraph="" id="ef8c" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">}<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="85cb" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Whoop, we are done. now if you run the test, you will see the result as:</p><figure class="ke kf kg kh ga kw fo fp paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="fo fp le" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 451px;"><img alt="" class="cf lb lc" height="709" loading="lazy" role="presentation" src="https://miro.medium.com/max/902/1*iHJYaQcB2sRl6g54nZROgw.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 451px;" width="451" /></div></figure><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="be48" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Entire code is available here: <a class="au kd" href="https://github.com/binodmahto/FunProjects/tree/main/CoreWebAPIMoqDemo" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://github.com/binodmahto/FunProjects/tree/main/CoreWebAPIMoqDemo</a></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="fb56" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">That’s all. Hope you enjoyed the content. Please don’t forget to follow me for more like this and <span style="font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; letter-spacing: -0.06px;">like/comment </span>for it. Happy programming.</span></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-59364865496292156992022-06-25T19:57:00.003+05:302022-10-27T12:05:14.524+05:30props vs emit in vue.js<p> <span style="background-color: white; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">In my last</span><span style="background-color: white; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;"> </span><a class="au kd" href="https://binodmahto.blogspot.com/2022/06/data-vs-props-and-methods-vs-computed.html" rel="noopener" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">article here</a><span style="background-color: white; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;"> </span><span style="background-color: white; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">, I tried to explain about data(), props, methods and components. Here I’m gonna explain about emit function of vue.js.</span></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="bdd2" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">From the last article we understood the concept behind props and the usage of it. In short props helps to pass the information from parent to child but not vice versa, so what should do if we need to pass information back to parent(caller) from the child component. This is where emit function helps us.</p><blockquote class="ke kf kg" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="jf jg kh jh b ji jj jk jl jm jn jo jp ki jr js jt kj jv jw jx kk jz ka kb kc ib gj" data-selectable-paragraph="" id="c8a8" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">$emit function emit or send custom events to it’s parent.</p></blockquote><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="1d03" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Lets see by an example, how we can do this. I’m considering a scenario here, where <em class="kh" style="box-sizing: inherit;">a child components will receive payload information from parent via props and child component will send modified value (payload) via an event back to the parent</em>.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="a057" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Creating child components names <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">MyComponent.vue</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="c7f6" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><template><br style="box-sizing: inherit;" /> <div><br style="box-sizing: inherit;" /> <input type="text" <span class="kt ij" style="box-sizing: inherit; font-weight: 700;">v-model="firstName"</span>/><br style="box-sizing: inherit;" /> <input type="text" <span class="kt ij" style="box-sizing: inherit; font-weight: 700;">v-model="lastName"</span>/><br style="box-sizing: inherit;" /> <br/><br style="box-sizing: inherit;" /> <button <a class="au kd" href="http://twitter.com/click" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">@click</a>='<span class="kt ij" style="box-sizing: inherit; font-weight: 700;">onButtonClick</span>()'><br style="box-sizing: inherit;" /> Click Me<br style="box-sizing: inherit;" /> </button><br style="box-sizing: inherit;" /> </div><br style="box-sizing: inherit;" /></template><br style="box-sizing: inherit;" /><script><br style="box-sizing: inherit;" /> export default {<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> <span class="kt ij" style="box-sizing: inherit; font-weight: 700;">props: ['firstName', 'lastName']</span>,<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> <span class="kt ij" style="box-sizing: inherit; font-weight: 700;">emits: ['onClick']</span>,<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> methods :{<br style="box-sizing: inherit;" /> onButtonClick($event){<br style="box-sizing: inherit;" /> <span class="kt ij" style="box-sizing: inherit; font-weight: 700;"> this.$emit("onClick", { fName: this.firstName, lName:this.lastName})</span>;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /></script></span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="7771" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Here in the child component, we have two text box which binds the value firstName and lastName as received from parent. There is a button which calls the method ‘onButtonClick’ on click and emit an event for parent with payload information with updated firstName and lastName.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="718b" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now let’s create the main component, <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">App.vue</span></p><pre class="kl km kn ko ga kp bt kq" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kr ks ii kt b do ku kv l kw" data-selectable-paragraph="" id="c5ff" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><script><br style="box-sizing: inherit;" /> <span class="kt ij" style="box-sizing: inherit; font-weight: 700;">import MyComp from './MyComponent.vue' //import the component</span><br style="box-sizing: inherit;" />export default {<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> components: { <br style="box-sizing: inherit;" /> <span class="kt ij" style="box-sizing: inherit; font-weight: 700;">'my-comp' : MyCompl</span> //define the component<br style="box-sizing: inherit;" /> }, <br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> data() {<br style="box-sizing: inherit;" /> return {<br style="box-sizing: inherit;" /> firstName: 'Binod',<br style="box-sizing: inherit;" /> lastName: 'Mahto',<br style="box-sizing: inherit;" /> fullName:'',<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> methods : {<br style="box-sizing: inherit;" /> <span class="kt ij" style="box-sizing: inherit; font-weight: 700;">mtdCalculateFullName</span>(<span class="kt ij" style="box-sizing: inherit; font-weight: 700;">payload</span>) {<br style="box-sizing: inherit;" /> <span class="kt ij" style="box-sizing: inherit; font-weight: 700;">this.$data.firstName = payload.fName;</span><br style="box-sizing: inherit;" /> <span class="kt ij" style="box-sizing: inherit; font-weight: 700;">this.$data.lastName = payload.lName;</span><br style="box-sizing: inherit;" /> this.$data.fullName = this.$data.firstName + ' ' + this.$data.lastName;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }, <br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /></script><br style="box-sizing: inherit;" /><template><br style="box-sizing: inherit;" /> <div><br style="box-sizing: inherit;" /> <span class="kt ij" style="box-sizing: inherit; font-weight: 700;"><my-comp :first-Name='firstName' :last-Name='lastName' </span><a class="au kd" href="http://twitter.com/on" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank"><span class="kt ij" style="box-sizing: inherit; font-weight: 700;"><em class="kh" style="box-sizing: inherit;">@on</em></span></a><span class="kt ij" style="box-sizing: inherit; font-weight: 700;"><em class="kh" style="box-sizing: inherit;">-Click='mtdCalculateFullName'</em>></my-comp></span><br style="box-sizing: inherit;" /> </div><br style="box-sizing: inherit;" /> <div><br style="box-sizing: inherit;" /> <p>Full Name:</p><p>{{fullName}}</p><br style="box-sizing: inherit;" /> </div><br style="box-sizing: inherit;" /></template></span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="226e" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In above main component, I have give a name to my child component as ‘my-comp’ and in the template using the child component as <my-comp/>. This is optional and instead you can use <MyComp/> if you don’t want to give any name as I did in my last article example.<br style="box-sizing: inherit;" />Main component (parent) here binding data() function members firstName and lastName against the props <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">:first-Name=’firstName’ :last-Name=’lastName’ </span>to pass the information to child, and it also binds the emitted event by child @on-click with a method available in parent <a class="au kd" href="http://twitter.com/on" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;"><em class="kh" style="box-sizing: inherit;">@on</em></span></a><span class="jh ij" style="box-sizing: inherit; font-weight: 700;"><em class="kh" style="box-sizing: inherit;">-Click=’mtdCalculateFullName’.</em></span></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="30bb" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In result, when you click on button rendered by child component, child component will emit a event name ‘<span class="jh ij" style="box-sizing: inherit; font-weight: 700;">on-click</span>’ with updated firstName and lastName as event payload to the parent. if you run the example, your output would be as:</p><figure class="kl km kn ko ga ky fo fp paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="fo fp kx" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 557px;"><img alt="" class="cf kz la" height="239" loading="lazy" role="presentation" src="https://miro.medium.com/max/1114/1*aUF3bTsWc4r3gqX8r05gow.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 557px;" width="557" /></div></figure><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="01c4" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Conclusion:</span></p><blockquote class="ke kf kg" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="jf jg kh jh b ji jj jk jl jm jn jo jp ki jr js jt kj jv jw jx kk jz ka kb kc ib gj" data-selectable-paragraph="" id="7367" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">props is a way to pass information from parent to child and emit function is a way to pass information back to parent from child.</p></blockquote><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="94f7" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">That’s all. Hope you enjoyed the content, don’t forget to follow me for more like this and <span style="font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; letter-spacing: -0.06px;">like/comment </span>for it please. Happy programming.</span></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="85f8" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Reference:<br style="box-sizing: inherit;" /><a class="au kd" href="https://vuejs.org/guide/introduction.html" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://vuejs.org/guide/introduction.html</a></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="b883" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Reminder once again, you don’t need any tool or install anything to try above example instead you can do this via vue’s SFC playgorund: <a class="au kd" href="https://sfc.vuejs.org/" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://sfc.vuejs.org/</a></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-26829309503358472482022-06-23T19:06:00.005+05:302022-10-27T12:05:31.290+05:30data vs props and methods vs computed in Vue.js<p> <span style="background-color: white; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">Vue.js is a versatile & popular framework for building web user interfaces. Even I feel, compare to other UI frameworks, Vue framework seems to be easier to learn & code. There are four basic & major concepts of Vue framework which often seems to be confusing from each others, specially for beginners.</span></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="6598" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">These four concepts on which entire vue page/components depends on are:<br style="box-sizing: inherit;" />1. data()<br style="box-sizing: inherit;" />2. props<br style="box-sizing: inherit;" />3. computed and<br style="box-sizing: inherit;" />4. methods</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="b2ad" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Here I’ll try to explain these concepts and also make sure there won’t be any more confusion around them to use it. For the article below, I’ll be using below example for explanation so please pay attention to it but don’t worry as I'll explain what I did here.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="32d1" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">App.vue</span></p><pre class="kd ke kf kg ga kh bt ki" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kj kk ii kl b do km kn l ko" data-selectable-paragraph="" id="2730" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><script><br style="box-sizing: inherit;" />export default {<br style="box-sizing: inherit;" /> data() {<br style="box-sizing: inherit;" /> return {<br style="box-sizing: inherit;" /> firstName: 'Binod',<br style="box-sizing: inherit;" /> lastName: 'Mahto',<br style="box-sizing: inherit;" /> fullName:'',<br style="box-sizing: inherit;" /> methodcount:0,<br style="box-sizing: inherit;" /> computedcount:0<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> methods : {<br style="box-sizing: inherit;" /> mtdCalculateFullName() {<br style="box-sizing: inherit;" /> this.$data.methodcount++;<br style="box-sizing: inherit;" /> this.$data.fullName = this.$data.firstName + ' ' + this.$data.lastName;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> computed : {<br style="box-sizing: inherit;" /> cmptCalculateFullName() {<br style="box-sizing: inherit;" /> this.$data.computedcount++;<br style="box-sizing: inherit;" /> this.$data.fullName = this.$data.firstName + ' ' + this.$data.lastName;<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /></script></span><span class="gj kj kk ii kl b do kp kq kr ks kt kn l ko" data-selectable-paragraph="" id="793e" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><template><br style="box-sizing: inherit;" /> <input type="text" v-model="firstName"><br style="box-sizing: inherit;" /> <input type="text" v-model="lastName"><br style="box-sizing: inherit;" /> <div><br style="box-sizing: inherit;" /> <button <a class="au ku" href="http://twitter.com/click" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">@click</a>='mtdCalculateFullName()'><br style="box-sizing: inherit;" /> Click Me<br style="box-sizing: inherit;" /> </button><br style="box-sizing: inherit;" /> <p>Full Name:</p><p>{{fullName}}</p><br style="box-sizing: inherit;" /> <p>count: {{methodcount}}</p><br style="box-sizing: inherit;" /> </div><br style="box-sizing: inherit;" /> <div><br style="box-sizing: inherit;" /> <button <a class="au ku" href="http://twitter.com/click" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">@click</a>='cmptCalculateFullName'><br style="box-sizing: inherit;" /> Click Me<br style="box-sizing: inherit;" /> </button><br style="box-sizing: inherit;" /> <p>Full Name:</p><p>{{fullName}}</p><br style="box-sizing: inherit;" /> <p>count: {{computedcount}}</p><br style="box-sizing: inherit;" /> </div><br style="box-sizing: inherit;" /></template></span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="645f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Let’s discuss the concepts now.</p><h2 class="kj kk ii bn kv kw kx ky kz la lb lc ld jq le lf lg ju lh li lj jy lk ll lm ln gj" data-selectable-paragraph="" id="c220" style="background-color: white; box-sizing: inherit; color: #292929; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 20px; line-height: 24px; margin: 2.37em 0px -0.31em;"><span class="lo" style="box-sizing: inherit; font-style: inherit;">data():</span></h2><p class="pw-post-body-paragraph jf jg ii jh b ji lp jk jl jm lq jo jp jq lr js jt ju ls jw jx jy lt ka kb kc ib gj" data-selectable-paragraph="" id="3ace" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 0.86em 0px -0.46em; word-break: break-word;">by definition, <em class="lu" style="box-sizing: inherit;">it is a function that returns the initial reactive state for the component instance.</em><br style="box-sizing: inherit;" />Technically it is a data placeholder which keeps the state of data throughout the component/page life cycle. For backend programmer, it is like class variables which holds the data state for the class.<br style="box-sizing: inherit;" />In above example here, I have five data members to capture the data state for my vue page and they are defined as:</p><pre class="kd ke kf kg ga kh bt ki" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kj kk ii kl b do km kn l ko" data-selectable-paragraph="" id="ae0d" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">data() {<br style="box-sizing: inherit;" /> return {<br style="box-sizing: inherit;" /> firstName: 'Binod',<br style="box-sizing: inherit;" /> lastName: 'Mahto',<br style="box-sizing: inherit;" /> fullName:'',<br style="box-sizing: inherit;" /> methodcount:0,<br style="box-sizing: inherit;" /> computedcount:0<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="8c0e" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">The syntax is like a function named ‘data()’ which returns a type holding members and it is consumed within the script as</p><pre class="kd ke kf kg ga kh bt ki" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kj kk ii kl b do km kn l ko" data-selectable-paragraph="" id="bce7" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">this.$data.{datamembername} <br style="box-sizing: inherit;" />//not necessary to use $data instead you do this.{datamembername} but i'm doing this for readability purpose.</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="779f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">This member’s value can be modified through out the page/component lifecycle and it will retain the state for the same. In my example, I’m using the same data member in UI component to bind with <input/> as well to display it in html.</p><blockquote class="lv lw lx" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="jf jg lu jh b ji jj jk jl jm jn jo jp ly jr js jt lz jv jw jx ma jz ka kb kc ib gj" data-selectable-paragraph="" id="5674" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Hence, as the name says data(), the purpose of it is to maintain the data for throughout the component life cycle.</p></blockquote><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="d96e" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">props:</span><br style="box-sizing: inherit;" />props are <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">one-way-down</span> data binding technique to bind between the child property and the parent one: when the parent property updates, it will flow down to the child, but not the other way around. Hence for the child component it is read only.<br style="box-sizing: inherit;" />For an example let’s create a reusable component which has a template to display messages passed by parent and this is what exactly the props serves.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="17ed" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Here is the component : <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">MyComp.vue</span></p><pre class="kd ke kf kg ga kh bt ki" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kj kk ii kl b do km kn l ko" data-selectable-paragraph="" id="ab57" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><template><br style="box-sizing: inherit;" /> <div><br style="box-sizing: inherit;" /> <p>{{greetingMessage}}</p><br style="box-sizing: inherit;" /> </div><br style="box-sizing: inherit;" /></template></span><span class="gj kj kk ii kl b do kp kq kr ks kt kn l ko" data-selectable-paragraph="" id="da7b" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><script><br style="box-sizing: inherit;" /> export default {<br style="box-sizing: inherit;" /> props: ['greetingMessage']<br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /></script></span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="c455" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">and use this component in parent component as:</p><pre class="kd ke kf kg ga kh bt ki" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kj kk ii kl b do km kn l ko" data-selectable-paragraph="" id="e7d0" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><script><br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /><span class="kl ij" style="box-sizing: inherit; font-weight: 700;">import MyComp from './MyComp.vue' //import it first</span></span><span class="gj kj kk ii kl b do kp kq kr ks kt kn l ko" data-selectable-paragraph="" id="c496" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">export default {<br style="box-sizing: inherit;" /> <span class="kl ij" style="box-sizing: inherit; font-weight: 700;">components: { <br style="box-sizing: inherit;" /> MyComp </span>//define the component<span class="kl ij" style="box-sizing: inherit; font-weight: 700;"><br style="box-sizing: inherit;" /> }</span>, <br style="box-sizing: inherit;" /> data() {<br style="box-sizing: inherit;" /> return {<br style="box-sizing: inherit;" /> message: 'Hi This is a message for props',<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /></script></span><span class="gj kj kk ii kl b do kp kq kr ks kt kn l ko" data-selectable-paragraph="" id="df59" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;"><template><br style="box-sizing: inherit;" /> <span class="kl ij" style="box-sizing: inherit; font-weight: 700;"> <MyComp greetingMessage ='Hi This is props'></MyComp><br style="box-sizing: inherit;" /> <MyComp greeting-Message ='Hi This is props'></MyComp><br style="box-sizing: inherit;" /> <MyComp :greeting-Message ='message'></MyComp></span><br style="box-sizing: inherit;" /> </div><br style="box-sizing: inherit;" /></template></span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="ae4f" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Above code will display the message passed by parent in the child component. Hope you noticed something here, I have used the child component in three different ways and the purpose was to make you aware so that you will not get confused.<br style="box-sizing: inherit;" />In short, from the above code <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">greeting-Message</span> (pascal case) is the standard suggested to follow to keep code inline with html syntax and when you need to bind the data member, you will have to use the props with ‘:’ as prefix i.e. <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">:greeting-Message =’message’.</span></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="5fc6" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">one more thing, if you noticed the props (you can call it property) I defined in child component, looks like an array and this is one way of defining it. Vue framework allows you to define in other way also (like an object). i.e.</p><pre class="kd ke kf kg ga kh bt ki" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kj kk ii kl b do km kn l ko" data-selectable-paragraph="" id="e1e3" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><template><br style="box-sizing: inherit;" /> <div><br style="box-sizing: inherit;" /> <p>{{greetingMessage}}</p><br style="box-sizing: inherit;" /> </div><br style="box-sizing: inherit;" /></template><br style="box-sizing: inherit;" /><script><br style="box-sizing: inherit;" /> export default {<br style="box-sizing: inherit;" /> <span class="kl ij" style="box-sizing: inherit; font-weight: 700;">props: {<br style="box-sizing: inherit;" /> greetingMessage : string,<br style="box-sizing: inherit;" /> }</span><br style="box-sizing: inherit;" />}<br style="box-sizing: inherit;" /></script></span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="1e44" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">It’s all your call, vue framework allows both. In any way, in case of complex object for props you would need the second way of declaration.</p><blockquote class="lv lw lx" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="jf jg lu jh b ji jj jk jl jm jn jo jp ly jr js jt lz jv jw jx ma jz ka kb kc ib gj" data-selectable-paragraph="" id="d95d" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="ii" style="box-sizing: inherit; font-style: normal;">Hence, props are a way of one-way data binding technique to pass value from parent to child and not vice versa.</span></p></blockquote><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="c88a" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">methods:</span><br style="box-sizing: inherit;" />methods allows you to create your re-usable functions to perform your logic. it takes parameters and returns output or void. Syntax for defining methods is:</p><pre class="kd ke kf kg ga kh bt ki" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kj kk ii kl b do km kn l ko" data-selectable-paragraph="" id="16ff" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">methods:{<br style="box-sizing: inherit;" /> mymethod1(payload: any){<br style="box-sizing: inherit;" /> //logic goes here<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> <br style="box-sizing: inherit;" /> //syntax to define async methods<br style="box-sizing: inherit;" /> async mymethod2(payload: any){<br style="box-sizing: inherit;" /> //logic goes here<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="fd89" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">In my first example, I have a method called ‘mtdCalculateFullName’ which formats the full name string and save it back to data() function member.</p><blockquote class="lv lw lx" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="jf jg lu jh b ji jj jk jl jm jn jo jp ly jr js jt lz jv jw jx ma jz ka kb kc ib gj" data-selectable-paragraph="" id="fc6c" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Hence, methods provides to define functions which perform certain action, logic etc. These functions you can call within a function or you can bind to action event also. i.e.</p></blockquote><pre class="kd ke kf kg ga kh bt ki" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kj kk ii kl b do km kn l ko" data-selectable-paragraph="" id="33ec" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><button <a class="au ku" href="http://twitter.com/click" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">@click</a>=<span class="kl ij" style="box-sizing: inherit; font-weight: 700;">'mtdCalculateFullName()'</span>></span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="d7f4" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">computed:</span><br style="box-sizing: inherit;" />This is similar to methods in terms of syntax or use but it is not really similar and <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">it has a great purpose behind it</span>. This is where most of the people get confused between methods and computed.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="4c54" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">computed allows you to define properties or methods with the reactive dependencies of the data and the output of computed property or function is cached (and will not be re-executed or calculated) until data state changes.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="932a" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Not clear, no worries, plz pay attention to my first example here (App.vue) which has a computed member (function) named ‘<em class="lu" style="box-sizing: inherit;">cmptCalculateFullName()</em>’ which formats the full name as the methods member (function) named ‘<em class="lu" style="box-sizing: inherit;">mtdCalculateFullName()</em>’ does. Both the functions increment the data variable named <em class="lu" style="box-sizing: inherit;">computedcount </em>and <em class="lu" style="box-sizing: inherit;">methodcount </em>respectively when the specific function is being called on click on respective buttons.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="9269" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">When you run the example, you will see the output as:</p><figure class="kd ke kf kg ga mc fo fp paragraph-image" style="background-color: white; box-sizing: inherit; clear: both; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 56px auto 0px;"><div class="fo fp mb" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 639px;"><img alt="" class="cf md me" height="527" loading="lazy" role="presentation" src="https://miro.medium.com/max/1278/1*1WmndEJSOm-xHl9tLyF8Ag.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 639px;" width="639" /></div></figure><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="fdb3" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">and here is the key fact: no matter how many times you are clicking the second button, count value will not change for second div unless you change the firstName and lastName from the input text box and that is the purpose of computed property or function, where as you will always see the count value increasing on click of 1st button because the methods function is being re-executed every time it is being called but computed function’s data is cached and ignore the execution unless data is changed.</p><blockquote class="lv lw lx" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="jf jg lu jh b ji jj jk jl jm jn jo jp ly jr js jt lz jv jw jx ma jz ka kb kc ib gj" data-selectable-paragraph="" id="0ddb" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Hence, computed allows you to create property or function which works with reactive dependencies of data member by caching the output until data changes.</p></blockquote><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="fdc0" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">I hope this made you clear the purpose of method and computed concepts of the vue framework. Now let me give you one simple example with respect to computed: Suppose in your application component you have data() member which is array of string data, example countries :[‘India’, ‘Japan’, …]. In your component you bind this data multiple places but by sorting it in a ascending order. So in this case, the best option to use computed member instead of method to gain the <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">performance</span>.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="3519" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">One more confusing fact, In some articles you may find people saying that, “<span class="jh ij" style="box-sizing: inherit; font-weight: 700;">computed doesn’t allow parameter but methods does allow</span>” is as one of the difference but this statement is partially true, let’s see how.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="4674" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">This is true that computed function doesn’t allow function’s input parameter but the same can be achieved through getters, setters property of computed member, here is the example:</p><pre class="kd ke kf kg ga kh bt ki" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kj kk ii kl b do km kn l ko" data-selectable-paragraph="" id="9902" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">export default {<br style="box-sizing: inherit;" /> data() {<br style="box-sizing: inherit;" /> return {<br style="box-sizing: inherit;" /> firstName: 'Binod',<br style="box-sizing: inherit;" /> lastName: 'Mahto'<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> },<br style="box-sizing: inherit;" /> computed: {<br style="box-sizing: inherit;" /> <span class="kl ij" style="box-sizing: inherit; font-weight: 700;">computedFullName</span>: {<br style="box-sizing: inherit;" /> // getter<br style="box-sizing: inherit;" /> <span class="kl ij" style="box-sizing: inherit; font-weight: 700;">get() {<br style="box-sizing: inherit;" /> return this.$data.firstName + ' ' + this.$data.lastName<br style="box-sizing: inherit;" /> },</span><br style="box-sizing: inherit;" /> // setter<br style="box-sizing: inherit;" /> <span class="kl ij" style="box-sizing: inherit; font-weight: 700;">set(newValue) {<br style="box-sizing: inherit;" /> // Note: we are using destructuring assignment syntax here.<br style="box-sizing: inherit;" /> [this.$data.firstName, this.$data.lastName] = newValue.split(' ')</span><br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="eb17" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">You can call this getters, setters as:</p><pre class="kd ke kf kg ga kh bt ki" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kj kk ii kl b do km kn l ko" data-selectable-paragraph="" id="21f2" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">this.computedFullName = 'James Bond';//to set the new value<br style="box-sizing: inherit;" />this.computedFullName; // to get the value.</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="b0f4" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Hence, though computed doesn’t allow you to do this:</p><pre class="kd ke kf kg ga kh bt ki" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kj kk ii kl b do km kn l ko" data-selectable-paragraph="" id="e44a" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">//this is not allowed<br style="box-sizing: inherit;" />computed:{<br style="box-sizing: inherit;" /> cmptCalculateFullName(payload : string)<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="b430" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">but then you have the way to achieve the same using setters:</p><pre class="kd ke kf kg ga kh bt ki" style="background: rgb(242, 242, 242); box-sizing: inherit; color: rgba(0, 0, 0, 0.8); margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kj kk ii kl b do km kn l ko" data-selectable-paragraph="" id="6444" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">computed: {<br style="box-sizing: inherit;" /> computedFullName: {<br style="box-sizing: inherit;" /> // setter<br style="box-sizing: inherit;" /> set(newValue) {<br style="box-sizing: inherit;" /> // Note: we are using destructuring assignment syntax here.<br style="box-sizing: inherit;" /> [this.$data.firstName, this.$data.lastName] = newValue.split(' ')<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }</span></pre><blockquote class="lv lw lx" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="jf jg lu jh b ji jj jk jl jm jn jo jp ly jr js jt lz jv jw jx ma jz ka kb kc ib gj" data-selectable-paragraph="" id="2e3a" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Hence saying that, computed doesn’t allow payload input parameter is partially true because though it is not possible through computed function but by computed member’s setter you can achieve the same.</p></blockquote><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="5068" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">That’s all. Hope you enjoyed the content, don’t forget to follow me for more like this and like/comment for it please. Happy programming.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="583a" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Reference:</p><div class="mf mg fw fy mh mi" style="background-color: white; box-shadow: rgb(230, 230, 230) 0px 0px 0px 1px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin-top: 32px;"><a href="https://vuejs.org/guide/introduction.html" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit; text-decoration-line: none;" target="_blank"><div class="mj o hi" style="box-sizing: inherit; display: flex; flex: 0 0 auto; padding: 0px;"><div class="mk o db dz ep ml" style="box-sizing: inherit; display: flex; flex-direction: column; flex: 1 1 auto; justify-content: center; padding: 16px 20px;"><h2 class="bn ij do bp mm mn mo mp mq mr ms ih gj" style="-webkit-box-orient: vertical; -webkit-line-clamp: 2; box-sizing: inherit; color: #292929; display: -webkit-box; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 16px; letter-spacing: 0px; line-height: 20px; margin: 0px; max-height: 40px; overflow: hidden; text-overflow: ellipsis;">Introduction | Vue.js</h2><div class="mt l" style="box-sizing: inherit; margin-top: 8px;"><h3 class="bn b do bp mm mn mo mp mq mr ms co" style="-webkit-box-orient: vertical; -webkit-line-clamp: 2; box-sizing: inherit; color: #757575; display: -webkit-box; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 16px; font-weight: 400; line-height: 20px; margin: 0px; max-height: 40px; overflow: hidden; text-overflow: ellipsis;">You are reading the documentation for Vue 3! Vue (pronounced /vjuː/, like view) is a JavaScript framework for building…</h3></div><div class="mu l" style="box-sizing: inherit; margin-top: 12px;"><p class="bn b gr bp mm mn mo mp mq mr ms co" style="-webkit-box-orient: vertical; -webkit-line-clamp: 2; box-sizing: inherit; color: #757575; display: -webkit-box; font-family: sohne, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; line-height: 20px; margin: 0px; max-height: 40px; overflow: hidden; text-overflow: ellipsis;">vuejs.org</p></div></div><div class="mv l" style="box-sizing: inherit; width: 160px;"><div class="mw l mx my mz mv na md mi" style="background-image: url("https://miro.medium.com/max/320/0*PaVfAh6dqlEsh0ON"); background-origin: border-box; background-position: 50% 50%; background-size: cover; box-shadow: rgb(230, 230, 230) 0px 0px 0px 1px inset; box-sizing: inherit; height: 167px; max-width: 100%; width: 160px;"></div></div></div></a></div><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="aa51" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Also, you don’t need any tool or to install anything, to try above example instead you can do this via vue’s SFC playgorund: <a class="au ku" href="https://sfc.vuejs.org/" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://sfc.vuejs.org/</a></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-7037196914423635422022-06-02T16:22:00.003+05:302022-10-27T12:05:50.529+05:30Clean Code Architecture with Mediator & CQRS pattern in .Net Core<p> <span style="color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">May be for some of you, The Mediator pattern is known but here my focus is to using the</span><span style="color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;"> </span><span class="jh ij" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; font-weight: 700; letter-spacing: -0.003em;">Mediator </span><span style="color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">pattern with CQRS (</span><span class="jh ij" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; font-weight: 700; letter-spacing: -0.003em;">Command and Query Responsibility Segregation</span><span style="color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">) pattern to make our .net core (API or web) code cleaner, extensible and maintainable.</span></p><div class="o dz" style="box-sizing: inherit; display: flex; justify-content: center;"><div class="eo cf fa fb fc fd fe ff fg fh fi" style="box-sizing: inherit; margin: 0px 32px; max-width: 692px; min-width: 0px; width: 692px;"><article style="box-sizing: inherit;"><div class="l" style="box-sizing: inherit;"><div class="l" style="box-sizing: inherit;"><section style="box-sizing: inherit;"><div style="box-sizing: inherit;"><div class="ib ic id ie if" style="box-sizing: inherit; overflow-wrap: break-word; word-break: break-word;"><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="8334" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">We often see, In complex project when the dependencies are increased then our controller gets overloaded and tightly coupled with dependent services while using the built-in IoC container provided by ASP.NET Core.<br style="box-sizing: inherit;" />Take a scenario example as Loan Application approval process. In this case, loan approval has to go through various process such as:<br style="box-sizing: inherit;" />1. CIBIL Score checks: ; 2. Employment Status check: ; 3. Account Details validation: ; 4. Payment History: ; 5. EMI to Income Ratio check etc.<br style="box-sizing: inherit;" />And assume in this case, all five processes are as different services and we have a web api endpoint loan application approval process to perform the loan approval. Our code will look like this:</p><pre class="kd ke kf kg ga kh bt ki" style="background: rgb(242, 242, 242); box-sizing: inherit; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kj kk ii kl b do km kn l ko" data-selectable-paragraph="" id="05ca" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">[ApiController]<br style="box-sizing: inherit;" /> [Route("[controller]")]<br style="box-sizing: inherit;" /> public class LoanProcessController : ControllerBase<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> private ICibilService _cibilService;<br style="box-sizing: inherit;" /> private IEmploymentService _employmentService;<br style="box-sizing: inherit;" /> private IAccountService _employmentService;<br style="box-sizing: inherit;" /> private IPaymentService _paymentService;<br style="box-sizing: inherit;" /> private IEMIService _emiService;</span><span class="gj kj kk ii kl b do kp kq kr ks kt kn l ko" data-selectable-paragraph="" id="29d4" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">public LoanProcessController(ICibilService cibilService, <br style="box-sizing: inherit;" /> IEmploymentService employmentService,<br style="box-sizing: inherit;" /> IAccountService accountService,<br style="box-sizing: inherit;" /> IPaymentService paymentService,<br style="box-sizing: inherit;" /> IEMIService emiService)<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> _cibilService = cibilService;<br style="box-sizing: inherit;" /> _employmentService = employmentService;<br style="box-sizing: inherit;" /> _accountService = accountService;<br style="box-sizing: inherit;" /> _paymentService = paymentService;<br style="box-sizing: inherit;" /> _emiService = emiService;<br style="box-sizing: inherit;" /> }</span><span class="gj kj kk ii kl b do kp kq kr ks kt kn l ko" data-selectable-paragraph="" id="6fb9" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">[HttpGet(Name = "GetWeatherForecast")]<br style="box-sizing: inherit;" /> public async Task<IEnumerable<LoanApplication>> ApproveLoan()<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> _cibilService.ValidateCibilScore();<br style="box-sizing: inherit;" /> _employmentService.ValidateEmployeeStatus();<br style="box-sizing: inherit;" /> _accountService.ValidateAccount();<br style="box-sizing: inherit;" /> _paymentService.ValidatePaymentHistory();<br style="box-sizing: inherit;" /> __emiService.ValidatePaymentEMIPaymentRatio();<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="6e5d" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">This is where we need a mediator to decouple the multiple services dependencies on controller. Hence the above code must be refactored using mediator pattern and it should be like as:</p><figure class="kd ke kf kg ga kv fo fp paragraph-image" style="box-sizing: inherit; clear: both; margin: 56px auto 0px;"><div class="kw kx dq ky cf kz" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 692px; z-index: auto;" tabindex="0"><div class="fo fp ku" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 1010px;"><img alt="" class="cf la lb" height="344" role="presentation" src="https://miro.medium.com/max/1400/1*yRrUOD8V6HnI23RhGZrm6w.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 692px;" width="700" /></div></div></figure><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="1eb3" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Seems easy going in implementation but this become more easy to implement with <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">MediatR Extensions for Microsoft Dependency Injection with CQRS pattern.</span></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="b67a" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Pardon me as I’m going to show you a simple example instead of creating a big example to depict the above scenario. Here I’m going to tweak the weather forecast sample application to demonstrate the mediator pattern with CQRS.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="f320" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">To follow me with this example, create a web api project using the web api template in .Net 6. This template will create weather forecast api for you and then lets follow the below steps to implement <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">MediatR with CQRS </span>to retrieve the weather forecast<span class="jh ij" style="box-sizing: inherit; font-weight: 700;">.</span></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="a97a" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 1:</span> Install the <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">MediatR </span>nugets.</p><figure class="kd ke kf kg ga kv fo fp paragraph-image" style="box-sizing: inherit; clear: both; margin: 56px auto 0px;"><div class="kw kx dq ky cf kz" role="button" style="box-sizing: inherit; cursor: zoom-in; position: relative; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s; width: 692px; z-index: auto;" tabindex="0"><div class="fo fp lc" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 708px;"><img alt="" class="cf la lb" height="224" role="presentation" src="https://miro.medium.com/max/1400/1*YNyiNTp0FMI0ASs6iHG4OQ.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 692px;" width="700" /></div></div></figure><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="2b8a" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 2:</span> Create the <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">CQRS </span>folder structure to separate our your commands and queries related classes.</p><figure class="kd ke kf kg ga kv fo fp paragraph-image" style="box-sizing: inherit; clear: both; margin: 56px auto 0px;"><div class="fo fp ld" style="box-sizing: inherit; margin-left: auto; margin-right: auto; max-width: 466px;"><img alt="" class="cf la lb" height="447" role="presentation" src="https://miro.medium.com/max/932/1*W3lua6g4uJI9geSK3p2zVA.png" style="box-sizing: inherit; height: auto; max-width: 100%; vertical-align: middle; width: 466px;" width="466" /></div></figure><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="b2c6" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Command </span>folder is for commands related to state change operations like create, update, delete etc.<br style="box-sizing: inherit;" />and the <span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Query </span>folder is for queries requests like read which in general doesn’t change the state of data.</p><blockquote class="le lf lg" style="box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="jf jg lh jh b ji jj jk jl jm jn jo jp li jr js jt lj jv jw jx lk jz ka kb kc ib gj" data-selectable-paragraph="" id="43ae" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">“Based on our above loan approval, probably CQRS pattern would be overthought pattern hence can be avoided simply and steak to mediator pattern only.</p></blockquote><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="61db" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 3:</span> Register the mediatR service</p><pre class="kd ke kf kg ga kh bt ki" style="background: rgb(242, 242, 242); box-sizing: inherit; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kj kk ii kl b do km kn l ko" data-selectable-paragraph="" id="649b" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;"><span class="kl ij" style="box-sizing: inherit; font-weight: 700;">builder.Services.AddMediatR(Assembly.GetExecutingAssembly());</span></span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="72f3" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 4:</span> Create query request and handler</p><pre class="kd ke kf kg ga kh bt ki" style="background: rgb(242, 242, 242); box-sizing: inherit; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kj kk ii kl b do km kn l ko" data-selectable-paragraph="" id="1d40" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">using MediatR;</span><span class="gj kj kk ii kl b do kp kq kr ks kt kn l ko" data-selectable-paragraph="" id="165f" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">namespace CQRSWebAPIDemo.CQRS.Query<br style="box-sizing: inherit;" />{<br style="box-sizing: inherit;" /> public class <span class="kl ij" style="box-sizing: inherit; font-weight: 700;">GetWeatherForecastQueryRequest </span>: <span class="kl ij" style="box-sizing: inherit; font-weight: 700;">IRequest<IEnumerable<WeatherForecast>></span><br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> private static readonly string[] Summaries = new[]{<br style="box-sizing: inherit;" /> "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"<br style="box-sizing: inherit;" /> };<br style="box-sizing: inherit;" /> <span class="kl ij" style="box-sizing: inherit; font-weight: 700;"><em class="lh" style="box-sizing: inherit;">public DateTime DateTime { get; set; }</em></span></span><span class="gj kj kk ii kl b do kp kq kr ks kt kn l ko" data-selectable-paragraph="" id="60f8" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">public class <span class="kl ij" style="box-sizing: inherit; font-weight: 700;">GetWeatherForecastQueryHandler </span>: <span class="kl ij" style="box-sizing: inherit; font-weight: 700;">IRequestHandler<GetWeatherForecastQueryRequest, IEnumerable<WeatherForecast>></span><br style="box-sizing: inherit;" /> { <br style="box-sizing: inherit;" /> private ILogger<GetWeatherForecastQueryHandler> _logger;</span><span class="gj kj kk ii kl b do kp kq kr ks kt kn l ko" data-selectable-paragraph="" id="a9a3" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">public GetWeatherForecastQueryHandler(ILogger<GetWeatherForecastQueryHandler> logger)<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> _logger = logger;<br style="box-sizing: inherit;" /> }</span><span class="gj kj kk ii kl b do kp kq kr ks kt kn l ko" data-selectable-paragraph="" id="c620" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">public async Task<IEnumerable<WeatherForecast>> Handle(GetWeatherForecastQueryRequest query, CancellationToken cancellationToken)<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> var dateTime = query.DateTime;<br style="box-sizing: inherit;" /> return Enumerable.Range(1, 5).Select(index => new WeatherForecast<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> Date = dateTime.AddDays(index),<br style="box-sizing: inherit;" /> TemperatureC = Random.Shared.Next(-20, 55),<br style="box-sizing: inherit;" /> Summary = Summaries[Random.Shared.Next(Summaries.Length)]<br style="box-sizing: inherit;" /> }).ToArray();<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> } <br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="3dde" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Syntax for creating a Query or command request is as:<br style="box-sizing: inherit;" /><span class="jh ij" style="box-sizing: inherit; font-weight: 700;"><em class="lh" style="box-sizing: inherit;">public class {Command_Query_request_name} : IRequest<{response_type}><br style="box-sizing: inherit;" /></em></span>you should define all your request parameter here, for an example purpose I have added DateTime for request as input.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="3eeb" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">similarly the syntax for command handler is as:<br style="box-sizing: inherit;" /><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">public class {handler_Name} : IRequestHandler<{<em class="lh" style="box-sizing: inherit;">Command_Query_request_name type}, {response_type}></em></span></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="33f7" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 5:</span> Go to WeatherForecast controller and modify the code to call through mediator command.</p><pre class="kd ke kf kg ga kh bt ki" style="background: rgb(242, 242, 242); box-sizing: inherit; margin-bottom: 0px; margin-top: 56px; overflow-x: auto; padding: 20px;"><span class="gj kj kk ii kl b do km kn l ko" data-selectable-paragraph="" id="31cf" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: -0.09em; white-space: pre-wrap;">using CQRSWebAPIDemo.CQRS.Query;<br style="box-sizing: inherit;" /><span class="kl ij" style="box-sizing: inherit; font-weight: 700;">using MediatR;</span><br style="box-sizing: inherit;" />using Microsoft.AspNetCore.Mvc;</span><span class="gj kj kk ii kl b do kp kq kr ks kt kn l ko" data-selectable-paragraph="" id="c44a" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">namespace CQRSWebAPIDemo.Controllers<br style="box-sizing: inherit;" />{<br style="box-sizing: inherit;" /> [ApiController]<br style="box-sizing: inherit;" /> [Route("[controller]")]<br style="box-sizing: inherit;" /> public class WeatherForecastController : ControllerBase<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> private readonly ILogger<WeatherForecastController> _logger;<br style="box-sizing: inherit;" /> <span class="kl ij" style="box-sizing: inherit; font-weight: 700;"> private IMediator _mediator;</span></span><span class="gj kj kk ii kl b do kp kq kr ks kt kn l ko" data-selectable-paragraph="" id="8fce" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">public WeatherForecastController(<span class="kl ij" style="box-sizing: inherit; font-weight: 700;">IMediator mediator, </span>ILogger<WeatherForecastController> logger)<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> _logger = logger;<br style="box-sizing: inherit;" /> <span class="kl ij" style="box-sizing: inherit; font-weight: 700;"> _mediator = mediator;</span><br style="box-sizing: inherit;" /> }</span><span class="gj kj kk ii kl b do kp kq kr ks kt kn l ko" data-selectable-paragraph="" id="c1de" style="box-sizing: inherit; color: #292929; display: block; font-family: Menlo, Monaco, "Courier New", Courier, monospace; font-size: 16px; letter-spacing: -0.022em; line-height: 1.18; margin-bottom: -0.09em; margin-top: 1.91em; white-space: pre-wrap;">[HttpGet(Name = "GetWeatherForecast")]<br style="box-sizing: inherit;" /> public async Task<IEnumerable<WeatherForecast>> Get()<br style="box-sizing: inherit;" /> {<br style="box-sizing: inherit;" /> <span class="kl ij" style="box-sizing: inherit; font-weight: 700;"> return await _mediator.Send(new GetWeatherForecastQueryRequest { DateTime = DateTime.Now });</span><br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" /> }<br style="box-sizing: inherit;" />}</span></pre><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="828f" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Step 6: </span>We are done, You can now run and validate.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="9084" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jh ij" style="box-sizing: inherit; font-weight: 700;">Conclusion</span>:<br style="box-sizing: inherit;" />The mediator pattern with CQRS structure is a great pattern to reduce the dependencies and make code clean within your application which helps you to reuse your components and also to keep you in line with the Single Responsible Principle.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="3981" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">You can also use the Command process pipeline using Mediator pattern to invoke a command handler. Or you can use messaging service as part of pipeline too for microservice api architecture design.</p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="b75c" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Reference:<br style="box-sizing: inherit;" /><a class="au ll" href="https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/microservice-application-layer-implementation-web-api" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/microservice-application-layer-implementation-web-api</a></p><p class="pw-post-body-paragraph jf jg ii jh b ji jj jk jl jm jn jo jp jq jr js jt ju jv jw jx jy jz ka kb kc ib gj" data-selectable-paragraph="" id="0fe1" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Hope you like it, Don’t forget to like/comment and follow me to get more like this. Thank You.</p></div></div></section></div></div></article><div class="lm o" style="box-sizing: inherit; display: flex; padding: 16px 0px 0px;"></div></div></div><div style="box-sizing: inherit;"></div><div class="dc ln o dz lo lp" style="bottom: 16px; box-sizing: inherit; display: flex; justify-content: center; opacity: 1; position: sticky; transition: opacity 300ms ease 0s;"><div class="lq eb lr ls lt o ao c" style="align-items: center; background-color: white; border-radius: 20px; border: none; box-shadow: rgba(0, 0, 0, 0.1) 0px 2px 10px 0px; box-sizing: inherit; display: flex; height: 40px; padding: 0px 14px 0px 16px;"><div class="o ao gl" style="align-items: center; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); display: flex; flex-direction: row; font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;"><div class="pw-multi-vote-icon dq tc lv lw lx" style="box-sizing: inherit; margin-right: 0px; position: relative; user-select: none;"><div style="box-sizing: inherit;"><div style="box-sizing: inherit;"><div aria-describedby="289" aria-hidden="false" aria-labelledby="289" class="cj" style="box-sizing: inherit; display: inline-block;"><div class="dt td dg lz ma mb mc bb md me mf lx" style="border: 0px; box-sizing: inherit; cursor: not-allowed; fill: rgb(117, 117, 117); opacity: 0.25; outline: 0px; padding: 0px; user-select: none;"><svg aria-label="clap" height="24" viewbox="0 0 24 24" width="24"><path clip-rule="evenodd" d="M11.37.83L12 3.28l.63-2.45h-1.26zM15.42 1.84l-1.18-.39-.34 2.5 1.52-2.1zM9.76 1.45l-1.19.4 1.53 2.1-.34-2.5zM20.25 11.84l-2.5-4.4a1.42 1.42 0 0 0-.93-.64.96.96 0 0 0-.75.18c-.25.19-.4.42-.45.7l.05.05 2.35 4.13c1.62 2.95 1.1 5.78-1.52 8.4l-.46.41c1-.13 1.93-.6 2.78-1.45 2.7-2.7 2.51-5.59 1.43-7.38zM12.07 9.01c-.13-.69.08-1.3.57-1.77l-2.06-2.07a1.12 1.12 0 0 0-1.56 0c-.15.15-.22.34-.27.53L12.07 9z" fill-rule="evenodd"></path><path clip-rule="evenodd" d="M14.74 8.3a1.13 1.13 0 0 0-.73-.5.67.67 0 0 0-.53.13c-.15.12-.59.46-.2 1.3l1.18 2.5a.45.45 0 0 1-.23.76.44.44 0 0 1-.48-.25L7.6 6.11a.82.82 0 1 0-1.15 1.15l3.64 3.64a.45.45 0 1 1-.63.63L5.83 7.9 4.8 6.86a.82.82 0 0 0-1.33.9c.04.1.1.18.18.26l1.02 1.03 3.65 3.64a.44.44 0 0 1-.15.73.44.44 0 0 1-.48-.1L4.05 9.68a.82.82 0 0 0-1.4.57.81.81 0 0 0 .24.58l1.53 1.54 2.3 2.28a.45.45 0 0 1-.64.63L3.8 13a.81.81 0 0 0-1.39.57c0 .22.09.43.24.58l4.4 4.4c2.8 2.8 5.5 4.12 8.68.94 2.27-2.28 2.71-4.6 1.34-7.1l-2.32-4.08z" fill-rule="evenodd"></path></svg></div></div></div></div></div></div></div></div>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0tag:blogger.com,1999:blog-3429466238827610100.post-65385854749437811992022-04-20T15:41:00.002+05:302022-10-27T12:06:31.713+05:30Choose your SQL Database option on Azure<p> <span style="background-color: white; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em;">Microsoft Azure provides various option for SQL Database on Azure platform and it is often confusing what to choose when. Here I’ll be trying to answer the questions and help you to choose the right SQL database on Azure.</span></p><p class="pw-post-body-paragraph iz ja ic jb b jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw hv gp" data-selectable-paragraph="" id="ebd0" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Microsoft provide below options for SQL Database options on Azure Platform:</p><ol style="background-color: white; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; list-style: none none; margin: 0px; padding: 0px;"><li class="jx jy ic jb b jc jd jg jh jk jz jo ka js kb jw kc kd ke kf gp" data-selectable-paragraph="" id="43fe" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 2.14em; padding-left: 0px;"><em class="kg" style="box-sizing: inherit;">SQL Server on Azure VMs</em></li><li class="jx jy ic jb b jc kh jg ki jk kj jo kk js kl jw kc kd ke kf gp" data-selectable-paragraph="" id="1cd2" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;"><em class="kg" style="box-sizing: inherit;">SQL Server Managed instances:<br style="box-sizing: inherit;" />- Single Instance<br style="box-sizing: inherit;" />- Instance Pool</em></li><li class="jx jy ic jb b jc kh jg ki jk kj jo kk js kl jw kc kd ke kf gp" data-selectable-paragraph="" id="dfb6" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 28px; list-style-type: decimal; margin-bottom: -0.46em; margin-left: 30px; margin-top: 1.14em; padding-left: 0px;"><em class="kg" style="box-sizing: inherit;">Azure SQL:<br style="box-sizing: inherit;" />- Single Database<br style="box-sizing: inherit;" />- Elastic Pool</em></li></ol><p class="pw-post-body-paragraph iz ja ic jb b jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw hv gp" data-selectable-paragraph="" id="ded1" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">Now lets see what has been offered with these different options.</p><p class="pw-post-body-paragraph iz ja ic jb b jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw hv gp" data-selectable-paragraph="" id="ed9c" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jb id" style="box-sizing: inherit; font-weight: 700;">Azure SQL Database</span><br style="box-sizing: inherit;" />A PaaS deployment option and it is a highly scalable, intelligent, relational database service built for the cloud with the industry’s highest availability SL of 99.995% and huge database storage up to 100 TB.. It is best to support modern cloud applications on an intelligent, managed database service, that includes server less compute.</p><p class="pw-post-body-paragraph iz ja ic jb b jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw hv gp" data-selectable-paragraph="" id="95f8" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">What you won’t have with this options are:<br style="box-sizing: inherit;" />- <em class="kg" style="box-sizing: inherit;">No Backup commands supported</em> but you have Automatic Backup options from Azure.<br style="box-sizing: inherit;" />- <em class="kg" style="box-sizing: inherit;">Common Language Runtime (CLR) not supported</em>.<br style="box-sizing: inherit;" />- <em class="kg" style="box-sizing: inherit;">Linked Server (Cross-database queries or transactions) not supported.</em><br style="box-sizing: inherit;" />- <em class="kg" style="box-sizing: inherit;">Database Mirroring and snapshots features are not supported.</em><br style="box-sizing: inherit;" />- <em class="kg" style="box-sizing: inherit;">No Event Notification but you can set Alerts</em><br style="box-sizing: inherit;" />- <em class="kg" style="box-sizing: inherit;">Extended Stored Procedures are not supported. </em>Anyway this feature will be removed from future version of SQL Servers so not expecting it to be here too, by the way CLR integration is an alternative here but that too not supported in this version.<br style="box-sizing: inherit;" />- <em class="kg" style="box-sizing: inherit;">Filestream not supported</em>. This features enables SQL Server-based applications to store unstructured data, such as documents and images, on the file system.<br style="box-sizing: inherit;" />- <em class="kg" style="box-sizing: inherit;">Time Zone Choice is not available</em> if you are looking for it and it obvious as it is fully managed resource.<br style="box-sizing: inherit;" />- <em class="kg" style="box-sizing: inherit;">SQL Server Profiler</em> is not available but Extended events are available as an alternatives<br style="box-sizing: inherit;" />- <em class="kg" style="box-sizing: inherit;">Machine Learning Services </em>are not supported.<br style="box-sizing: inherit;" />- No Attaching/De-attaching database feature.</p><p class="pw-post-body-paragraph iz ja ic jb b jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw hv gp" data-selectable-paragraph="" id="175b" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">There are other features too which are not available but I’m mentioning above as these are the important feature which can help you on decision making.</p><p class="pw-post-body-paragraph iz ja ic jb b jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw hv gp" data-selectable-paragraph="" id="c573" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><em class="kg" style="box-sizing: inherit;">Elastic pool: In Azure SQL database you can set Elastic Pool which will enable you to buy a set of compute and storage resources that are shared among all the databases in the pool. Each database can use the resources they need, within the limits you set, depending on current load.</em></p><p class="pw-post-body-paragraph iz ja ic jb b jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw hv gp" data-selectable-paragraph="" id="b718" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jb id" style="box-sizing: inherit; font-weight: 700;">SQL Server Managed Instances<br style="box-sizing: inherit;" /></span>This also a PaaS deployment option of Azure SQL and provides an instance of SQL Server, but removes much of the overhead of managing a virtual machine. Most of the features available in SQL Server are available in SQL Managed Instance.</p><p class="pw-post-body-paragraph iz ja ic jb b jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw hv gp" data-selectable-paragraph="" id="41bb" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">SQL Managed Instance is ideal for customers who want to use instance-scoped features and want to move to Azure without re-architecting their applications.</p><p class="pw-post-body-paragraph iz ja ic jb b jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw hv gp" data-selectable-paragraph="" id="b399" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">SQL Managed Instance instance-scoped features include:<br style="box-sizing: inherit;" /><em class="kg" style="box-sizing: inherit;">- SQL Server Agent<br style="box-sizing: inherit;" />- Service Broker<br style="box-sizing: inherit;" />- CLR<br style="box-sizing: inherit;" />- Database Mail<br style="box-sizing: inherit;" />- Linked Servers<br style="box-sizing: inherit;" />- Distributed Transactions (currently in Preview in the time of this article)<br style="box-sizing: inherit;" />- Machine Learning Services</em></p><p class="pw-post-body-paragraph iz ja ic jb b jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw hv gp" data-selectable-paragraph="" id="52b2" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">What are not supported compare to Azure SQL Instance:<br style="box-sizing: inherit;" />-<em class="kg" style="box-sizing: inherit;"> Filestream<br style="box-sizing: inherit;" />- No Attaching/De-attaching database feature.<br style="box-sizing: inherit;" />- Database Mirroring and snapshots features are not supported.<br style="box-sizing: inherit;" />- Event Notifications<br style="box-sizing: inherit;" />- Extended stored procedures</em></p><p class="pw-post-body-paragraph iz ja ic jb b jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw hv gp" data-selectable-paragraph="" id="5958" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><em class="kg" style="box-sizing: inherit;">And the most important point to note here is, Azure SQL Server managed instances supports databases up to 16 TB only.</em></p><blockquote class="km kn ko" style="background-color: white; box-shadow: rgb(41, 41, 41) 3px 0px 0px 0px inset; box-sizing: inherit; color: rgba(0, 0, 0, 0.8); font-family: medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; margin: 0px 0px 0px -20px; padding-left: 23px;"><p class="iz ja kg jb b jc jd je jf jg jh ji jj kp jl jm jn kq jp jq jr kr jt ju jv jw hv gp" data-selectable-paragraph="" id="6b71" style="box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 21px; font-style: italic; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">With <span class="jb id" style="box-sizing: inherit; font-weight: 700;">Azure SQL </span>and <span class="jb id" style="box-sizing: inherit; font-weight: 700;">Azure SQL Managed Instance</span>, the database software is automatically configured, patched, and upgraded by Azure, which reduces your administration costs. In addition, its <a class="au ks" href="https://docs.microsoft.com/en-us/azure/azure-sql/database/automated-backups-overview" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">built-in backup</a> capabilities help you achieve significant cost savings, especially when you have a large number of databases.</p></blockquote><p class="pw-post-body-paragraph iz ja ic jb b jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw hv gp" data-selectable-paragraph="" id="279a" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jb id" style="box-sizing: inherit; font-weight: 700;">SQL Server on Azure VMs<br style="box-sizing: inherit;" /></span>It is a version of SQL Server that runs on Azure VM instead of your on-prem server. So you have all the capabilities offered by SQL Server in this case.</p><p class="pw-post-body-paragraph iz ja ic jb b jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw hv gp" data-selectable-paragraph="" id="2419" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">SQL Server on Azure VMs gives you full control including OS control like on-prem infrastructure.</p><p class="pw-post-body-paragraph iz ja ic jb b jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw hv gp" data-selectable-paragraph="" id="2363" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><em class="kg" style="box-sizing: inherit;">Now lets conclude the options, when to choose what.</em></p><p class="pw-post-body-paragraph iz ja ic jb b jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw hv gp" data-selectable-paragraph="" id="254b" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span class="jb id" style="box-sizing: inherit; font-weight: 700;">SQL Server on Azure VMs :</span> When considering migrations and applications requiring OS level access.<br style="box-sizing: inherit;" /><span class="jb id" style="box-sizing: inherit; font-weight: 700;">SQL Server Managed Instances :</span> When considering Lift and Shift migrations to the cloud.<br style="box-sizing: inherit;" /><span class="jb id" style="box-sizing: inherit; font-weight: 700;">Azure SQL :</span> When considering modern cloud applications solution.</p><p class="pw-post-body-paragraph iz ja ic jb b jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw hv gp" data-selectable-paragraph="" id="6779" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;">To know more about features comparison read here <a class="au ks" href="https://docs.microsoft.com/en-us/azure/azure-sql/database/features-comparison" rel="noopener ugc nofollow" style="-webkit-tap-highlight-color: transparent; box-sizing: inherit;" target="_blank">Azure SQL Database and Azure SQL Managed Instance</a>.</p><p class="pw-post-body-paragraph iz ja ic jb b jc jd je jf jg jh ji jj jk jl jm jn jo jp jq jr js jt ju jv jw hv gp" data-selectable-paragraph="" id="69f4" style="background-color: white; box-sizing: inherit; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.003em; line-height: 32px; margin: 2em 0px -0.46em; word-break: break-word;"><span style="font-family: source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif; font-weight: 700; letter-spacing: -0.06px;">Hope you enjoyed the content, follow me for more like this and please don’t forget to like/comment for it. Happy programming.</span></p>Binod Mahto (Full Stack Solution Architect)http://www.blogger.com/profile/05631580893744334543noreply@blogger.com0