<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Blog by Bruno Câmara]]></title><description><![CDATA[Blog by Bruno Câmara]]></description><link>http://github.com/dylang/node-rss</link><generator>GatsbyJS</generator><lastBuildDate>Sat, 28 Mar 2026 04:17:48 GMT</lastBuildDate><item><title><![CDATA[Exploring AWS WAF rules with OWASP Juice Shop]]></title><description><![CDATA[In this blog post I will show how can we explore AWS WAF rules easily with the OWASP Juice Shop vulnerable app.
]]></description><link>https://bfcamara.com/posts/aws-waf-owasp-juice-shop</link><guid isPermaLink="false">https://bfcamara.com/posts/aws-waf-owasp-juice-shop</guid><pubDate>Mon, 04 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: Consider seriously using a WAF in front of your public web apps/APIs. Also, consider educating your developers about the OWASP Top 10 security list.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;When we expose our web applications or APIs to the internet, we are exposing the
features that add value to our customers, but we are also exposing our
applications vulnerabilities ready to be exploited. &lt;strong&gt;We need to be prepared to
cope with malicious actors&lt;/strong&gt;. We should do our best and use the best tools to
prevent a cyber attack. This is even more true when we expose an app that we
don’t know in detail. Imagine a company that has just acquired another company
and the due diligence during the acquisition didn’t include a legacy web app
that is being exposed to its customers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;We don’t know how vulnerable the app is until we do some exploratory work,
penetration testing, code reviews, threat modelling analysis, etc&lt;/strong&gt;. Probably it’s a legacy
app that nobody touches for years and that has some security holes which can be
exploited by a threat actor.&lt;/p&gt;
&lt;h2 id=&quot;web-application-firewall-waf&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#web-application-firewall-waf&quot; aria-label=&quot;web application firewall waf permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Web Application Firewall (WAF)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;As a first line of defense, we can use a Web Application Firewall (WAF)&lt;/strong&gt;.
Basically a WAF protects web apps/APIs by inspecting HTTP requests. It acts at
the layer 7 (Application Layer of the &lt;a href=&quot;https://www.fortinet.com/resources/cyberglossary/osi-model&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;OSI
Model&lt;/a&gt;) and it
behaves like a reverse proxy with policies and rules attached to it to protect
malicious requests, preventing them to flow to our servers or services. Using
a &lt;strong&gt;WAF doesn’t replace other initiatives that we should be doing in our apps
such as code reviews, penetration tests, threat modelling analysis, etc&lt;/strong&gt;. And
most of all, &lt;strong&gt;using a WAF doesn’t mean that we don’t need to adopt security
engineering practices while writing or deploying our apps&lt;/strong&gt;. At the end of the
day, a WAF is just one more tool at our disposal that we can use to make the
life of a threat actor harder.&lt;/p&gt;
&lt;p&gt;There are several WAFs we can use, but if our workloads are running in AWS, the
natural choice is to use &lt;a href=&quot;https://aws.amazon.com/waf/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;AWS WAF&lt;/a&gt;. This is not
mandatory. In a previous company I worked for, we were using &lt;a href=&quot;https://developers.cloudflare.com/waf/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Cloudflare
WAF&lt;/a&gt; in front of our AWS and Azure
public workloads.&lt;/p&gt;
&lt;p&gt;When we start using a WAF in front of our apps, it’s normal that we break some
functionality because we start blocking some requests that WAF considers
potential malicious, even if they are legit. We should test our apps and select
and tweak the WAF rules that must be applied to our web app or API.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;We should never forget that a WAF is just the first line of defense - our app
should be written with security in mind and assuming breach (&lt;a href=&quot;https://learn.microsoft.com/en-us/security/zero-trust/zero-trust-overview&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Zero
Trust&lt;/a&gt;),
and we have to protect it against malicious actors.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;owasp-top-10&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#owasp-top-10&quot; aria-label=&quot;owasp top 10 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;OWASP Top 10&lt;/h2&gt;
&lt;p&gt;As developers we should be aware of the &lt;a href=&quot;https://owasp.org/www-project-top-ten/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;OWASP Top
10&lt;/a&gt;, which represents &lt;strong&gt;the list of the
most critical security risks to web applications&lt;/strong&gt;. I would say that it consists
of the top 10 concerns that we, developers, should have on our head when
developing and writing our apps. (Broken access control, Injection, Cryptographic
failures, etc.).&lt;/p&gt;
&lt;p&gt;When developing features, developers are so focused on the feature itself that
sometimes they forget to add some security checks. That’s when we typically
introduce vulnerabilities without even noticing. If we have &lt;strong&gt;a code review
process in place, we can minimize these risks by having team mates reviewing our
pull request and signing off. If we have CI/CD pipelines that run security
checks on each change before deploying into production, and prevents deployment
if it detects critical or high risk vulnerabilities, even better&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In this post, I don’t want to go into the details of the OWASP Top 10 list. I
just want to show a possible setup for developers to be able to explore AWS WAF
to protect against these risks. To start exploring WAF, we need a vulnerable app
to serve as a playground.&lt;/p&gt;
&lt;h2 id=&quot;owasp-juice-shop&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#owasp-juice-shop&quot; aria-label=&quot;owasp juice shop permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;OWASP Juice Shop&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://owasp.org/www-project-juice-shop/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;OWASP Juice Shop&lt;/a&gt; is a vulnerable
web application, designed intentionally as insecure, and it can be used as a
training tool. The app exposes vulnerabilities from the OWASP Top 10 list, and
also other security flaws. &lt;strong&gt;What we want is to be able to explore vulnerabilities
and to check how AWS WAF behaves to prevent them&lt;/strong&gt;. Basically we want to use Juice
Shop as “guinea pig” to AWS WAF.&lt;/p&gt;
&lt;p&gt;To be able to assess how WAF behaves we need to perform two installations of
Juice Shop:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;One installation without any protection - for this I will use docker locally.&lt;/li&gt;
&lt;li&gt;One installation with WAF - for this I will use &lt;a href=&quot;https://aws.amazon.com/apprunner/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;AWS AppRunner&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;installing-juice-shop-locally-docker&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#installing-juice-shop-locally-docker&quot; aria-label=&quot;installing juice shop locally docker permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Installing Juice Shop Locally (Docker)&lt;/h3&gt;
&lt;p&gt;To install Juice Shop locally I’m going to use docker with the official image
&lt;a href=&quot;https://hub.docker.com/r/bkimminich/juice-shop&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;bkimminich/juice-shop&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; pull bkimminich/juice-shop&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;Using default tag: latest
latest: Pulling from bkimminich/juice-shop
07a64a71e011: Pull complete
fe5ca62666f0: Pull complete
&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.
Digest: sha256:4a80df64f0430b73955b97a653d31adb1f7782417b900c930805c7084b5dfe41
Status: Downloaded newer image &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; bkimminich/juice-shop:latest
docker.io/bkimminich/juice-shop:latest&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And then running it&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;NODE_ENV=unsafe&quot;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;:3000 bkimminich/juice-shop&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;info: All dependencies &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; ./package.json are satisfied &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OK&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
info: Detected Node.js version v20.10.0 &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OK&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
info: Detected OS linux &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OK&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
info: Detected CPU x64 &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OK&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
info: Configuration default validated &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OK&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
info: Entity models &lt;span class=&quot;token number&quot;&gt;19&lt;/span&gt; of &lt;span class=&quot;token number&quot;&gt;19&lt;/span&gt; are initialized &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OK&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
info: Required &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt; server.js is present &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OK&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
info: Required &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt; index.html is present &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OK&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
info: Required &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt; styles.css is present &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OK&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
info: Required &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt; main.js is present &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OK&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
info: Required &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt; polyfills.js is present &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OK&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
info: Required &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt; runtime.js is present &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OK&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
info: Required &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt; vendor.js is present &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OK&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
info: Port &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt; is available &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OK&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
info: Domain https://www.alchemy.com/ is reachable &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OK&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
info: Chatbot training data botDefaultTrainingData.json validated &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OK&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
info: Server listening on port &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I’m adding the environment variable &lt;code class=&quot;language-text&quot;&gt;NODE_ENV=unsafe&lt;/code&gt; to be sure that all
challenges are available, even those considered dangerous. Let’s try and open
our browser locally on port 3000.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/5c8d7093ed7d6bade9bd013803eea844/b1c31/owasp-juice-shop-local.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 48.75000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACe0lEQVQoz02SWU8TARSF5xdo3IBI7UwXirSzFDrUdijLdFppaZnpVKhLrVCWUkoiCqKiJFotKBqNLxp90Kgv/szPMBrjw5dzcnNzb+7JFSzLIpfLkzVN4vE4siyjqiqqdoL2V//6k/o/FFRFQdPixGSF2HCY8GwToeTM4dRqFBZuUVy4Sa6yyHTJZbIwT2a27On/fmrOwbSvecyUq+TcGlalxtRskdzWK4R4XGNEURmSNYZiKuGYSjSeYL7iYldcHLfKvFPx/NVCkcz0DFJkBGk46vVGZI2RUZ3haBSr3UPw+S6h6zpW1kRPJPANXmQoHGbpzhIbrZbH2uqqx0pzharrousJxhJjSKLf6xdFkcG+s0wtPUGQJImD7iFvP33n84+fJJNJNE2juXyHzfY67Y0NOlubbHTWaXfWub3UoHv4lo+fvzBtml7mw5dH8A1cINfqIgQDAfaedWktd3hz8JJsPo+RNigtVMm7DgXHwXFsbHuecqnAXNlma3uV46PHFMsVjHT638BC5xBB9Is87XV593SPo/uPSRoGo5rGcWOOr80CB4tZTCtLNpvFvdnAvV7n+PU+7993MYwM0csRQsEg/WdOcbX94s/JJ++SNDKMp1MosoyiKFSTKs2JOJXUKAld93JOTc6QTBtcMabI2QtM5ktMWCVSZpGxKyns3Q8IUkDCL0qIkojP7ycUChMKhegbvMTpvgHO9Q/g8/kIBAKIfj/9F84TiSk094/YPDzi7pserd5zlvefU3/1CyEgBslZ4ziNcepFEzkaJRgKMZHJsL2zw72dB9iu6y2JRCLcqNfZfrRPY7fL9YcNlntVao8WKd5eY/HZN34DSElqWpxnnVAAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/5c8d7093ed7d6bade9bd013803eea844/8ac56/owasp-juice-shop-local.webp 240w,
/static/5c8d7093ed7d6bade9bd013803eea844/d3be9/owasp-juice-shop-local.webp 480w,
/static/5c8d7093ed7d6bade9bd013803eea844/e46b2/owasp-juice-shop-local.webp 960w,
/static/5c8d7093ed7d6bade9bd013803eea844/91d86/owasp-juice-shop-local.webp 1413w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/5c8d7093ed7d6bade9bd013803eea844/8ff5a/owasp-juice-shop-local.png 240w,
/static/5c8d7093ed7d6bade9bd013803eea844/e85cb/owasp-juice-shop-local.png 480w,
/static/5c8d7093ed7d6bade9bd013803eea844/d9199/owasp-juice-shop-local.png 960w,
/static/5c8d7093ed7d6bade9bd013803eea844/b1c31/owasp-juice-shop-local.png 1413w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/5c8d7093ed7d6bade9bd013803eea844/d9199/owasp-juice-shop-local.png&quot;
            alt=&quot;OWASP Juice Shop running locally&quot;
            title=&quot;OWASP Juice Shop running locally&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;OWASP Juice Shop provides interactive training tutorials, and presents vulnerabilities as challenges that we need to discover. It’s really cool as a training security tool for developers. The first challenge is to discover the Score Board page where you can track your progress.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/fc981ae33a79aaffff11dd1889fb77b5/8b70b/juice-shop-score-board.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 59.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAA7DAAAOwwHHb6hkAAACkUlEQVQoz2WQXW8aRxSG+SlVFBvYz9md/cCAYWHBjiNqdoG1wdghJia2UxOrkVsqV05jV7Fq9aLtdX/sU+1gVZV68ejMvOed92hOIf1wy80PS5a3n5l++pXZzQOT6zuS8x9JL1aK5LmmFz/9j8OPd5x8uldvzr/8QaG2E7E7jOiOYuJRh07WIR7FRIM2rf/QTCMaSZNm+kyyJkoj2qOYeq9KOltQaAxNxk8B468hk8eAw68+Y0XA5DFk/Liug3uL/i86yRf9uRqK/Jzem7y6eUH2bkbBkQLhmRhCU9jSeMZE+NZadzTlEZ71L5ZrKOz87gvK+ksGx3MKtmUTRS22KlUqYQWtpFEqljENi7jdobpVI/BDSsUS5ZKGrhnU69uEQQXbtNENG1nZZnNjk8E0D7RtpOfhBz6+72OaBoZhIISN67qEYYjne5imiWVb5P5cDwIfIQSGaeJKj82NlwzzQMdxCMJ107aFMudajpRSDbEsC8/PBwbK57iu6qlwx1EevVxkcHRKwfUFnaxBNzlgbzgmOZ7TG79hJ8lUTU7m7KYH7GVT9o/esjs8pDeZMZpf0u2P1ADXlZRLxfWXXc8jW3zg5OOK4fySZLZgfHFNtrji4P2SyeX3ZIulug/PvlNa3Etp7/Vov/4Ww9AxDZ2NF9+QjN9QEMJhqxHR7HSpNiKq203CWp1a1KYZ7yitUm8QdXapNVt4lQpbUYv96Sm9w1P6R+f0j895dTDlbPWwDvR9SRBKpNqNiyclrisQwlJnz5NqV/n3dK1Eaz9l8fAXF799Zvnnz7x/WjFZ3XH9+995oFBGKT21aKnCJMKxsISB4zp43rqnaRrFzQ3CZszrt1f0r4ZMbwdkNwO6RzPObp/4B4rQsroZhb1VAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/fc981ae33a79aaffff11dd1889fb77b5/8ac56/juice-shop-score-board.webp 240w,
/static/fc981ae33a79aaffff11dd1889fb77b5/d3be9/juice-shop-score-board.webp 480w,
/static/fc981ae33a79aaffff11dd1889fb77b5/e46b2/juice-shop-score-board.webp 960w,
/static/fc981ae33a79aaffff11dd1889fb77b5/da80b/juice-shop-score-board.webp 1266w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/fc981ae33a79aaffff11dd1889fb77b5/8ff5a/juice-shop-score-board.png 240w,
/static/fc981ae33a79aaffff11dd1889fb77b5/e85cb/juice-shop-score-board.png 480w,
/static/fc981ae33a79aaffff11dd1889fb77b5/d9199/juice-shop-score-board.png 960w,
/static/fc981ae33a79aaffff11dd1889fb77b5/8b70b/juice-shop-score-board.png 1266w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/fc981ae33a79aaffff11dd1889fb77b5/d9199/juice-shop-score-board.png&quot;
            alt=&quot;alt text&quot;
            title=&quot;alt text&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;installing-juice-shop-in-aws-apprunner&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#installing-juice-shop-in-aws-apprunner&quot; aria-label=&quot;installing juice shop in aws apprunner permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Installing Juice Shop in AWS AppRunner&lt;/h2&gt;
&lt;p&gt;To run OWASP Juice Shop in AWS, I’ve chosen AWS AppRunner service. The OWASP
Juice docs suggest to use an EC2 instance, but I prefer to use the AppRunner
service which is much simpler (we don’t need to setup a VPC).&lt;/p&gt;
&lt;p&gt;I am going to configure the AppRunner service to use the official docker image.
We need to push this image to a private registry in &lt;a href=&quot;https://docs.aws.amazon.com/AmazonECR/latest/userguide/what-is-ecr.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;AWS
ECR&lt;/a&gt;. I
am going to use the aws cli to create a repository &lt;code class=&quot;language-text&quot;&gt;juice-shop&lt;/code&gt; in my private
registry of my aws account.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;aws ecr create-repository --repository-name juice-shop&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 957px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/48b92ca7145ac5f6c7e4bb1f61e55f28/6bff2/aws-cli-ecr-create-repository.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 34.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAA7DAAAOwwHHb6hkAAABNUlEQVQoz4WQ30vCUBTHr5aY5o/lyiIImnNTp3M6MwmhKOih55zO6dyWEmYEPvTQf/+Ne2ZiKfTw4ZwL537P93vYsvOF+ecCmrdEWh8hXXeRMSY4Mj1kjQkSmo1UbYikZiNruMiZPpJVB4nKAEJjArEVIGd6EFs+UvoYjBWfITRnkLpznF5PITQ8nHWmNByvDBGvODisjZHSXSQ0B8nqaE2sbINJPbBCb1UtsIhkId8OUH78wOVtKKo+vKN4v4Bo+hCaHrnKGC713DVBCx0w2UKk2F/DuPrJVYD60xLKSqhw90b1uBWQKIe73VftkFJIVOnvEJQtyn5+M8NF9xX59gstiJXsMIK0EUfehkQ2e94caA6J8Lj8fjwiP/KeOvi1fRdbDrmTn0dUGayG+uSQx/z74b8F3yH828OmF3gHAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/48b92ca7145ac5f6c7e4bb1f61e55f28/8ac56/aws-cli-ecr-create-repository.webp 240w,
/static/48b92ca7145ac5f6c7e4bb1f61e55f28/d3be9/aws-cli-ecr-create-repository.webp 480w,
/static/48b92ca7145ac5f6c7e4bb1f61e55f28/c15ec/aws-cli-ecr-create-repository.webp 957w&quot;
              sizes=&quot;(max-width: 957px) 100vw, 957px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/48b92ca7145ac5f6c7e4bb1f61e55f28/8ff5a/aws-cli-ecr-create-repository.png 240w,
/static/48b92ca7145ac5f6c7e4bb1f61e55f28/e85cb/aws-cli-ecr-create-repository.png 480w,
/static/48b92ca7145ac5f6c7e4bb1f61e55f28/6bff2/aws-cli-ecr-create-repository.png 957w&quot;
            sizes=&quot;(max-width: 957px) 100vw, 957px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/48b92ca7145ac5f6c7e4bb1f61e55f28/6bff2/aws-cli-ecr-create-repository.png&quot;
            alt=&quot;aws ecr create-repository&quot;
            title=&quot;aws ecr create-repository&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;To be able to push images to this new repository, we need to login docker into
our ECR registry.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;aws ecr get-login-password &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; login &lt;span class=&quot;token parameter variable&quot;&gt;--username&lt;/span&gt; AWS --password-stdin &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;your-account-id&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;.dkr.ecr.us-east-1.amazonaws.com&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/582355cb6cae49db820a55fb5f57588f/a8c87/aws-docker-login-ecr.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 2.9166666666666665%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAYAAADeko4lAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAASUlEQVQI12Pg0Y35z6EZ/p9LO/K/oGE8HAsZxf/n1Y39L2QU/V/IKOY/n37cf3aN8P/c2hH/efVAeiLBbC6tCIheo/j/IsaJ/wHnVh+2GOA9FgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/582355cb6cae49db820a55fb5f57588f/8ac56/aws-docker-login-ecr.webp 240w,
/static/582355cb6cae49db820a55fb5f57588f/d3be9/aws-docker-login-ecr.webp 480w,
/static/582355cb6cae49db820a55fb5f57588f/e46b2/aws-docker-login-ecr.webp 960w,
/static/582355cb6cae49db820a55fb5f57588f/f992d/aws-docker-login-ecr.webp 1440w,
/static/582355cb6cae49db820a55fb5f57588f/5e0a5/aws-docker-login-ecr.webp 1538w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/582355cb6cae49db820a55fb5f57588f/8ff5a/aws-docker-login-ecr.png 240w,
/static/582355cb6cae49db820a55fb5f57588f/e85cb/aws-docker-login-ecr.png 480w,
/static/582355cb6cae49db820a55fb5f57588f/d9199/aws-docker-login-ecr.png 960w,
/static/582355cb6cae49db820a55fb5f57588f/07a9c/aws-docker-login-ecr.png 1440w,
/static/582355cb6cae49db820a55fb5f57588f/a8c87/aws-docker-login-ecr.png 1538w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/582355cb6cae49db820a55fb5f57588f/d9199/aws-docker-login-ecr.png&quot;
            alt=&quot;docker login in AWS ecr&quot;
            title=&quot;docker login in AWS ecr&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Check the list of images&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; images&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/1525712b0bf19a6f14274aa8fa8f33e4/87a80/docker-images.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 14.166666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA2UlEQVQI1x2M0UrCYABG/5uuwm5KysrZtHBLkU0zttnGqCiDUNJt6RhMq+XvkB6gV+ihT/BffYdz4BN/8of0t6T9kGN6MW1vSa33xtH1hMYg4uImptqZovXndPyM5jBB60d0g4wza8a5PcdwF1SMGaKVIKxxgRWscJ4/GDyuMUcp9n2OPowxRinO+FOdXzkLnqId4UQqH04l7suX4uC14LAbIZoJQruT1IMtdX9LIyipeRu1x843FWtF9bZA6Al7ZoYe7tD8kv1ervqpJzmw15y4G8TlO6IV8w9nIGdcJvqlsgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/1525712b0bf19a6f14274aa8fa8f33e4/8ac56/docker-images.webp 240w,
/static/1525712b0bf19a6f14274aa8fa8f33e4/d3be9/docker-images.webp 480w,
/static/1525712b0bf19a6f14274aa8fa8f33e4/e46b2/docker-images.webp 960w,
/static/1525712b0bf19a6f14274aa8fa8f33e4/0ea8a/docker-images.webp 973w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/1525712b0bf19a6f14274aa8fa8f33e4/8ff5a/docker-images.png 240w,
/static/1525712b0bf19a6f14274aa8fa8f33e4/e85cb/docker-images.png 480w,
/static/1525712b0bf19a6f14274aa8fa8f33e4/d9199/docker-images.png 960w,
/static/1525712b0bf19a6f14274aa8fa8f33e4/87a80/docker-images.png 973w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/1525712b0bf19a6f14274aa8fa8f33e4/d9199/docker-images.png&quot;
            alt=&quot;docker images&quot;
            title=&quot;docker images&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Then we just need to push our image&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; tag 402fefa2b068 &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;account-id&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;.dkr.ecr.us-east-1.amazonaws.com/juice-shop:latest&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; push &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;account-id&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;.dkr.ecr.us-east-1.amazonaws.com/juice-shop:latest&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/d0f3cc3b891fe8612a7d81be300a01a2/709cb/docker-push.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 64.99999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACOElEQVQ4y62SW1NSYRSGt3bA6aAFiqFgHOSkIOje6BYEUUT0xjROKghshABBa7xo6q7bLvoVTb/zqf0Blk4zjTNdvLPW+mZ97zq90o/dr3z/9onMl8/MRau4EudYVY1ppSJgiVQxLZcxyxVeLJ3yMlTCtl5nWqmKt9k1DWO4zPPAMWO+IlL6oIaaqSNvlQlvlvCqBdyrOZxKVsAVyTK3fIi8XcYhv2UmeEB0TyO2r+FV88T2NDxqgXDimED8FMm31WYxfcHCTofgbhdPsiViZ7yJwZvnsSfHw/ks7mQLY6iEwZMnkO4S3r/kVaTKQqojch0bDWbVOpJls8XkapNp5RxbrIVJ0TCvnmOSNaT5ApIzj2TPYY2+YzxUYdRTxJPq4d+9YiJcwZm8wKI2mVlvYo7UkTLJa5KHHXxvelijDaaUGmMLpwIG/wkG3wmPvMe83mgxpWiML53hTXXxpy9FbE+0hZ1UNIwrNaSj7Y/ka9eEih9wJFqYI5qoNDuoaFypYpJrIln/qEOPJ2WNZ8EykjPXn8KV71tbqoMt3sW61sSy1kByDBLuJg7t0B/EI/OFW5D8Oz0WM1c4NtvMrDf+mvQv6OQ3vnenJ/ah7+K/EHq2+wu2x9tY1PsTDslu1uBL3enQdf8OR1x5Rt3FPrEz1cWduhSyEB3as4OD5PoHctzx/8TwSM4cY8EqD7wnSGryPbGjHq5MV0hFl8JEqMJ46EzYoa+LWhfy77cKTxZLPA2UhE5F0V8j/wSnPaZlE7kxuwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/d0f3cc3b891fe8612a7d81be300a01a2/8ac56/docker-push.webp 240w,
/static/d0f3cc3b891fe8612a7d81be300a01a2/d3be9/docker-push.webp 480w,
/static/d0f3cc3b891fe8612a7d81be300a01a2/e46b2/docker-push.webp 960w,
/static/d0f3cc3b891fe8612a7d81be300a01a2/43c62/docker-push.webp 1034w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/d0f3cc3b891fe8612a7d81be300a01a2/8ff5a/docker-push.png 240w,
/static/d0f3cc3b891fe8612a7d81be300a01a2/e85cb/docker-push.png 480w,
/static/d0f3cc3b891fe8612a7d81be300a01a2/d9199/docker-push.png 960w,
/static/d0f3cc3b891fe8612a7d81be300a01a2/709cb/docker-push.png 1034w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/d0f3cc3b891fe8612a7d81be300a01a2/d9199/docker-push.png&quot;
            alt=&quot;docker push&quot;
            title=&quot;docker push&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In the AWS Console we should see the image published&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/22222775580595dc1f4986c032a7895a/5d942/aws-console-ecr.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 30.41666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABTUlEQVQY0z2QSW7bQBBFeQJnYSsyZM5kk82pyebUoizSsCF4lQBeOMfIBXL5F7BhePHxUL+qPlDlbK/v/P74w7K+0fWGSCpOSYUratysIc1rnvyU+58uh0efh6P3rYOlz49DwN1DwP0xwBmWjenyQt1NtL2hqDrLPVzpGS/MOJ5Cyz3YDYTlrpMv8MOUofQwtUsS+TjjeqM7b8ivICEVvdnI6wEvLghFTZwrCjVZb1dW9WSVRhSaRin+/nL59+lxMynO9eXGfNnIK003nIlEiaxH9PRMIluirCFISvykJExrkqKznig1qWxt/Rhr3NzwFFU43bigekOpBrrBkMmGZlhozUrVjkzLxnheGczVzuy/3utuutCOC3rnMDMvV4RscPaF9fWdRs80eiJKC/xYEiQFYVrYV5RNj6w1UVqSFYo4q2wv/JoJE2kv80LBf29vtK0YU9d9AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/22222775580595dc1f4986c032a7895a/8ac56/aws-console-ecr.webp 240w,
/static/22222775580595dc1f4986c032a7895a/d3be9/aws-console-ecr.webp 480w,
/static/22222775580595dc1f4986c032a7895a/e46b2/aws-console-ecr.webp 960w,
/static/22222775580595dc1f4986c032a7895a/9c8f3/aws-console-ecr.webp 1343w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/22222775580595dc1f4986c032a7895a/8ff5a/aws-console-ecr.png 240w,
/static/22222775580595dc1f4986c032a7895a/e85cb/aws-console-ecr.png 480w,
/static/22222775580595dc1f4986c032a7895a/d9199/aws-console-ecr.png 960w,
/static/22222775580595dc1f4986c032a7895a/5d942/aws-console-ecr.png 1343w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/22222775580595dc1f4986c032a7895a/d9199/aws-console-ecr.png&quot;
            alt=&quot;AWS Console ECR&quot;
            title=&quot;AWS Console ECR&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Now we can use this image in our AppRunner Service. Navigate to the AppRunner service and create a new service, specifying the docker image URI for the service&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 922px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/c6c0d8d38551393fa95ed9c79a1eb87f/6da96/aws-apprunner-create-service.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 94.58333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAC0klEQVQ4y32T63KbMBCF8widuDbYmIsEQgIk7jfbNHGcS9O00/QR+v4vcTqSE0/S1vnxzWqAOTq7e7ggLINFMziEg3GF5ZoaglDApxwkSszZ8Rk+2x7mLyyW/j/o5xd+KBByBZ6VCMIEl4s1SJSiHSYUzYBhe22QZY8gShHGEvaanoTnf11y4VMBV0M4bIcYF24QI1UNVNkjkdXJmbUisBwCaxV84JAKOAHDyouwWAX4bLlYBzHKegBlGWiUGrRrEur2U/gaejwHUQY9NjfgR0GPHp0t3dDcYgSJQLN/RL07gBUDQtUjzHtEeQ+Rt8jKHnkzIslbxFkFIRvQWL4IEo7ZYn2awdxysQwEvO0T4qufcPsH2NUBy/oWdnVjRGWzQ1ZvEKsOYVqDJhUIeyOoXb3OQZ/1TNV0D95egRYbAzF1hCg64/DVnXGoGoT8jKB2aAcCzvCIYPwGq7yBVR0wU1eYyS+gskPRX6Ha7CHKAUx1ILxEwLLzDj0qMF7fY7h+QN5PkO0WqpuQdxPKfmccClmbKKlqQJq3JnpnBdc+Qz1MaMYvZvhlt0PVT6j6Y+WyRigKqKpHO04QsgJl6XlBx4sgiw6yaJHI2kTiLR4R8MPEdKLzqyOk/6TzSyHctNztbpAUPZisEcvGoBeQqOa4kLQ06PZpnH28FG/3A2T7BNvE5WCqVe5NJvN2As87MNmeovNxbIhAubuFmu7A6h1YtT2Rlj2yekTWTabq+GjX74L9TnCxhhummA5fsb99wGbaI6+6E3oRsuqRtlukZsYVsqI9n0N91v/33dMz7r//wub6DqoeIV9QL+T1iKLdICtbyLJDJM7ERj/UW9Zt6Hjo4ZNY/QPlymQv4hIhz83GjaBLYswWDua2axaiq75gNndwOXdM1WP4Pw4W6xjP4wK/95f4NPdwETAJ22VYevE7Vr6Gm/r3u9M3uvocjDGIOILtxfgDskEio5iHFSAAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/c6c0d8d38551393fa95ed9c79a1eb87f/8ac56/aws-apprunner-create-service.webp 240w,
/static/c6c0d8d38551393fa95ed9c79a1eb87f/d3be9/aws-apprunner-create-service.webp 480w,
/static/c6c0d8d38551393fa95ed9c79a1eb87f/88718/aws-apprunner-create-service.webp 922w&quot;
              sizes=&quot;(max-width: 922px) 100vw, 922px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/c6c0d8d38551393fa95ed9c79a1eb87f/8ff5a/aws-apprunner-create-service.png 240w,
/static/c6c0d8d38551393fa95ed9c79a1eb87f/e85cb/aws-apprunner-create-service.png 480w,
/static/c6c0d8d38551393fa95ed9c79a1eb87f/6da96/aws-apprunner-create-service.png 922w&quot;
            sizes=&quot;(max-width: 922px) 100vw, 922px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/c6c0d8d38551393fa95ed9c79a1eb87f/6da96/aws-apprunner-create-service.png&quot;
            alt=&quot;AWS AppRunner create service&quot;
            title=&quot;AWS AppRunner create service&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Then just give the name &lt;code class=&quot;language-text&quot;&gt;juice-shop&lt;/code&gt; and specify the cpu and memory.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 905px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/01898db1161b4d4e1b431c59e1a4f439/65d79/aws-apprunner-create-service-2.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 68.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABuklEQVQ4y42U6XKiQBRGfYhERQOyKTTQ3ey7oEnM1Djv/zzfVDfgkjLO/Dh1G7r68N1bwMzaBVjYFCvbh+Nx6JaL16WGlWpdUN5MvCobzP+D2cYiUKxBOtddvMzfpCDJW0RpDcpT2C7Hi6LLB/2LmW4RWA6F7VIoqiVvLtcGWFyCxwU0073ce46J+UofhCLlxnTlhjgsNmhUIC07eCwdH8hgOd+hNzCsNXtoeamaMp0QTWnSqkOUt7AJx9YLYZMQOz+6sPUjOEEMjyUgdKia4QjhMDeZTNncCHuEeSsP8bRGUnXweA7C0pFE1kno8/QqnGS3wrhowZIKhCbXNcvg8RQkCEGC6I77hAv1TrhYG2j6T7z/+iM5nM44fp3Rn87g9TtY2YMVHYJ8D1Z24EkJGhdQjd1joUiY1T2a40lS9R8o2gPCrEYQF6BJBTaOgSalbPeu5YfCqsNBpPr8jXJ/hBtEEjEvMlZfzG9cP21ZzjBvUDQHSVruEYTZ5eDEdC0rfyKUX0rZgfAMDk2uyZ4wJHwywyhr5HsYZg1YXFzm9BOiA838IaGoIpUQCbaEQbcJjK33GFtUX/5I/gJTFphmveXPaQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/01898db1161b4d4e1b431c59e1a4f439/8ac56/aws-apprunner-create-service-2.webp 240w,
/static/01898db1161b4d4e1b431c59e1a4f439/d3be9/aws-apprunner-create-service-2.webp 480w,
/static/01898db1161b4d4e1b431c59e1a4f439/4d060/aws-apprunner-create-service-2.webp 905w&quot;
              sizes=&quot;(max-width: 905px) 100vw, 905px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/01898db1161b4d4e1b431c59e1a4f439/8ff5a/aws-apprunner-create-service-2.png 240w,
/static/01898db1161b4d4e1b431c59e1a4f439/e85cb/aws-apprunner-create-service-2.png 480w,
/static/01898db1161b4d4e1b431c59e1a4f439/65d79/aws-apprunner-create-service-2.png 905w&quot;
            sizes=&quot;(max-width: 905px) 100vw, 905px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/01898db1161b4d4e1b431c59e1a4f439/65d79/aws-apprunner-create-service-2.png&quot;
            alt=&quot;AWS AppRunner create service&quot;
            title=&quot;AWS AppRunner create service&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;For now we can assume all the defaults. We are not associating yet any WAF to our service. Let’s first be sure that we are able to run the service. Just review the info on the last step of the wizard and create and deploy the service. AppRunner will take several minutes to perform its magic to deploy the service and expose it to the internet.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/eaa3cbe5ff8ac04f0b26a70b8be1700e/de766/aws-app-runner-services.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 19.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAsUlEQVQY053NbU7DMBBF0awCRJGbBlGPPbYTfzRtsgHYB/vfw0W4hQXw42jmaZ40g8wr4yQ8vYz/9nwYMcZweDUMS93xaeV0Tpg33x07fUyPmYTj5P6Yh/vNY13k68PweTsxaNmQWLGhIqGiecWl1ncJBRcbse5oviLpgsSGLishX7FasJp7r1x2rC4MP0VNBR/vYi7o/Jszmiqx7YS2oXXrD+PSCHPrHdGZd4k9n13iG0AFdMBVLu5xAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/eaa3cbe5ff8ac04f0b26a70b8be1700e/8ac56/aws-app-runner-services.webp 240w,
/static/eaa3cbe5ff8ac04f0b26a70b8be1700e/d3be9/aws-app-runner-services.webp 480w,
/static/eaa3cbe5ff8ac04f0b26a70b8be1700e/e46b2/aws-app-runner-services.webp 960w,
/static/eaa3cbe5ff8ac04f0b26a70b8be1700e/f992d/aws-app-runner-services.webp 1440w,
/static/eaa3cbe5ff8ac04f0b26a70b8be1700e/c4106/aws-app-runner-services.webp 1838w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/eaa3cbe5ff8ac04f0b26a70b8be1700e/8ff5a/aws-app-runner-services.png 240w,
/static/eaa3cbe5ff8ac04f0b26a70b8be1700e/e85cb/aws-app-runner-services.png 480w,
/static/eaa3cbe5ff8ac04f0b26a70b8be1700e/d9199/aws-app-runner-services.png 960w,
/static/eaa3cbe5ff8ac04f0b26a70b8be1700e/07a9c/aws-app-runner-services.png 1440w,
/static/eaa3cbe5ff8ac04f0b26a70b8be1700e/de766/aws-app-runner-services.png 1838w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/eaa3cbe5ff8ac04f0b26a70b8be1700e/d9199/aws-app-runner-services.png&quot;
            alt=&quot;AWS AppRunner services&quot;
            title=&quot;AWS AppRunner services&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You can click on the link and you should see the Juice Shop&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/e2c47039ebcc98f08f3f18d8e2ddf9f3/e088a/juice-shop-in-apprunner.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 62.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAC5UlEQVQ4y42RS08bZxSGvU43LUSFNMEe29jjMTNjjy94bIPHARsIxhQDvozHVzyDcVWkKIu2UhZNkBBUVUnbTSXEIqqyyiqrbrrsD3sqj4lUdVF18ei85+g7r86n1xNXo+Qyq6ytJkjGVojLIkHvFwiPFxAef86TxYfMz80x9z/xBCNREvEoT/NpSsU1jHyGUjHPhpFjTU+hJxXEFYVlSSE0JXpf7/V0vizJMyIyHuPLBiPrGfvtDlt1i+26xU6jw0atSa5SI797QKZccdG39u713j0VsttVcjv7ZJ8dkK0c4RFlFVmWkWIaUixBRNVcLSpxApJMIp2h0WhweHREdX+fer1B7fCQg1qN43qdUqlMwTBY1bOEZRWP4PPyZGmJR4uLCD4f037us09ZXFjg4fw8iixj2zbdbtettj2i1+vR7/fp93tYloVpmqRSKT558ACPIAgEg0GGtsPXz5/jnH3l6hVZxh8IkEymGJ+OsW2H09NTJpMJZ2dn/5iNORmO3GudyQSPz+cjLIrc/f6Oqze33L17z/sPH8joOhFRJJPJMBj2OLEHOI7NcDh064ndxx4PGIw6mJ069njMza+3eLxeH5IU4eL6J46d75icv+Tu7Vvy6+sYhkHBKDByhlg9k1arSbPRomN1MNst2pZJp2vRbjepHps0nBezC0VR5Jffbrm++ZZXsSw/v7omaxRIaBp6Vmevtst2dYtypcR2tcxm+SlGwcAwihTWC+iZLL2BxY83388MQ6EQF1fXvL58zcU3L7m8+oHUapqwGCGfTvKHs8Of9hZ/jTZ4c2xQLJUolzbZLJcZnL/AHJ/TsrpcXl3PQgkEAiiKgqYliKeSqLEYqqK4wWgxlaOsRjOXwMxp7GY0kqkU6fSUNLlCEX3dIJFMoqrqzNDv9xOJRGaIIpIkuUQlyQ3skVdgKRhiaTmEsBxyf/SRgN+Pz+slHA67+56p2dT0v5guBfyCi98/O+DffHz7N8a7xavuHuBkAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/e2c47039ebcc98f08f3f18d8e2ddf9f3/8ac56/juice-shop-in-apprunner.webp 240w,
/static/e2c47039ebcc98f08f3f18d8e2ddf9f3/d3be9/juice-shop-in-apprunner.webp 480w,
/static/e2c47039ebcc98f08f3f18d8e2ddf9f3/e46b2/juice-shop-in-apprunner.webp 960w,
/static/e2c47039ebcc98f08f3f18d8e2ddf9f3/3a6ad/juice-shop-in-apprunner.webp 1015w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/e2c47039ebcc98f08f3f18d8e2ddf9f3/8ff5a/juice-shop-in-apprunner.png 240w,
/static/e2c47039ebcc98f08f3f18d8e2ddf9f3/e85cb/juice-shop-in-apprunner.png 480w,
/static/e2c47039ebcc98f08f3f18d8e2ddf9f3/d9199/juice-shop-in-apprunner.png 960w,
/static/e2c47039ebcc98f08f3f18d8e2ddf9f3/e088a/juice-shop-in-apprunner.png 1015w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/e2c47039ebcc98f08f3f18d8e2ddf9f3/d9199/juice-shop-in-apprunner.png&quot;
            alt=&quot;Juice Shop in AppRunner&quot;
            title=&quot;Juice Shop in AppRunner&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Remember that we are still not running Juice Shop with any WAF.&lt;/p&gt;
&lt;h2 id=&quot;setting-aws-waf-in-juice-shop-app-runner&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#setting-aws-waf-in-juice-shop-app-runner&quot; aria-label=&quot;setting aws waf in juice shop app runner permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Setting AWS WAF in Juice Shop App Runner&lt;/h2&gt;
&lt;p&gt;Now that we have Juice Shop running in AWS, let’s put it behind a AWS WAF. &lt;strong&gt;We
first need create a Web access control list (&lt;a href=&quot;https://docs.aws.amazon.com/waf/latest/developerguide/web-acl.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Web
ACL&lt;/a&gt;)&lt;/strong&gt;. A
Web ACL defines the set of rules we want to apply to our resource, in this case
our AWS AppRunner service. We can associate a web acl to protect other resources
such as Amazon CloudFront, Amazon API Gateway, Application Load Balancer, Amazon
Cognito, etc. Let’s create a web acl with the name &lt;code class=&quot;language-text&quot;&gt;juice-shop-web-acl&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/55d9f10bd2b8aff7dacf473953556ebe/f5209/aws-waf-web-acl-create.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 72.91666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACNUlEQVQ4y42U2W7bQAxF8w+t4niTrcXSLBoto5FlS05sp0laF8hD//9jbkHKzooAeTgYgg9HJIejqyBW8JYCnp/AW6TwgxSJLDBbrDCehZjMIz5vpgFD8SU/mQ/xaLKEd+MzV4tQQJgapmqR6BLjWYCpH0OZGspY6NzxSWRlg7xcQ+gSpmig8xqmbBCkBt54ievxYhBSRTKrkOqSK/sxmkMXDVx7h7zaYBEpZhnrl/g1N+QJP5SDcErtUWvziL9CVE2Htj9wVdSBMBYis8N5RlKeclkFaSwSVeDKD1PMlglLLzJvvIDtj/jz/A8Pp2c+D48n9PsH9AfiEbvjE3+QRCqvGeqQhdPliuf2Vli1t7h/+ovj44lPot//QrO9RbO9Q9vtuQvJldpXIbXsRwJ+KPjmLlK77tF0e5RNB1W4NzSMzB1SXbHonZAqnPgxM7Q93FbmOuTtHVTdITbuTPMGh1W+HuTvhEGKn9ezlz0iSGi6e9jjCWpzQGQ7xHWP2PZDbCnuENU7JFTxR6E38l/ndxYW9QbNlubUQ9Eu5g6S26u5XXm+iE8z5ApH80/CrGpRrnfIXQdTb3l1El19YFidbwltu8Pu+BtNd+A5idwx8swl5ovKa+jC8T5+KVzJApqWOrP8JC9VrVT5rsoozRALwwQr9Vl4kUrjYNc7JrdblK5D6Xr4kcQ8EPzUEpKriruhedPHv6wwzWpkdgtdbaDLDVJaE2URigJhWiAUJSJCUtX0Hxie5n/RWLyZdCHr0AAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/55d9f10bd2b8aff7dacf473953556ebe/8ac56/aws-waf-web-acl-create.webp 240w,
/static/55d9f10bd2b8aff7dacf473953556ebe/d3be9/aws-waf-web-acl-create.webp 480w,
/static/55d9f10bd2b8aff7dacf473953556ebe/e46b2/aws-waf-web-acl-create.webp 960w,
/static/55d9f10bd2b8aff7dacf473953556ebe/44ba8/aws-waf-web-acl-create.webp 1061w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/55d9f10bd2b8aff7dacf473953556ebe/8ff5a/aws-waf-web-acl-create.png 240w,
/static/55d9f10bd2b8aff7dacf473953556ebe/e85cb/aws-waf-web-acl-create.png 480w,
/static/55d9f10bd2b8aff7dacf473953556ebe/d9199/aws-waf-web-acl-create.png 960w,
/static/55d9f10bd2b8aff7dacf473953556ebe/f5209/aws-waf-web-acl-create.png 1061w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/55d9f10bd2b8aff7dacf473953556ebe/d9199/aws-waf-web-acl-create.png&quot;
            alt=&quot;AWS WAF Web ACL&quot;
            title=&quot;AWS WAF Web ACL&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In this context I want to start with the common rules to protect against that the OWASP Top 10 list. AWS WAF supports out of the box a set of rules that we can enable.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/eb1bdf6a9a1523a7a0cdcd9593d6e90c/b9024/aws-waf-web-acl-managed-rules.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 36.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAA7DAAAOwwHHb6hkAAABYUlEQVQoz22RyW7CMBRF+YWW0iSEEGPHsxNnIAToQEepqtRtd/3/z7iVTcWqi6tr2W84z2/GVYOEKGTUIC0FmLAoqUSyJEjzTfRsRXGTrjG/Xf2rRbrGbVZGn224QaZ6ZHZEwlwMcH6Lu9MbDg/PmI4n3D++ohkOYLJGpWpUskYAEdqDSRcbh4JBM8otCHdgyoNwG7sw4WD9FsK0MSkka9cjxAaA4FRYVMKCUIn5Isf1PMMiKc6ExUaiIOI8WlJEgm68R6U8uG4hbA9uWnDtoZstXDuBmw779y98fv9gfPqAHh+RU30uuFxXSFc00gWVzMQkXQ+Qtodptqj7fXRpu3in6gHN7gHHlw90hyeobkJW8j9CqiJl+ItQkFQa0rYQxkeFsx/22B1P8MME5booGd51gzQnuAojX5ayoshLHknDyOGP6nYH60c03YS628G1QSOkabGmCoSZsyqLZcEuS/kFzLTK1Vlic6sAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/eb1bdf6a9a1523a7a0cdcd9593d6e90c/8ac56/aws-waf-web-acl-managed-rules.webp 240w,
/static/eb1bdf6a9a1523a7a0cdcd9593d6e90c/d3be9/aws-waf-web-acl-managed-rules.webp 480w,
/static/eb1bdf6a9a1523a7a0cdcd9593d6e90c/e46b2/aws-waf-web-acl-managed-rules.webp 960w,
/static/eb1bdf6a9a1523a7a0cdcd9593d6e90c/bf9e6/aws-waf-web-acl-managed-rules.webp 1203w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/eb1bdf6a9a1523a7a0cdcd9593d6e90c/8ff5a/aws-waf-web-acl-managed-rules.png 240w,
/static/eb1bdf6a9a1523a7a0cdcd9593d6e90c/e85cb/aws-waf-web-acl-managed-rules.png 480w,
/static/eb1bdf6a9a1523a7a0cdcd9593d6e90c/d9199/aws-waf-web-acl-managed-rules.png 960w,
/static/eb1bdf6a9a1523a7a0cdcd9593d6e90c/b9024/aws-waf-web-acl-managed-rules.png 1203w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/eb1bdf6a9a1523a7a0cdcd9593d6e90c/d9199/aws-waf-web-acl-managed-rules.png&quot;
            alt=&quot;AWS WAF Web ACL Managed Rules&quot;
            title=&quot;AWS WAF Web ACL Managed Rules&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Under AWS Managed Rules, enable the rules that you want to explore. For now I am going to try the Core Rule set to protect against many of the OWASP Top 10 list, and also the SQL database rule set to protect against the popular SQL injection attack.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 791px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/616080cf4c00a74559a576bb08b587e5/cc8d6/aws-waf-web-acl-managed-rules-selection.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 98.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAA7DAAAOwwHHb6hkAAADPklEQVQ4y4WUyW4bRxiE+Q5O5AgQ5diCtcza+zYz3EmLVnwIcsglef/H+IxuUnRsJMihUN095N//UtWzN1c31L1jtf/MuD7ghzWPrabqLVVvqLp/oLc8dZo6f+tM4d5EWuXpdOTDfcPsp7c3VE2PjxPWJ6wf0DZ+g0voMJ3YBHqhkdrS9QptPJvtHh8H4jDy8aFi9m5+y+gkq2lgMQSiMyRvSZmdIcZAWi6IKRCMJDqNN7Ksg7fEFBm8YYwe0zfM3t/eIrUnrY/YYcNT76lkpFIDlUpUwlN1uXzPU++4bzSNTrTScy8jmz/+Kq0SYUXbdszu3t3ijcL5RAiJEBPGekxaYMYV2nq0tmhjUdogpUIqjVIaKWSBkIq2E6iuYfbL9byU+HL8xOfnA/vNCmc0wZ7hDMGay9pbQ3S27KO3bFYLxhhYjom+bZi9eTvn7rGnUbGUVctAI2PZNyoVru1EPewKZwU0MlAJVzgsdkg3ovzE+495ylc3NL1hvXtmvTuy3h+xcaJqFXVvvkHYy7rqFFWnCz82siDv7+7rLJs59406NVV6hEn0GTrS6x/YL4oWhQl00iFMZH34jB9WhGnN3cM5wyfhCNuc2YJWOp5adRaz/h7CFj59P/FDLS4ZfigZXt2UzbTal/ErN5RM/wv5onxpIyyd8sRpU/6jw8jdySlzPtaK2i95bFSxViMcnQrFUgWlFZHOZm0GWmFLwBw4lyttKkFLD7OXG+lZHl4I44phuS23PZ3L+D+8lp+HdQ4456FWhGmLH3fExQ4TV7Qq0ulUTH/iE7JscvaNdPQ6lEfFpmXJtMjm+nqO04pxvSmedarHa/lN2D8iu0rL02+y0J0tTkveoLo6Pw5zxhTYfXphsz0UX/faI5T7V3RCo2xAaUtjE4c//2a73TNMK6Jqmf16e4tRCmEGhA6osEBNO0SY6KSlV55euQuaXpfzjKZTKOPLumolVjTMfn57w+Atv/925OV5x5fjgS/HPWOwRKtITn+H17PM+dmaki+8TB7Zvsqmkoi4vjS+N0MZynfQicYtirRaFaiztHRksTuiwwKbzkPJAR/y5NLqMv7CPyKfZy+fPfwqm8daXCSWZfMV35N8iuhM/tkAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/616080cf4c00a74559a576bb08b587e5/8ac56/aws-waf-web-acl-managed-rules-selection.webp 240w,
/static/616080cf4c00a74559a576bb08b587e5/d3be9/aws-waf-web-acl-managed-rules-selection.webp 480w,
/static/616080cf4c00a74559a576bb08b587e5/5f564/aws-waf-web-acl-managed-rules-selection.webp 791w&quot;
              sizes=&quot;(max-width: 791px) 100vw, 791px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/616080cf4c00a74559a576bb08b587e5/8ff5a/aws-waf-web-acl-managed-rules-selection.png 240w,
/static/616080cf4c00a74559a576bb08b587e5/e85cb/aws-waf-web-acl-managed-rules-selection.png 480w,
/static/616080cf4c00a74559a576bb08b587e5/cc8d6/aws-waf-web-acl-managed-rules-selection.png 791w&quot;
            sizes=&quot;(max-width: 791px) 100vw, 791px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/616080cf4c00a74559a576bb08b587e5/cc8d6/aws-waf-web-acl-managed-rules-selection.png&quot;
            alt=&quot;AWS WAF Web ACL Rules&quot;
            title=&quot;AWS WAF Web ACL Rules&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The rules are organized into groups and are maintained by AWS and AWS Marketplace sellers (Fortinet, Cloudbric, F5, etc.). For now, we can go with the defaults on the rest of the wizard.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/498d3ece67e702cdb91010ee944aa7cf/203d3/aws-waf-web-acl-list.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 35%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAA7DAAAOwwHHb6hkAAABUElEQVQoz33Qy27TUBSFYYMEQkJQiJpe4tuxfa72sY8Tk9gZdMKAAeJhUAGp6oBX/5HdqKWTDj4t7aWtPdhRuE9p/15g789Qdx8wdx8p/rxjc/uK+Pb1o+TXy+ad7PcbomvTsOlGyn5i47aLKxu4MC2XJ2vtOZcN52rmT/lkrRoudcO6MkSF2+GO3xD9Ddd2T+wOJyNJPS55pQdWReCz6PiUt0uuRHhQBN5nPW/jgbPUE5XS0e8OlKomzeUiTstnkqxaaOtpw4BxLZVyi7ys+TEl/Py+4uhjokLW9Icb/HbCtntcGCltT6E7ChMW5ZzKI12P8QOq3lKZbiFUx65zfJ0sTW2J8tJS9yO2n5B1j2u/YPwOaQPS/ceG05H28Zj1A03Yo/0e3R0RqiVKc0UsNIlsSIQmziRxVpGXhkSohzl/kpzMfSo0onKIyjK/bu7/Aab0zV2bVsR2AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/498d3ece67e702cdb91010ee944aa7cf/8ac56/aws-waf-web-acl-list.webp 240w,
/static/498d3ece67e702cdb91010ee944aa7cf/d3be9/aws-waf-web-acl-list.webp 480w,
/static/498d3ece67e702cdb91010ee944aa7cf/e46b2/aws-waf-web-acl-list.webp 960w,
/static/498d3ece67e702cdb91010ee944aa7cf/0ee79/aws-waf-web-acl-list.webp 1322w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/498d3ece67e702cdb91010ee944aa7cf/8ff5a/aws-waf-web-acl-list.png 240w,
/static/498d3ece67e702cdb91010ee944aa7cf/e85cb/aws-waf-web-acl-list.png 480w,
/static/498d3ece67e702cdb91010ee944aa7cf/d9199/aws-waf-web-acl-list.png 960w,
/static/498d3ece67e702cdb91010ee944aa7cf/203d3/aws-waf-web-acl-list.png 1322w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/498d3ece67e702cdb91010ee944aa7cf/d9199/aws-waf-web-acl-list.png&quot;
            alt=&quot;AWS WAF Web ACl list&quot;
            title=&quot;AWS WAF Web ACl list&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Now we need to associate this Web ACL to our AppRunner service. We could have
done this step directly while we were creating the web acl, but we can also
configure this association in the AppRunner service. Let’s go to the AppRunner
service and change the configuration.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/7b4bd6c979f8ba1d0160af39717d390e/0f586/aws-apprunner-edit-cfg.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 42.083333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABKElEQVQoz42Ra26DMBCEc4m0SdMQ2xiDXxgbTAI0VY/Q+19mKjsSUlEV9censXbl3dXMrqwtaNOCCIu3guNwong5Xv4Bwf5Q4Eyq/Ndrhu/pFTtaKRg3wg0zCFcZyjXIBloZMGE2dQXetBAqwFqDJVSPgToEWB8hbYBKtP0vUt31E4bpEz7O8OOMMC4rPk7o4gLWBOwoV+hud4TlC7IbofwV2vVQ1q8LZNsjxgg3LtDDAjPMMHGBiR/Q4ZqXajdAWv+4MHlQmYBSduDao9YO0nZI/laNxYXVKJ6Q+ozXOBORBmqQUkJIh4IIHN9pDudImqyngucQ9k8CSuEwWqKW3eNCoTx441bjWdJKZ021dOkzmEja5nf2MBnd3+6rF1u2If1F8r3WHX4AidrrNCxk17IAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/7b4bd6c979f8ba1d0160af39717d390e/8ac56/aws-apprunner-edit-cfg.webp 240w,
/static/7b4bd6c979f8ba1d0160af39717d390e/d3be9/aws-apprunner-edit-cfg.webp 480w,
/static/7b4bd6c979f8ba1d0160af39717d390e/e46b2/aws-apprunner-edit-cfg.webp 960w,
/static/7b4bd6c979f8ba1d0160af39717d390e/f992d/aws-apprunner-edit-cfg.webp 1440w,
/static/7b4bd6c979f8ba1d0160af39717d390e/72539/aws-apprunner-edit-cfg.webp 1498w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/7b4bd6c979f8ba1d0160af39717d390e/8ff5a/aws-apprunner-edit-cfg.png 240w,
/static/7b4bd6c979f8ba1d0160af39717d390e/e85cb/aws-apprunner-edit-cfg.png 480w,
/static/7b4bd6c979f8ba1d0160af39717d390e/d9199/aws-apprunner-edit-cfg.png 960w,
/static/7b4bd6c979f8ba1d0160af39717d390e/07a9c/aws-apprunner-edit-cfg.png 1440w,
/static/7b4bd6c979f8ba1d0160af39717d390e/0f586/aws-apprunner-edit-cfg.png 1498w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/7b4bd6c979f8ba1d0160af39717d390e/d9199/aws-apprunner-edit-cfg.png&quot;
            alt=&quot;AWS App Runner configuration&quot;
            title=&quot;AWS App Runner configuration&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In the Security panel, activate the WAF and select the Web ACL that we created.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/0e336c6ca2c59fd6d3af77d3aa4c12ba/5a190/aws-apprunner-activate-waf.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 99.58333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAA7DAAAOwwHHb6hkAAADKUlEQVQ4y4WU23KjOBCG/RRJfARsg0ASIIQ4B/Apm4w3lYt5/3f5p9R4kvFspfbiq1YLqemTeva4cLF0fMzXeyw2e6ycgFjeWLkB1h77Hpdh44V0d8dizB7mDkRa4ni5Iq1G7CIFP0zhRxaFHUvg7Pj/snIZPF9gZj0MeIas6JDkDaSqIFWJOKsInhhsA4ltEP8XXxLTTyMwoTB7Wnoo2xHPhxckukIYa4jUQKgCIi1IxlmJWJeQVt6wa5G3EKaFyEr4UYIozieDed2j7o8wzYBmOEGZhowneY1YV1+Q4S+dW2NlTz+1BndMTgar/oj+/Ip6PGO4vJFu2gGmHVF04209oGi/1nnTQzcDsu4EPVzApMbW55jNV1twVYJnFWTeQOgaLCkQfoP9JnVNxovugEjXEEUHJjNY58hDXXYouwPlJZT6DnuQiXs+85waRDIDjzMwrmA7Zva49FCc3nC+flC4/fkfymVWdoRUBXiiwZP8DzSi+MZtz1b4ceFMHkrTkvt1fyLKboSunumgvXRv7J4/DZKH1mCSlRR2alrqRZHV4GlBB0OZfUt0g8d6Ctl6aBu7P7/hx8dPXK//4v39HS+XE4a2QdEMKNuB+nRioL2i7qkocXOAqA+Q7ZGqfMuhi+x8hWkPqIxGqRVSlSNWBpIo7rCF4PEUKrOe2eL9HbLt8ETX4Mo2bINAaHj2WQWS5O+1uxcI4xypaeipWq+r7oC8eqbBYKOdzZcueFJgPP/A4XJF3R0pl9ObrpDmDeKshrSoEsq0MPUA04xoxxc0w4X0T4PMcyn5QrfgqqZp4wYJtiyFFyS0dv0YHktpz+qO1YMEXhCT93a4+GEytc167aFOOVUpLzrsbIg7TiEGXFGIQpU0XezlfZhgH6YUvh1X3t7ezegtfzZ2WPbYFGf4wwdW9SuxSHosk2dsshGOPmAuW8xFS9IzR4TtK/zqgqB+gWtO2IgCT1Nju1hwg4fQ4CEqsExarNIOC15gHubEE9MkF5EhuRIltqqFlzYkN3GNFUvxaD18mLsIeYrcNFBZCS+Q2Dg+HI99sWX3uhdg7fhYu5PcWN0NKORfiNBinPuTRncAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/0e336c6ca2c59fd6d3af77d3aa4c12ba/8ac56/aws-apprunner-activate-waf.webp 240w,
/static/0e336c6ca2c59fd6d3af77d3aa4c12ba/d3be9/aws-apprunner-activate-waf.webp 480w,
/static/0e336c6ca2c59fd6d3af77d3aa4c12ba/d00b9/aws-apprunner-activate-waf.webp 800w&quot;
              sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/0e336c6ca2c59fd6d3af77d3aa4c12ba/8ff5a/aws-apprunner-activate-waf.png 240w,
/static/0e336c6ca2c59fd6d3af77d3aa4c12ba/e85cb/aws-apprunner-activate-waf.png 480w,
/static/0e336c6ca2c59fd6d3af77d3aa4c12ba/5a190/aws-apprunner-activate-waf.png 800w&quot;
            sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/0e336c6ca2c59fd6d3af77d3aa4c12ba/5a190/aws-apprunner-activate-waf.png&quot;
            alt=&quot;AWS AppRunner Activate WAF&quot;
            title=&quot;AWS AppRunner Activate WAF&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Save changes and wait. It takes some time to update the service with the association.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/78ff7da3be51265087801e55486bdfdb/2b608/aws-apprunner-updating.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 17.916666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAq0lEQVQY043LPwuCUAAE8DeHVjpkPi1IXmqpkZhog6O1BRUNkSE4NyfRn7GvfaFCQ0k0/Dg47oj+3GFw30C9rdF/bCFfVxDyGGK+gFjmb8VWOFfalxiELk8QogxilIEPEjS8PTg/Aecf/sL7CVphimZwBB+kILZlwzBMqFSB0pVBJamW3Kl8dj1KYZkmdMbANA3E8eaw3RBs7JaGNYrenPgwnNnXpvyNpu//C2qefdTZ5F1vAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/78ff7da3be51265087801e55486bdfdb/8ac56/aws-apprunner-updating.webp 240w,
/static/78ff7da3be51265087801e55486bdfdb/d3be9/aws-apprunner-updating.webp 480w,
/static/78ff7da3be51265087801e55486bdfdb/e46b2/aws-apprunner-updating.webp 960w,
/static/78ff7da3be51265087801e55486bdfdb/f992d/aws-apprunner-updating.webp 1440w,
/static/78ff7da3be51265087801e55486bdfdb/96506/aws-apprunner-updating.webp 1540w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/78ff7da3be51265087801e55486bdfdb/8ff5a/aws-apprunner-updating.png 240w,
/static/78ff7da3be51265087801e55486bdfdb/e85cb/aws-apprunner-updating.png 480w,
/static/78ff7da3be51265087801e55486bdfdb/d9199/aws-apprunner-updating.png 960w,
/static/78ff7da3be51265087801e55486bdfdb/07a9c/aws-apprunner-updating.png 1440w,
/static/78ff7da3be51265087801e55486bdfdb/2b608/aws-apprunner-updating.png 1540w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/78ff7da3be51265087801e55486bdfdb/d9199/aws-apprunner-updating.png&quot;
            alt=&quot;AWS AppRunner Updating&quot;
            title=&quot;AWS AppRunner Updating&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;After updated with success, &lt;strong&gt;we are now  in conditions to start comparing the behavior of Juice Shop with and without WAF&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;testing-waf-with-sql-injection&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#testing-waf-with-sql-injection&quot; aria-label=&quot;testing waf with sql injection permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Testing WAF with SQL Injection&lt;/h2&gt;
&lt;p&gt;Let’s &lt;strong&gt;start by the well known SQL Injection attack in the login page to access
to the authenticated part of the web, even without knowing any login
credentials&lt;/strong&gt;. Starting with the unprotected version of the site that I am
running locally, go to the login page, and I just need to put &lt;code class=&quot;language-text&quot;&gt;&apos; OR 1=1--&lt;/code&gt; in
the Email text box, and in the Password text box we can put any value we want.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/372af790318aa7a84ee919267ce76983/5a190/juice-shop-login-sql-injection.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 96.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAACXBIWXMAAA7DAAAOwwHHb6hkAAACUElEQVQ4y52UW1PTQBhA+4NI0hYoNEmT7CWbpKWFYltaketYhGEcQN6UgjiOjqjjTz5O0uLwgNwezmx2v2/Pftlkt5QO3qB622zu9RntvmZ9/5i17TGt0R6t0S7JYAuxNrwX098i7m2SDPeLvGy4Q2l0fkX//Cs/Lw/5fjPh7ec/vLv6wcHlDUdffnN0/YuND1f0zyYMziZFe0vv9IL+6QW9k0/0TqZtaaHusVB3WazVqdRcqkv1gvnl/NmlWlumvLjEwrLLNPdhSrZlUWBbODnWDNvCmpvD8zzanVWCIMB13aJ/F9f1cGwb25orPKVyucz9VHAcm2Ys2Nsa0c40TSNoJZKWmZHIIl6tVnFm8/4rdJwy82WbbuKz3mmykkgyHZHFU5pxRKoFr9IGtfkKtuM8LqyWHVa1y3orZi2TtE1I20T/WDERXeOz+BRhjm3bBGFId71LHMdordBaFyilSIwhTdNZAU8Q5pvdaDSKSVIplJrJtC76+SJJkjxdaNsOQdig2UnIVnJZSMPzCIMGIgwQQhBGEZVK5YkVOg6e76OkJOkO6GyNGY6P6e6Mi1OkYoN4ttDzkFLSGYwYjY84ODln5/A9eq2H0jHRc4W+7xd7ZZQh0ympTpGBRPgRWulisWcL8w9hViOyDUFrQ9IaKrJBhDbq+cL8lUUkaB+67H/L2JxItq8Ng48+wgREoXhZhSJUaKkxsSm2QAQKJV9QYa1WKy6FulsnCH1COcX13Ol4vf74f5gHbxPy03KLZdlYc1bB3fHb3Lx9tMKH4vfl/gVLV4mKd+M5awAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/372af790318aa7a84ee919267ce76983/8ac56/juice-shop-login-sql-injection.webp 240w,
/static/372af790318aa7a84ee919267ce76983/d3be9/juice-shop-login-sql-injection.webp 480w,
/static/372af790318aa7a84ee919267ce76983/d00b9/juice-shop-login-sql-injection.webp 800w&quot;
              sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/372af790318aa7a84ee919267ce76983/8ff5a/juice-shop-login-sql-injection.png 240w,
/static/372af790318aa7a84ee919267ce76983/e85cb/juice-shop-login-sql-injection.png 480w,
/static/372af790318aa7a84ee919267ce76983/5a190/juice-shop-login-sql-injection.png 800w&quot;
            sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/372af790318aa7a84ee919267ce76983/5a190/juice-shop-login-sql-injection.png&quot;
            alt=&quot;Juice Shop Login SQL Injection&quot;
            title=&quot;Juice Shop Login SQL Injection&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;And here is the result&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/2bad5ab830c467840eb4445ba477af1f/bf433/juice-shop-login-sql-injection-success.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75.41666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAA7DAAAOwwHHb6hkAAADUklEQVQ4y3WR609bdRzG+1d4mcwFMhxSei69nUt7TtvTdlXZkBZwYVxKCzJZwckY6SJShI2lDjT6ziWEOCOZusAEdYmJErXOGZO9MHEx84WJWeILlmjMoi8m5mPOadnioid5zvO9POf5/n7n6xL8CpKiooYCKGYMxYghq2GEgEqLL4jHp9DiU2ocRFZCTj9gxPHpBgFNw2MdpDk9wuMdBVzdk6fInyjxxivHOTr7GkdKCzw3s8jI7Ktki/N0Pv8SXS+U6DpWReexaQ6NzzA4VXa0+RfL5KfKFIovM1oq4wqaEUIxAzMaQrUiaJaJFre5Gqv/A6df0+nxCEo8impFcQUibrrLCn2LIfoWdPoXqmyj96xWq+lkF8PV/KxG1xmZ9rlm0nNu2m3MNtM57+FA0Y3Lr0vEsyKJnERiQCI+IJLMe0nmZeIDOzWJRE5m/6DXgd2r9sW7SOREot0CLlGUcDd5aGpsRnBLiC1edj+8hz2P1NPY0MTe+sccbnh0L7serGPXA3XUPbTb0TTW76OxYZ+j2fneJUkioiSSH36WEyeLjI2PMzI2xoG2NgTRgz/gRxA8RK0YRwpHGS6MMFWaZm7+NJmODLIs4fV5Hba9XKIoIskyP2/d4vY2XP/xJvZz/sK7+LxeUqkUfr+f6ZkZp/77HYfYBg739BIOh0kkEui6jiAIuOyXz+fj2+++5/WVLzmz/Al/AUtvnccIG3RkMqiKwsRkkSuVq1Q+XeeDi6tsfrRJNpcjmUzS2tp6z9A+odfr5dr1G6xe/YZTQxPc2PiccysrPJl6gtFCAVVVGD8+yZUvKlQ213l7/2FWh06SHR4m054mk8mg69o9Q1mW+emXLX64WeHaxCi/Lq2xtLaKX5Kc6fbAUu3Kt/64w59bv3F7+2+6e3owTdO5sqZp2F7VfyjJvLm8zDvvr3PuwhrrX33N1NxpdD10V9zb38+ljy9zcWODS59t8t6Hl0l3HcI0DOLx+P2GEoqioKlBzGiMtp48zwwVSLUexLJixGIxZzGqqhLw+7GeeprOwQLpvjyWZf17KTuGhmFgRiIYhunE9vZCoRDhsOGIg8EgkUjE0djXtDXVftiJ7b5zQtvMDgRBdCbYsPNq7b9zoZbfr7G9/gGkkFyP9N7yCQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/2bad5ab830c467840eb4445ba477af1f/8ac56/juice-shop-login-sql-injection-success.webp 240w,
/static/2bad5ab830c467840eb4445ba477af1f/d3be9/juice-shop-login-sql-injection-success.webp 480w,
/static/2bad5ab830c467840eb4445ba477af1f/e46b2/juice-shop-login-sql-injection-success.webp 960w,
/static/2bad5ab830c467840eb4445ba477af1f/3697b/juice-shop-login-sql-injection-success.webp 971w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/2bad5ab830c467840eb4445ba477af1f/8ff5a/juice-shop-login-sql-injection-success.png 240w,
/static/2bad5ab830c467840eb4445ba477af1f/e85cb/juice-shop-login-sql-injection-success.png 480w,
/static/2bad5ab830c467840eb4445ba477af1f/d9199/juice-shop-login-sql-injection-success.png 960w,
/static/2bad5ab830c467840eb4445ba477af1f/bf433/juice-shop-login-sql-injection-success.png 971w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/2bad5ab830c467840eb4445ba477af1f/d9199/juice-shop-login-sql-injection-success.png&quot;
            alt=&quot;Juice Shop Login SQL Injection success&quot;
            title=&quot;Juice Shop Login SQL Injection success&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Basically I am authenticated as the administrator. The SQL injection attack was a success.&lt;/p&gt;
&lt;p&gt;Now let’s try to do the same in the version running in AWS with WAF protection.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 798px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/4ca171e68f7040cbf4302b3030015a78/898f6/juice-shop-login-sql-injection-failed.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 94.16666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAACXBIWXMAAA7DAAAOwwHHb6hkAAACNklEQVQ4y5WTW2/aQBCF/QuqQNP3pqVgG+MLIRGtItvrC8bcktBQKgGKquAE2kCQ+pRLG6UPRe1D+5NPtYtNUYEGP3weaXd89szOLJfcegJFEqAoChRZRiadRiqVws7zHTzb3kYikUCSkkwu8TSZnO2zuMXyuIyQxStewIsMj5dpEXuvD5DfK0LJ76NQPJix/wayVkBGzCGVyTLSQg7q7j54SUW+aECSFai7BXCdz1/RurrH759D3EwfMHz4hYsvUwR3UwzvfyC4+47W+AYn42ucjFYwvp7vtSe34GqnA1R7F5h8aKNzPkAzuMLx2Se8DUZoBiMcn12i3Omj3A3W4odUeufgsqIASRRASxd4ASLPQxT4eZQlCaoiQ1NkFhdha3IOUlaEJIpMh1M1DRRNU6Gx+BdVVVGvN9Dt9WA7Dizbhr2I48A0zTB3psOx7q6AismyjFKphEajDsuylqCiVJDmRv9w9LMOmuS6Lo6ODlm0/3HoOA4IIfEEqRPf95fEIgzDiO+wWqmCkLDUUIg6owd5njcX20jQti14ZRduyYHjhM7CO6SHxS7ZdgnKVRd+3YPjOtANE8SymVNiWdB1fTNB1m1VhaEbsCwblU4frcEEl7ffWKx2+2xsDCOOoKKwS6fdbL5r433vFMHgI7xaA3apzFxu3JRFQXpfhJiwCIGh6zANA8Q02XpsQTq40Yj4tRKqh2VU6l68wY42aaTPKp/PryV6ohsJLjp9jCj30ZL/N1arTPwBv/x8VQ0nt3MAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/4ca171e68f7040cbf4302b3030015a78/8ac56/juice-shop-login-sql-injection-failed.webp 240w,
/static/4ca171e68f7040cbf4302b3030015a78/d3be9/juice-shop-login-sql-injection-failed.webp 480w,
/static/4ca171e68f7040cbf4302b3030015a78/ce206/juice-shop-login-sql-injection-failed.webp 798w&quot;
              sizes=&quot;(max-width: 798px) 100vw, 798px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/4ca171e68f7040cbf4302b3030015a78/8ff5a/juice-shop-login-sql-injection-failed.png 240w,
/static/4ca171e68f7040cbf4302b3030015a78/e85cb/juice-shop-login-sql-injection-failed.png 480w,
/static/4ca171e68f7040cbf4302b3030015a78/898f6/juice-shop-login-sql-injection-failed.png 798w&quot;
            sizes=&quot;(max-width: 798px) 100vw, 798px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/4ca171e68f7040cbf4302b3030015a78/898f6/juice-shop-login-sql-injection-failed.png&quot;
            alt=&quot;Juice Shop Login SQL Injection failed&quot;
            title=&quot;Juice Shop Login SQL Injection failed&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;When we click in the Login button, nothing happens. Apparently &lt;strong&gt;WAF is blocking
the request&lt;/strong&gt;. Let’s confirm it in the Developer Tools.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/9f7d4e8b9ef70327c05dfe9fac4f23a4/b1c31/juice-shop-login-console-errors.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 44.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABzElEQVQoz12SWW/TQBSF82OiLE68zIzXOrHjJWmNIU4oQU1JUREQlRdoFYmH8uM/NBOgEg9H59yZq3PPLL318cTj6RufTz/Z/3jm8PRMd3zkzZfv7J9+0bw/ME9TpFL4vk+SJEgpUUohhEAFCUIolJAIKel5nkBJRZYviJKEKI5JLlLDruchhCSOY8bjMZZlGaN+v89gMGA4HDIcDoz+i57jOARBQNetWdY1dVUZzrIMvadTlWVJFEWmT6fTRqPRiOl0ih9EZpCuNXqu65rGpmmo65qqqgzneY7e08fSQ7SeTCbYtv2SbjA0bGqtdULdqFOsVkuKRUaezamqkqIozgnDiFXTUuiUcYzyFVPbNrAdx0BfjeM6OK77x1AplldLtrcf2NzcsWrXzGYz01DHPl1R8rqoaDUWFU22MFhdpCzjiCoMWc1yLrPyxbCsat7t7+h2e+qrV8znc3zpUgWS+7Lg4fqG4/4rh8uWbRjwNo7ZhqHRna/YhCGbKDwb6pfTd5bnM4pyzmKRk6YprucSC8FtnnHf7fi4+8R1XtAIl1YpWiVpfXWG1sp8Gw/Pc/89gJACvaZrzY5tMxmPmVoWE2titDUaYY1HZ/4PvwFkfS0JwyhYdgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/9f7d4e8b9ef70327c05dfe9fac4f23a4/8ac56/juice-shop-login-console-errors.webp 240w,
/static/9f7d4e8b9ef70327c05dfe9fac4f23a4/d3be9/juice-shop-login-console-errors.webp 480w,
/static/9f7d4e8b9ef70327c05dfe9fac4f23a4/e46b2/juice-shop-login-console-errors.webp 960w,
/static/9f7d4e8b9ef70327c05dfe9fac4f23a4/91d86/juice-shop-login-console-errors.webp 1413w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/9f7d4e8b9ef70327c05dfe9fac4f23a4/8ff5a/juice-shop-login-console-errors.png 240w,
/static/9f7d4e8b9ef70327c05dfe9fac4f23a4/e85cb/juice-shop-login-console-errors.png 480w,
/static/9f7d4e8b9ef70327c05dfe9fac4f23a4/d9199/juice-shop-login-console-errors.png 960w,
/static/9f7d4e8b9ef70327c05dfe9fac4f23a4/b1c31/juice-shop-login-console-errors.png 1413w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/9f7d4e8b9ef70327c05dfe9fac4f23a4/d9199/juice-shop-login-console-errors.png&quot;
            alt=&quot;Juice Shop Login Console Errors&quot;
            title=&quot;Juice Shop Login Console Errors&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;As soon as we open the developer tools, we can see some console errors, and we
notice that &lt;strong&gt;a &lt;code class=&quot;language-text&quot;&gt;POST&lt;/code&gt; request to the login endpoint is being blocked with a 403
Forbidden&lt;/strong&gt;. Let’s inspect what we got in the wire.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/cd06abbef8667cf780e87bbf08feecb4/8dd93/juice-shop-login-network.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 54.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACBElEQVQoz22S207bQBiE8yitFGITe70+7clOTBzbglCaquWiiFYVFz0IiYqboj7+V+0GaFVxMVpr1//s7MzMrr/fcn//jeufv/n884Hru1/svvzg4uaWq7sHprcfKMuKWlu0sTjX4qzFGotSCpmXpEKSJEvSJGGWigzjWrqTDVobjLU0TYNSmizLEMrh2hV1XVEURVhrpahVTVVXyFyS5zl5kSPznJkQgr7v2e/3DNst4zgGtG2LlJK0qInjY5bLJctlQiolosxI8wxR/EXqITJmXsW669jtdmyHgWEYmKaJ1WoVFNZlQSYkr17PqZWhXffBAmMsxriwOteglaEoykfC9ZrT04l+c8Lm5IRpHOm6jlQItlYxdOugzFvhMZ/PsVrTNpZKJo/ql8RxfCBsVw27/RvO319y9u6S8XRH41xQ6LShW62plUYbE9TEx8fUVY3WmlzmRFFMFMfBmkDonOXsYs/VzVf2Hz8xnp3TNAdCH4A2DikLyqqmKMswKGVOkgqSJA3K/N4zoX+GD2SaeoZxQ99vwp4/8754z4SQIXlrXRj03lnXIPPimSwQ+iR9HaqqCjUIqA4V8XVI05Qoijg6OsIYHfz239ZatFLh0jiOWCwWRNGCmR/ypC/hX0KPp4s9oXM+YYOv3dPlfmb2NPg/XiI8qImDGk/mq+UV+3D8mf/3D7yEZWjfOg+jAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/cd06abbef8667cf780e87bbf08feecb4/8ac56/juice-shop-login-network.webp 240w,
/static/cd06abbef8667cf780e87bbf08feecb4/d3be9/juice-shop-login-network.webp 480w,
/static/cd06abbef8667cf780e87bbf08feecb4/e46b2/juice-shop-login-network.webp 960w,
/static/cd06abbef8667cf780e87bbf08feecb4/61eb3/juice-shop-login-network.webp 1369w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/cd06abbef8667cf780e87bbf08feecb4/8ff5a/juice-shop-login-network.png 240w,
/static/cd06abbef8667cf780e87bbf08feecb4/e85cb/juice-shop-login-network.png 480w,
/static/cd06abbef8667cf780e87bbf08feecb4/d9199/juice-shop-login-network.png 960w,
/static/cd06abbef8667cf780e87bbf08feecb4/8dd93/juice-shop-login-network.png 1369w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/cd06abbef8667cf780e87bbf08feecb4/d9199/juice-shop-login-network.png&quot;
            alt=&quot;Juice Shop Login Network&quot;
            title=&quot;Juice Shop Login Network&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We can check in AWS Web ACL the Traffic Overview&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/7f29ac194c7138f92a8d9685cc70bfc8/cea38/aws-web-acl-traffic-overview.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 50.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABsUlEQVQoz4WS2XKcMBBF+YTYmQUYFmGJRSBAYjzj2VKJ8///dFJSJs7kJX44dftSXdKlW1GhBqRZaI1D1j1xKtgm5b+alsQ7r+KuJes4ZxMXrLc5hWho9IRsBqK06ii1wx+cq4GyNuSyp2qnoP57VnUUzUxSW8p6IHvpWe8km0wGjYsm9OYvmmilLKn7SeZ+kLh3tvadna/n76zNjS/tiafuxFPQ811PPOvzB74nGa/k840oUROl/UYxnsjGM/F4YdMdWNcLK+X4emello86IB9Qjmdpg0ZNbxlfr+HXCtkjaoM2C5XqKaqWRs90xoU5+Xn5uf2PKJWGwryRdQtp69i1jrSsiXdVWEKSS9JcskkFa7+EpPxN/KB3NklJlBaK0qcRDUlWsUkEK39bKkLtmzzbVHxKOFBIjd2fmPenoIfXA3Z2WOtwbo8ZLe3gUN2IqAequuelHhCq/+ubIYzIB4u0cSzHS3iH2liOxyP2cKEfF8xy5HK9Ba/HBW2PTMtb4I/3QWbvpz29eyMSSoclyHak7gxunpimGWMmxsEwjTNKz6jWIBsTEvm0Hv+QH71P+guwHB1jGoA7sAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/7f29ac194c7138f92a8d9685cc70bfc8/8ac56/aws-web-acl-traffic-overview.webp 240w,
/static/7f29ac194c7138f92a8d9685cc70bfc8/d3be9/aws-web-acl-traffic-overview.webp 480w,
/static/7f29ac194c7138f92a8d9685cc70bfc8/e46b2/aws-web-acl-traffic-overview.webp 960w,
/static/7f29ac194c7138f92a8d9685cc70bfc8/f992d/aws-web-acl-traffic-overview.webp 1440w,
/static/7f29ac194c7138f92a8d9685cc70bfc8/47b01/aws-web-acl-traffic-overview.webp 1644w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/7f29ac194c7138f92a8d9685cc70bfc8/8ff5a/aws-web-acl-traffic-overview.png 240w,
/static/7f29ac194c7138f92a8d9685cc70bfc8/e85cb/aws-web-acl-traffic-overview.png 480w,
/static/7f29ac194c7138f92a8d9685cc70bfc8/d9199/aws-web-acl-traffic-overview.png 960w,
/static/7f29ac194c7138f92a8d9685cc70bfc8/07a9c/aws-web-acl-traffic-overview.png 1440w,
/static/7f29ac194c7138f92a8d9685cc70bfc8/cea38/aws-web-acl-traffic-overview.png 1644w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/7f29ac194c7138f92a8d9685cc70bfc8/d9199/aws-web-acl-traffic-overview.png&quot;
            alt=&quot;AWS Web ACL Traffic Overview&quot;
            title=&quot;AWS Web ACL Traffic Overview&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We can even check some sample requests&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/0c483c2d54cf4ccfb1b5d6b54d66c9d7/7321b/aws-web-acl-sample-requests.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 67.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACJUlEQVQ4y32T2XKjMBBF+YhJZZKxjREgCbQggVgNzvL//3Sn1OBU8jDzcKoXWt1aLkkqG6TcoBAGKRN4erng6fc/eD7j1/MZT88niqN/vnLkQiPnGueMI1G2g1QOhdC4MIGsqPF6zulj9E+XgmyaCbxmEifp8afqaTgrFW0k5wqMK2qeSNPhKixSVoFxA8Y1slKDlRppqXGJMIlzJimfCwsmHS7ZnkvzCte8Ri4MXk4MybC8ww0rVDNAuQF100MdcBPA7YCyaohCWhTC0q72uIFQLWoboN1AzRM/rpQoaoe428q2qMxO/cB2X6im+xHHOqkd+VlZI/H9DKn3KVTUhMP/zrH4aFAdQyoTBwS0/Ur2aLh8FfyPWGP9BNvNKCtHx92xaMNGV0QNm26iBdr1x5HCFzH3kxFNWKhpvHPtR1Tx/poBrl2QFRWSdrihG2+INkwb+mnb7bzBhZnyy/0T0/YBFyYY38O2I4wfyD78Jkz7DmMQ4bWDUB7yG/E4UWuMP9BElAi9uDTEHhucM4HEDyt8v6IyAWleE5fDpoXC9QeaLK9bKDdC+QmV7cGEJblFvSbS9BAmoKxbZNziWu6/YRRxVhqKY5PHsEdzGsx2UhK2JbEn3XSHbScSZqTpb+h8C9PfUNoBYbojzG+w7QzjR3rNaA2tGWkNxX6k/zmZt0/M2wcRJTQsb/QYevmEHu8YlzfsNTvduFJdtOPtHdMa+aBHi9L6CzjKp5f58GXsAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/0c483c2d54cf4ccfb1b5d6b54d66c9d7/8ac56/aws-web-acl-sample-requests.webp 240w,
/static/0c483c2d54cf4ccfb1b5d6b54d66c9d7/d3be9/aws-web-acl-sample-requests.webp 480w,
/static/0c483c2d54cf4ccfb1b5d6b54d66c9d7/e46b2/aws-web-acl-sample-requests.webp 960w,
/static/0c483c2d54cf4ccfb1b5d6b54d66c9d7/2754d/aws-web-acl-sample-requests.webp 1184w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/0c483c2d54cf4ccfb1b5d6b54d66c9d7/8ff5a/aws-web-acl-sample-requests.png 240w,
/static/0c483c2d54cf4ccfb1b5d6b54d66c9d7/e85cb/aws-web-acl-sample-requests.png 480w,
/static/0c483c2d54cf4ccfb1b5d6b54d66c9d7/d9199/aws-web-acl-sample-requests.png 960w,
/static/0c483c2d54cf4ccfb1b5d6b54d66c9d7/7321b/aws-web-acl-sample-requests.png 1184w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/0c483c2d54cf4ccfb1b5d6b54d66c9d7/d9199/aws-web-acl-sample-requests.png&quot;
            alt=&quot;AWS Web ACL Sample requests&quot;
            title=&quot;AWS Web ACL Sample requests&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Here is the detail of the request that was blocked.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 911px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/1ff4d810b48fcff3886a70fa5a60120d/636c2/aws-web-acl-sample-requests-detail.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 77.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAC2UlEQVQ4y22UWY/iVhBGec5DmpmmGzDeF67xjleMDRizNE1H3WGkiaLR5DflJ3/RLQNJJnk4KsviHn1VrktvKOoYTnSMRB1j/iyoeBpKeHwWMRheef6BoYinkfy/9ATJgCDqECQdE9mEotuErNuQNM4Msv5v+LuRaGAsGqDzsnkP0xtNNHC4XVIZFnVL5MsGbbPBoW1w3LXE6bDHy35Hz+k8gsU8KKYL0w6hmg55epJiQVSmGE10aIaDvNrAn+dgjo9VWaA9vhLZokaclQjjDFMnRJrEOBwOqLdHLNctjKmH4VhFj7cpyhYE0aBW/TiHF2VwghibMkPbrIlVtUSRpSiyhGTLbI623aE5nLHaHmHaPkaC1gk5PK5qzhCmC8z8GLYXI0pyFGWNeZLBCyL4YUwE18rcCNYsoKpbDs2RhHywN+E8r+CGKZwgIbE/L+BGOWZ+cse+wn/D4R2ZzO9meBNyu6QxJOUGed0iKtaYeimYl0KbBhA1B6LeIekuJMOFbHoYCAb2pw/sX97waTD5Qagy5PUOVfsKP63okGIFkE0f4lXCq6DOMFZsTDQHD08KjucLXn/5Ff3H8X8TZlWLxfqIvN4jKbeYhQV0e06YTgzdjkg8khkJ+88qDucLTucP9AdCt9iiYtFi82VOl1vEiwZBWsNy03u6LqEHdRrSuw4P/WflKnzvWubCW0qekCdb7c5EuTmC+RmYn4N5Gc30lpJXjUVdy28XnN4+8EAt/0PIF5x/kKp5QbHaw3JjmiE/yNscSoxavdHNUMb7l9/xcfkNP/eHXNgtNlWFYbE+YL0/Y9mcECQ1nHABy0tphvxDjOS/4cKfPot4vXzHl6/f8PB5fP1zkEy6KXyGcbFCVm2Rlg3yqkVabjAvVnCjAjoLoNshYVDlC23j63uL9brBp0eaYSfj10ZSprDsAAbz7piEf78RhBPCdkOoLMK2mOHPPx4RuzoGYwN/AW/V3XEbH1emAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/1ff4d810b48fcff3886a70fa5a60120d/8ac56/aws-web-acl-sample-requests-detail.webp 240w,
/static/1ff4d810b48fcff3886a70fa5a60120d/d3be9/aws-web-acl-sample-requests-detail.webp 480w,
/static/1ff4d810b48fcff3886a70fa5a60120d/19a92/aws-web-acl-sample-requests-detail.webp 911w&quot;
              sizes=&quot;(max-width: 911px) 100vw, 911px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/1ff4d810b48fcff3886a70fa5a60120d/8ff5a/aws-web-acl-sample-requests-detail.png 240w,
/static/1ff4d810b48fcff3886a70fa5a60120d/e85cb/aws-web-acl-sample-requests-detail.png 480w,
/static/1ff4d810b48fcff3886a70fa5a60120d/636c2/aws-web-acl-sample-requests-detail.png 911w&quot;
            sizes=&quot;(max-width: 911px) 100vw, 911px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/1ff4d810b48fcff3886a70fa5a60120d/636c2/aws-web-acl-sample-requests-detail.png&quot;
            alt=&quot;AWS Web ACL Sample requests&quot;
            title=&quot;AWS Web ACL Sample requests&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The request was blocked by the rule
&lt;a href=&quot;https://docs.aws.amazon.com/waf/latest/developerguide/aws-managed-rule-groups-use-case.html#aws-managed-rule-groups-use-case-sql-db&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;SQLi_BODY&lt;/code&gt;&lt;/a&gt;. We can say that AWS WAF has prevented the SQL injection attack.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Let’s explore another attack vector.&lt;/p&gt;
&lt;h2 id=&quot;testing-waf-with-cross-site-scripting-xss&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#testing-waf-with-cross-site-scripting-xss&quot; aria-label=&quot;testing waf with cross site scripting xss permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Testing WAF with Cross-Site Scripting (XSS)&lt;/h2&gt;
&lt;p&gt;Now let’s try another common attack with XSS. Running locally, let’s go to the new customer page and register a new customer with the name &lt;code class=&quot;language-text&quot;&gt;&amp;lt;iframe src=&quot;javascript:alert(&apos;xss&apos;)&quot;&gt;&lt;/code&gt;. You should notice that there’s a client side validation for the email.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 721px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/996b356eba3299941c0bd2f4b24f5304/01dae/juice-shop-signup-email-validation.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 97.08333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAACXBIWXMAAA7DAAAOwwHHb6hkAAACaUlEQVQ4y5WTbW/TMBDH94GWxC2aEF2S+imuE+c5S9qOAdImhAQd8AIG3/6P7LRTu3VaefHXnS7Oz3e+u7PN96/oN3+x2vzG8O0X1vcPWN//cX5+e4/i7lD57cbFd3b/W/PlJ87OfQLP9+H5wVZb3/NH3/Nx7nlOQUAwmU4xmUydJZMJAkIQkNH6AcEZIQEIIQcKggCZMWjbFv2w3GpAmmWI4hjxnGJOKWazmTtLdiKBBZKjwNJkWDUV1l2LD0OP932H2qRIaAwtGFLJEYXhCNz712VoS9llan2rnM8dIFUJilSjyjQak6LONBacwQiGJJrBewrcway1b2dvDC98rDXFXZPjY6Fx2+RY1yWWVY7OaGSCopAMMpzBfynDKbGgAOIdQfyWoFgIrAqDQjAYFoNTCkopGGMQgkNKiTCMjpU8vtmbCcHlxRj0fAKpFBKtEVuIkBBCPIrzERhFR4DPS952OcswDINTWZaoqhJ1XUNr7YB5niOOY/i+/1pTRquUQlHkSNP0Mat92djRDI+NjNVCayit3by5UqU8KNnO5AsZPp9DuxWfb67x49M1rvsOy67F6qpFnRskjCLhFGkiX5rDJ8BthkYvcDNcYdlfoSwKJ5NqCM6cVCIRn1Ly/up1fY+u69zaDculaxQXHFwIJEr9xxuSAIkW0CaBzhS0UdBZAp5QCMWc5IIjii8R+K8CiQPmhUJZZKB8Di4ppBIwReZ8IUdgzE4CjgcYpxAJdwAmqANbMbG7gCOMLk8r2Vq7ZpxxmMy4ge7aDk3Toqpq6IUGYxzhKV0+AHIOY7bAzgIbVFX1uC3HgP8AO0qKxJpvohgAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/996b356eba3299941c0bd2f4b24f5304/8ac56/juice-shop-signup-email-validation.webp 240w,
/static/996b356eba3299941c0bd2f4b24f5304/d3be9/juice-shop-signup-email-validation.webp 480w,
/static/996b356eba3299941c0bd2f4b24f5304/c71bf/juice-shop-signup-email-validation.webp 721w&quot;
              sizes=&quot;(max-width: 721px) 100vw, 721px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/996b356eba3299941c0bd2f4b24f5304/8ff5a/juice-shop-signup-email-validation.png 240w,
/static/996b356eba3299941c0bd2f4b24f5304/e85cb/juice-shop-signup-email-validation.png 480w,
/static/996b356eba3299941c0bd2f4b24f5304/01dae/juice-shop-signup-email-validation.png 721w&quot;
            sizes=&quot;(max-width: 721px) 100vw, 721px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/996b356eba3299941c0bd2f4b24f5304/01dae/juice-shop-signup-email-validation.png&quot;
            alt=&quot;Juice Shop Email Validation&quot;
            title=&quot;Juice Shop Email Validation&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Instead of using the frontend, let’s hit directly the API endpoint using Postman&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/11ad9cfeee9ec03df36fb7a4ec438763/6a5c3/juice-shop-postman-xss-signup.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 54.58333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABEUlEQVQoz5WS4W7DIAyEeZItYBsbSKAoa7f3f7GbSLqt2tqp+fEJYdBxZ+PqqeP89o65dkwU8eIZr0Hw6q+EYzgzgWpEaw2tLdAoIArgKyH4Q7iUEkrJyDmhtoplLts+WgExw3sPf0SQhdHOF6xrR82KbIJkgpoFp7JT0kjB//Bz7vw0IbUVdb2gqmCxCCHCNE27O7+vY/8MzkwhqogpwWKECm+928Weg5lBQiAmuN47cilIppizIVsEhXDj0H87/C30VQtjeFfciGRzQ5krInkoewiNy4+Fbut/Ig9BnSva+QNFBSaMFAUp8ja1R4KPHnMUPHQ5ofYVzQQt6SZ6z8Uz/XREhEC8/bkhHu5EOjKgT65pN0xD24EKAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/11ad9cfeee9ec03df36fb7a4ec438763/8ac56/juice-shop-postman-xss-signup.webp 240w,
/static/11ad9cfeee9ec03df36fb7a4ec438763/d3be9/juice-shop-postman-xss-signup.webp 480w,
/static/11ad9cfeee9ec03df36fb7a4ec438763/e46b2/juice-shop-postman-xss-signup.webp 960w,
/static/11ad9cfeee9ec03df36fb7a4ec438763/f992d/juice-shop-postman-xss-signup.webp 1440w,
/static/11ad9cfeee9ec03df36fb7a4ec438763/83c5b/juice-shop-postman-xss-signup.webp 1646w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/11ad9cfeee9ec03df36fb7a4ec438763/8ff5a/juice-shop-postman-xss-signup.png 240w,
/static/11ad9cfeee9ec03df36fb7a4ec438763/e85cb/juice-shop-postman-xss-signup.png 480w,
/static/11ad9cfeee9ec03df36fb7a4ec438763/d9199/juice-shop-postman-xss-signup.png 960w,
/static/11ad9cfeee9ec03df36fb7a4ec438763/07a9c/juice-shop-postman-xss-signup.png 1440w,
/static/11ad9cfeee9ec03df36fb7a4ec438763/6a5c3/juice-shop-postman-xss-signup.png 1646w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/11ad9cfeee9ec03df36fb7a4ec438763/d9199/juice-shop-postman-xss-signup.png&quot;
            alt=&quot;Juice Shop API Users requests&quot;
            title=&quot;Juice Shop API Users requests&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The API endpoint is not validating the email field, and we were able to register
something in the database as a user that is not a valid email address. In fact
we are injecting a script&lt;/strong&gt;. Let’s see in the Administration screen, where the
list of users is shown, how this user is being displayed. Navigate as
administrator (by using sql injection) to &lt;a href=&quot;http://localhost:3000/#/administration&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://localhost:3000/#/administration&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a625075d09bc1df79865968fec70e132/4e814/juice-shop-administation-xss.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 45.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABt0lEQVQoz22RW2/aMBhA+R1t0cqt3ehQMlZIYEDsOCE3IMkCQ4yqm7aCkLr+/8czOawIbXs4sj/bOt/FFcsNSOYh/iLDiTPGwRxLBtw7/omemNL9JGk0b0pq9QbX13VqtQaXFxfctDvYKqIvAyqzxwO7/Te2h1/kP55Z7V9YfD8Qbp+IHnZED0/Ej3u85ZZ2+452u029XqdarXJ1dUnH6DGezvj885nl7oVKp/Oed3cdnIlDFAY4kwm2ZTEc2Aw0ts1wMMDq92k2m6Ws1Wpxe/uW2vUb8q8HwvkXeh8/0O12qZimiWkYRFFEURSEQchoNGIymTDWjMclQkrCMCSMIoQUDIfD8tzq35fJhRDYtk3FMExM08D1BH7koXwXKWWJ67p4nneKZ7MZ6/Wa1WpFmqYkSUKxXJarfmdZlhYaGKaJEA6JJ5iqo0ijlGI6nR5jKYnjmDzLmc/nLBYLojAsu9Jy/e4voSBVktiVyDOh7/vl/rXC18qSJC7Ro9KyIAj+FSZKkipBrI7Sc6FGC3VFeZ6zLAqyLD3d/0fokClJ4grUnxbPW9YJtXCz2ZzmmGVZiZ6f/jAt/A1uuD0ZGRfesQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/a625075d09bc1df79865968fec70e132/8ac56/juice-shop-administation-xss.webp 240w,
/static/a625075d09bc1df79865968fec70e132/d3be9/juice-shop-administation-xss.webp 480w,
/static/a625075d09bc1df79865968fec70e132/e46b2/juice-shop-administation-xss.webp 960w,
/static/a625075d09bc1df79865968fec70e132/3838e/juice-shop-administation-xss.webp 1335w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/a625075d09bc1df79865968fec70e132/8ff5a/juice-shop-administation-xss.png 240w,
/static/a625075d09bc1df79865968fec70e132/e85cb/juice-shop-administation-xss.png 480w,
/static/a625075d09bc1df79865968fec70e132/d9199/juice-shop-administation-xss.png 960w,
/static/a625075d09bc1df79865968fec70e132/4e814/juice-shop-administation-xss.png 1335w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/a625075d09bc1df79865968fec70e132/d9199/juice-shop-administation-xss.png&quot;
            alt=&quot;Juice Shop Administration XSS&quot;
            title=&quot;Juice Shop Administration XSS&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We are getting the alert box, which is exactly the script we have injected. &lt;strong&gt;The
XSS attack was succeeded, and we could run a malicious script on the
administration page&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Now let’s repeat the same API request in the version that is running behind WAF in AWS.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/2072d8323735a2a64a2ae90d6c47a3a4/e4611/juice-shop-postman-xss-signup-failed.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 54.58333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7CAAAOwgEVKEqAAAABe0lEQVQoz4WSyXLcMAxE9RG5xRmB+yZKM1I8FZ98zSVfk3O+/bnIKcuyPUkOXVxANhpoDClHcink6FnPle1yIcWA1ppxHFFKdYjIfbT46Svm4Qtq/MYw1cKyLKzbxrZ9Z11Xrtcr52UhhLATtgSfYdByQpZnxp+/8fMPhpxj/1hKoc6VusxM08RcK2Wa8D7gnPsvofr1B5meGGJMnSwGT06JpVZqyUwpEWJG2djLElG72k84PWC1Qith0EqRzht1fWROkWB0DxqtcFooTvDmH2QtWW+JQRvDoLUilMry9EydCtlbkrN4a7qqFo9W9STNhCPJbb0Z83ruhNZ58uWREgNzdCwpkL3rhK/lytHt8aPbbRqk93VoBuSpkua5j08zQD6UpHc1muA9PntscFjfYNE+4/MFYy3Dtq6klIgx7mtz3Tv7TsUogreKc7YErxGtUDsMMRVUU/jXYT02XYTiNSWYfh5HQd3513t417XDg9u4SDdnPN6/e/+2fwHmnDmgwOKqgwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/2072d8323735a2a64a2ae90d6c47a3a4/8ac56/juice-shop-postman-xss-signup-failed.webp 240w,
/static/2072d8323735a2a64a2ae90d6c47a3a4/d3be9/juice-shop-postman-xss-signup-failed.webp 480w,
/static/2072d8323735a2a64a2ae90d6c47a3a4/e46b2/juice-shop-postman-xss-signup-failed.webp 960w,
/static/2072d8323735a2a64a2ae90d6c47a3a4/94575/juice-shop-postman-xss-signup-failed.webp 1298w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/2072d8323735a2a64a2ae90d6c47a3a4/8ff5a/juice-shop-postman-xss-signup-failed.png 240w,
/static/2072d8323735a2a64a2ae90d6c47a3a4/e85cb/juice-shop-postman-xss-signup-failed.png 480w,
/static/2072d8323735a2a64a2ae90d6c47a3a4/d9199/juice-shop-postman-xss-signup-failed.png 960w,
/static/2072d8323735a2a64a2ae90d6c47a3a4/e4611/juice-shop-postman-xss-signup-failed.png 1298w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/2072d8323735a2a64a2ae90d6c47a3a4/d9199/juice-shop-postman-xss-signup-failed.png&quot;
            alt=&quot;Juice Shop XSS Failed&quot;
            title=&quot;Juice Shop XSS Failed&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We are being blocked with a 403 Forbidden as expected. Let’s check the WAF sample requests.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/4c134bf871534d729e9534063551a185/60b3a/aws-waf-web-acl-xss-sample.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 74.58333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACWElEQVQ4y42T2Y6bQBBF/Ql5iW3AbM2OWRvagPE+8XgURZMo35H/f71RlRclM5EmD1fdDdTpWwsTwwqgL7yH5rqLmeZgprmsqS4w1Vx8ntmYzu3HOjcEtJso5r6fGJYP3fT54HgJajVCqg3qdo26HSDVGm23geq2vFfdBrJd87emG8MNlrDcGNpCsKGJbnrQFh5mugM/zrE5nFGvRgzdCqfTEZfLBefzGbvtFof9HkPfo+86jEOPii5Va3hhhrnhglgMvEIFRLhE2fRIigayKjHuTnj59gO70zPyWqGoFZKsRpJVOD8dcf76isOXF/hR/h5IDwiYyxWSXKKsJNZ9h04pyLpCU9esVkq0jURVN0iLBlmlOI5K9g5IKVdqQLSsEC1rlO2AQvaIc8muk/ytJENFsLzWkIDXplyhVGA1nqDGI5ZVh7RcIcpbuGEB28/eyfIzOEEOx085nlgTw/axsAMYlgcRZuh3z2jXJ8jhgLjoYLgp5lbE0uz4L83tGLqTwPYSdkia3OePukwOh/0zhv0FanxCUnbw0wbBsoXl5wwhwF10pgttkXDJeA5NK4Bh+jycjpdifXjB8fLKQAI5YQk3qjjwX0D9BiRTxLk15TrYlogRFyskZc/pXt01vH4EnGsOm3oMNgH5hR1juggwM8NH7e71e0C4hgmvC3GroXH7U6ghLMvnlMnJ3cGf+7cNIdjMSvDJyGCKlJtKnIktYpAsN+KJjzOJ6APRN34q0coCv74LVHkCzQzhiIhSpoEku4LnyHLD/5LhRIhDHz9HDYEnMDOoKQK/AVaxtA5EPr7UAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/4c134bf871534d729e9534063551a185/8ac56/aws-waf-web-acl-xss-sample.webp 240w,
/static/4c134bf871534d729e9534063551a185/d3be9/aws-waf-web-acl-xss-sample.webp 480w,
/static/4c134bf871534d729e9534063551a185/e46b2/aws-waf-web-acl-xss-sample.webp 960w,
/static/4c134bf871534d729e9534063551a185/58f5f/aws-waf-web-acl-xss-sample.webp 1179w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/4c134bf871534d729e9534063551a185/8ff5a/aws-waf-web-acl-xss-sample.png 240w,
/static/4c134bf871534d729e9534063551a185/e85cb/aws-waf-web-acl-xss-sample.png 480w,
/static/4c134bf871534d729e9534063551a185/d9199/aws-waf-web-acl-xss-sample.png 960w,
/static/4c134bf871534d729e9534063551a185/60b3a/aws-waf-web-acl-xss-sample.png 1179w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/4c134bf871534d729e9534063551a185/d9199/aws-waf-web-acl-xss-sample.png&quot;
            alt=&quot;AWS WAF XSS Sample Request&quot;
            title=&quot;AWS WAF XSS Sample Request&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This request was blocked by the rule &lt;code class=&quot;language-text&quot;&gt;CrossSiteScripting_BODY&lt;/code&gt;. We can say that WAF has prevented the XSS attack as expected&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;We can continue our exploration of other attack vectors by visiting each Juice
Shop challenge and check if AWS WAF helps to protect against them in some way.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;A Web Application Firewall (WAF) is definitely a tool that we should consider
using in front of our public face apps and services&lt;/strong&gt;. Not having a WAF, is like
riding a mountain bike without a helmet. We should always remember that &lt;strong&gt;a WAF
is our first line of defense, but it doesn’t prevent all attacks&lt;/strong&gt;. As
developers, we should write our apps with the OWASP Top 10 list in mind to be
sure that our app is secure, even without a WAF.&lt;/p&gt;
&lt;p&gt;AWS WAF is the natural adoption for workloads running in AWS and it supports out of the box many rules to protect against common attacks. The Web ACLs need to be tweaked for the app that is going to be protected.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;As a final message, consider seriously using a WAF in front of your public apps. It’s something that you won’t regret, even if it costs you some money. But I’m sure that it will cost you even more if you are a victim of a cyber attack.&lt;/strong&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Using AWS Cognito for Service-to-Service Authorization in ASP.NET Core]]></title><description><![CDATA[In this blog post I will show how AWS Cognito can be used for Service to Service Authorization in ASP.NET Core.
]]></description><link>https://bfcamara.com/posts/aws-cognito-service2service-auth/</link><guid isPermaLink="false">https://bfcamara.com/posts/aws-cognito-service2service-auth/</guid><pubDate>Mon, 12 Feb 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In a Microservices architecture, we typically observe the number of services
increasing as a result of an organic growth, and some services start talking
with other services. Ideally the inter-services communication should be
asynchronous following a publish-subscribe pattern, but in practice we have some
services that need to follow a request-reply pattern.&lt;/p&gt;
&lt;p&gt;This is typically the case when we have &lt;strong&gt;&lt;a href=&quot;https://samnewman.io/patterns/architectural/bff/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Backends-for-Frontends
(BFF)&lt;/a&gt; acting as separate API
gateways for each front-end client. These BFFs need to talk to other services&lt;/strong&gt;,
typically issuing queries to fetch data, or commands to perform business actions
being handled by the downstream service. &lt;strong&gt;Most of the time these interactions
are made through REST APIs&lt;/strong&gt;, and &lt;strong&gt;we need to have a way to authorize these
requests, even if all these services are running within the internal network
perimeter&lt;/strong&gt; with restrictions from the outside world, &lt;strong&gt;following a &lt;a href=&quot;https://www.cloudflare.com/learning/security/glossary/what-is-zero-trust/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Zero
Trust&lt;/a&gt;
strategy&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Besides BFFs, another scenario where we need to authorize a service is when we
have &lt;strong&gt;external services running on-premise, outside of the cloud, and there’s no
human interaction in these services, for example having a windows service that
collects some data from on-premise installations and send it to a service that
lives in the cloud&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;oauth-20---client-credentials-grant-flow-&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#oauth-20---client-credentials-grant-flow-&quot; aria-label=&quot;oauth 20   client credentials grant flow  permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;OAuth 2.0 - Client Credentials Grant flow 🔒&lt;/h2&gt;
&lt;p&gt;There are several solutions to implement &lt;strong&gt;Service-to-Service authorization&lt;/strong&gt;,
known also as &lt;strong&gt;Machine to Machine (M2M) authorization&lt;/strong&gt;, such as API keys,
Mutual TLS, OAuth, etc. In this post I want to explore using &lt;strong&gt;&lt;a href=&quot;https://oauth.net/2/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;OAuth
2.0&lt;/a&gt; with the &lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc6749#section-4.4&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Client Credentials Grant
flow&lt;/a&gt;&lt;/strong&gt; in the
context of &lt;strong&gt;ASP.NET Core&lt;/strong&gt; and &lt;strong&gt;&lt;a href=&quot;https://aws.amazon.com/cognito/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Amazon
Cognito&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/f003aaae0e73b959366bf89fe871a81e/ddb69/oauth-client-credentials.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 64.16666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABuElEQVQoz32SPYsaQRzG/XipAkmTJgkpjoTANQeHRQgBCdgknZ/BBBWE2RfcRUhjpygE7W1EXce92ZfZnff9B3cuInLcrxtmfvM8u/9ptNvt4XDY7XZ/X2CX/X5/MBj0er1fNZe7CKFms9lYLBYAYIyBmqqqAMAL/mz3OC/KnJZKP26dUUqdznheYzqdAoCUUv9HKXWMH4QQt/ffXr65ubltkiTVWjPGjTFaa845ADiO05jP55fJACCEYIwBwIfP9y9evX/38S5+IHWAuk6+krXWhJCiLAHgS+vH67efvn7/SYvSGPOcbL82juPD4VDWcnTAi7+rzXYPAFxI6zwha60BgFKKMcbHY5bnSmrORZrlnHMpFefi3O7pZIwxISTLMniWa1kpxRhLkkRKaftfYW+vqsoYcy2XNYQQKyulzmOzbRlj9gyl1M7iJM9ms9O/iaLlcpnneZqm+/1+s9lst9soina7HcaYUhrH8Xq9Xq1WSZJY+TRn+8KKomCMSSmFEJdVz0tZY7tIKR+TO53OeDxGCHmehxDyfT8Mw6BmNBr5vh8EQRiGnuc5juO6LkLIdd3JZNJqtf4BWS+zzVWjrHcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/f003aaae0e73b959366bf89fe871a81e/8ac56/oauth-client-credentials.webp 240w,
/static/f003aaae0e73b959366bf89fe871a81e/d3be9/oauth-client-credentials.webp 480w,
/static/f003aaae0e73b959366bf89fe871a81e/e46b2/oauth-client-credentials.webp 960w,
/static/f003aaae0e73b959366bf89fe871a81e/f992d/oauth-client-credentials.webp 1440w,
/static/f003aaae0e73b959366bf89fe871a81e/882b9/oauth-client-credentials.webp 1920w,
/static/f003aaae0e73b959366bf89fe871a81e/7672f/oauth-client-credentials.webp 2684w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/f003aaae0e73b959366bf89fe871a81e/8ff5a/oauth-client-credentials.png 240w,
/static/f003aaae0e73b959366bf89fe871a81e/e85cb/oauth-client-credentials.png 480w,
/static/f003aaae0e73b959366bf89fe871a81e/d9199/oauth-client-credentials.png 960w,
/static/f003aaae0e73b959366bf89fe871a81e/07a9c/oauth-client-credentials.png 1440w,
/static/f003aaae0e73b959366bf89fe871a81e/29114/oauth-client-credentials.png 1920w,
/static/f003aaae0e73b959366bf89fe871a81e/ddb69/oauth-client-credentials.png 2684w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/f003aaae0e73b959366bf89fe871a81e/d9199/oauth-client-credentials.png&quot;
            alt=&quot;OAuth2 - Client Credentials flow&quot;
            title=&quot;OAuth2 - Client Credentials flow&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;OAuth 2.0 Client Credentials Grant flow explained&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;When the Client (&lt;code class=&quot;language-text&quot;&gt;MyBFF&lt;/code&gt;) needs to call the Resource Server (&lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt;), if
it doesn’t have a valid access token yet, makes a request to the
Authorization Server (AWS Cognito) passing tthe &lt;code class=&quot;language-text&quot;&gt;client_id&lt;/code&gt; and
&lt;code class=&quot;language-text&quot;&gt;client_secret&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Amazon Cognito validates the request and returns the &lt;code class=&quot;language-text&quot;&gt;access_token&lt;/code&gt; with a
given expiration in &lt;code class=&quot;language-text&quot;&gt;expires_in&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;MyBFF&lt;/code&gt; calls &lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt; to get some data, passing the &lt;code class=&quot;language-text&quot;&gt;access_token&lt;/code&gt; as a
&lt;code class=&quot;language-text&quot;&gt;Bearer&lt;/code&gt; token in the &lt;code class=&quot;language-text&quot;&gt;Authorization&lt;/code&gt; header&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt; validates the request and returns the data if the &lt;code class=&quot;language-text&quot;&gt;Bearer&lt;/code&gt; token
is valid.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;amazon-cognito-setup-️&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#amazon-cognito-setup-%EF%B8%8F&quot; aria-label=&quot;amazon cognito setup ️ permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Amazon Cognito Setup ☁️&lt;/h2&gt;
&lt;p&gt;To setup Amazon Cognito for our scenario we need the following resources:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A &lt;strong&gt;User Pool&lt;/strong&gt; - even though we won’t have real users in this pool, a User
Pool is the materialization of an &lt;strong&gt;Authorization Server&lt;/strong&gt; in OAuth lingo&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;Cognito domain&lt;/strong&gt; - &lt;strong&gt;exposes the authorization server&lt;/strong&gt; OAuth endpoints in
a domain&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;Resource Server&lt;/strong&gt; - &lt;strong&gt;it represents &lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt;&lt;/strong&gt;. We will have as many
resource servers as the number of services.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;Client&lt;/strong&gt; - &lt;strong&gt;it represents the Backend-for-Frontend &lt;code class=&quot;language-text&quot;&gt;MyBFF&lt;/code&gt;&lt;/strong&gt;. We will have
as many clients as the number of services that are calling other services.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I’m going to use &lt;a href=&quot;https://docs.aws.amazon.com/cloudformation/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;CloudFormation&lt;/a&gt;
to create all these resources instead of AWS console because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I love CloudFormation - I don’t care if I’m locked in to AWS. The truth is
that &lt;strong&gt;CloudFormation is so simple and so powerful&lt;/strong&gt; that I discard any other
IaC alternative when managing resources inside AWS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Amazon Cognito in console is not very intuitive&lt;/strong&gt;. In fact I think that’s
one of the disadvantages of Amazon Cognito, when comparing with other
solutions like Auth0 (considered by many as the best solution in the market in
this field). I think Amazon Cognito still needs to be polished to remove some
friction when used by developers and cloud architects.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;creating-a-user-pool&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#creating-a-user-pool&quot; aria-label=&quot;creating a user pool permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Creating a User Pool&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;  &lt;span class=&quot;token comment&quot;&gt;# Create a user pool&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;MyServicesUserPool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; AWS&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;Cognito&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;UserPool
    &lt;span class=&quot;token key atrule&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;UserPoolName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;MyServicesUserPool&quot;&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;# Disable Self-Service Account Recovery&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;AccountRecoverySetting&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;RecoveryMechanisms&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; admin_only
            &lt;span class=&quot;token key atrule&quot;&gt;Priority&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;# Disable Self-Service Signup&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;AdminCreateUserConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;AllowAdminCreateUserOnly&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;# Just in case a user is created by admin&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;MfaConfiguration&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ON&quot;&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;EnabledMfas&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; SOFTWARE_TOKEN_MFA&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The important thing here to notice is that I have disabled all self-service
operations from end-users since we won’t have any users registered in the pool.
We can check the result in AWS console.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/e9a99c6bb16e40f5c9b63bab459feefd/df56e/aws-user-pool.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 61.24999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABiklEQVQoz3VSa2/bMAz0//99+zCgWZpmdWPrSepJUrEzyGrWYdgIQiIPPAm600REN23Ps/pQ5rroeVHLqhalPWKI8Z+JIYyc7vf7+zy//Di/vr2dzq/ny+WmDIYYYvgfUxmjtAHASVoLMSmll1VpY0WYiIj/jo7Isz4ilzIxcwAbwEawXNO2bfu+iTQmvrcRdxFprZVSmHlAj30noomZzPtpPn1bL9+TmR9HiIg2xlrnvTfWppRaawAAiJVIRB6PBzNPLJJLjTHlUkqtg7xt29FVItr3fSDhEKnWyn+SU8pE1GePaSKq9av5hJ5C1CeSc55EBBFvt9v1+tNYyyLEX5qNfbTE3K994imlqbXmAI1H55x1Xmm9am2dU8asSvVCa+Oc7vZo533HtXYAIcZO1tZ9LCtgNxYQATHGiIgeIKY0WmOdsTbE6DwYa+H4Qt1nRFzX1UEYLy2ldPEOwcZaiUopn28RGUenlLtgMaUQg7UOEQHQOe88OO9j6hbknHPJv1WrtQuWSwkp/QIR860URkCbpQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/e9a99c6bb16e40f5c9b63bab459feefd/8ac56/aws-user-pool.webp 240w,
/static/e9a99c6bb16e40f5c9b63bab459feefd/d3be9/aws-user-pool.webp 480w,
/static/e9a99c6bb16e40f5c9b63bab459feefd/e46b2/aws-user-pool.webp 960w,
/static/e9a99c6bb16e40f5c9b63bab459feefd/7592c/aws-user-pool.webp 1188w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/e9a99c6bb16e40f5c9b63bab459feefd/8ff5a/aws-user-pool.png 240w,
/static/e9a99c6bb16e40f5c9b63bab459feefd/e85cb/aws-user-pool.png 480w,
/static/e9a99c6bb16e40f5c9b63bab459feefd/d9199/aws-user-pool.png 960w,
/static/e9a99c6bb16e40f5c9b63bab459feefd/df56e/aws-user-pool.png 1188w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/e9a99c6bb16e40f5c9b63bab459feefd/d9199/aws-user-pool.png&quot;
            alt=&quot;AWS Cognito - User Pool&quot;
            title=&quot;AWS Cognito - User Pool&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In the &lt;strong&gt;Sign-in experience&lt;/strong&gt; tab&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b13760fe5d873bcdef06447baaa1be84/7798c/aws-cognito-user-pool-signin.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 44.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA/UlEQVQoz4WRCWvDMAyF8///42A53JQ08SXJOkqaLs46sgP28TBYNk9PdsPCGRCJiAogIRKLMO8S0T/FLKUwEjaiOt2mtuucc+9t2/VDTAAIGQCwmhZC2k3ritWfYtovNSxCpTCzqt7vd9vRL0SEiJj5XDWzdV2ZuRGRDBBiNLNt2x4ntm0zs2VZAHCt+0/VI1HdO4eYQkw+RB8i1Bg/RGWHXkKilHMGaFjU+2V0w3hxzg0+Jjpm+w4R2QtVPUoNM8/uLVy7PI9p6jnd1sdj/cUR9cwRm+drH+ZrgQhhwrTo+cVOyElqRqXUr5qXwV3afvAZ1Uz+o5Tivf+Y+QmznQaOYv8dLAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/b13760fe5d873bcdef06447baaa1be84/8ac56/aws-cognito-user-pool-signin.webp 240w,
/static/b13760fe5d873bcdef06447baaa1be84/d3be9/aws-cognito-user-pool-signin.webp 480w,
/static/b13760fe5d873bcdef06447baaa1be84/e46b2/aws-cognito-user-pool-signin.webp 960w,
/static/b13760fe5d873bcdef06447baaa1be84/62502/aws-cognito-user-pool-signin.webp 1183w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/b13760fe5d873bcdef06447baaa1be84/8ff5a/aws-cognito-user-pool-signin.png 240w,
/static/b13760fe5d873bcdef06447baaa1be84/e85cb/aws-cognito-user-pool-signin.png 480w,
/static/b13760fe5d873bcdef06447baaa1be84/d9199/aws-cognito-user-pool-signin.png 960w,
/static/b13760fe5d873bcdef06447baaa1be84/7798c/aws-cognito-user-pool-signin.png 1183w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/b13760fe5d873bcdef06447baaa1be84/d9199/aws-cognito-user-pool-signin.png&quot;
            alt=&quot;AWS Cognito - User Pool Signin experience&quot;
            title=&quot;AWS Cognito - User Pool Signin experience&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In the &lt;strong&gt;Sign-up experience&lt;/strong&gt; tab&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/75f44ed524796bf63bd2ea44070bb996/e72de/aws-cognito-user-pool-signup.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 22.499999999999996%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAIAAADKYVtkAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAg0lEQVQY043NyQ7DIAxFUf7/D7sNpYTghJBgm0EiFSidFlV7dOXdk0VALKXkLqX4hIjhETFzjO/FfoWFeZBKaS2VXvxOREinPjnxp3X1q/fCgZm0tON1AbuH9q/tEUMIOefyReqEGS5gbuhM3OBo6vGfWqtYJuVg9DBubmZORPyKf3QHiBsgpYCzsckAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/75f44ed524796bf63bd2ea44070bb996/8ac56/aws-cognito-user-pool-signup.webp 240w,
/static/75f44ed524796bf63bd2ea44070bb996/d3be9/aws-cognito-user-pool-signup.webp 480w,
/static/75f44ed524796bf63bd2ea44070bb996/e46b2/aws-cognito-user-pool-signup.webp 960w,
/static/75f44ed524796bf63bd2ea44070bb996/40d0b/aws-cognito-user-pool-signup.webp 1198w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/75f44ed524796bf63bd2ea44070bb996/8ff5a/aws-cognito-user-pool-signup.png 240w,
/static/75f44ed524796bf63bd2ea44070bb996/e85cb/aws-cognito-user-pool-signup.png 480w,
/static/75f44ed524796bf63bd2ea44070bb996/d9199/aws-cognito-user-pool-signup.png 960w,
/static/75f44ed524796bf63bd2ea44070bb996/e72de/aws-cognito-user-pool-signup.png 1198w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/75f44ed524796bf63bd2ea44070bb996/d9199/aws-cognito-user-pool-signup.png&quot;
            alt=&quot;AWS Cognito - User Pool Signup experience&quot;
            title=&quot;AWS Cognito - User Pool Signup experience&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;setting-a-cognito-domain&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#setting-a-cognito-domain&quot; aria-label=&quot;setting a cognito domain permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Setting a Cognito domain&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;  &lt;span class=&quot;token comment&quot;&gt;# Creates a domain with oauth endpoints&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;MyServicesUserPoolDomain&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; AWS&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;Cognito&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;UserPoolDomain
    &lt;span class=&quot;token key atrule&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;Domain&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; replace&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;your&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;domain&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;here
      &lt;span class=&quot;token key atrule&quot;&gt;UserPoolId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;!Ref&lt;/span&gt; MyServicesUserPool&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We are using a AWS Cognito domain:
&lt;code class=&quot;language-text&quot;&gt;https://[replace-your-domain-here].auth.us-east-1.amazoncognito.com&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/badf4c87d2a78a101e7d54cbf75a3617/a3767/aws-cognito-domain.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 41.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAA7DAAAOwwHHb6hkAAABIklEQVQY022P227EMAhE9///sWq7ycaJbTBg7DjOrXXSfesI0BESmuFRayVmFglELIKBMARiBgyAeAESi0UGFmLyiIAYVVnkUdfVeW/GyUzTZO3LGOs9huC8d2+YvP/sTW8sANhrzyLXca2vYXh23WDMd9c9+94BeIDbwQNAAwC8lgAQAoa/UI9aV4/gvI8pz6XMpeR5zvOccv63NKVAJDFKjC12IBrMgO1pCiEQNYgxqqaUcuucVTW2iiJyx46qLTb5EccOxj6RzewSucSuRFw05CSqSVW3bdvfOo5j3/freClj92GdZ+ZSytJU6rKUspSsAqOmXEo5juM8z3veUk2PpS5u+BKcIlqBUWDkazZwwxzpOM9937dLtdZ1XW/+df4B+/nFY9EcO58AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/badf4c87d2a78a101e7d54cbf75a3617/8ac56/aws-cognito-domain.webp 240w,
/static/badf4c87d2a78a101e7d54cbf75a3617/d3be9/aws-cognito-domain.webp 480w,
/static/badf4c87d2a78a101e7d54cbf75a3617/e46b2/aws-cognito-domain.webp 960w,
/static/badf4c87d2a78a101e7d54cbf75a3617/efe91/aws-cognito-domain.webp 1210w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/badf4c87d2a78a101e7d54cbf75a3617/8ff5a/aws-cognito-domain.png 240w,
/static/badf4c87d2a78a101e7d54cbf75a3617/e85cb/aws-cognito-domain.png 480w,
/static/badf4c87d2a78a101e7d54cbf75a3617/d9199/aws-cognito-domain.png 960w,
/static/badf4c87d2a78a101e7d54cbf75a3617/a3767/aws-cognito-domain.png 1210w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/badf4c87d2a78a101e7d54cbf75a3617/d9199/aws-cognito-domain.png&quot;
            alt=&quot;AWS Cognito UserPool Domain&quot;
            title=&quot;AWS Cognito UserPool Domain&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: We could have used a custom domain instead of a Amazon Cognito domain,
which requires  adding some DNS records to your DNS zone.&lt;/p&gt;
&lt;h3 id=&quot;creating-a-resource-server-for-myservice&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#creating-a-resource-server-for-myservice&quot; aria-label=&quot;creating a resource server for myservice permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Creating a Resource Server for &lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt;&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;  &lt;span class=&quot;token comment&quot;&gt;# Resource Server for MyService&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;MyServiceUserPoolResourceServer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; AWS&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;Cognito&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;UserPoolResourceServer
    &lt;span class=&quot;token key atrule&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;Identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; MyService
      &lt;span class=&quot;token key atrule&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; MyService
      &lt;span class=&quot;token comment&quot;&gt;# Organize scopes&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;Scopes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;ScopeName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; weather_read
          &lt;span class=&quot;token key atrule&quot;&gt;ScopeDescription&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Grants the ability to read weather
      &lt;span class=&quot;token key atrule&quot;&gt;UserPoolId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;!Ref&lt;/span&gt; MyServicesUserPool&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can &lt;strong&gt;register whatever scopes we want to support in our service&lt;/strong&gt;. In this
case we are just registering one scope &lt;code class=&quot;language-text&quot;&gt;MyService/weather_read&lt;/code&gt; that grants the
ability to read weather data from &lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt; (which will expose an endpoint to
retrieve weather data).&lt;/p&gt;
&lt;p&gt;We can check the result in the &lt;strong&gt;App Integration&lt;/strong&gt; tab&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/591194587c8c24be26d2d27469e430d5/c929c/aws-cognito-resource-server.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 28.750000000000004%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA9ElEQVQY0y3QyW7EIAyA4bz/C1Zd0iFLcdhtMBCglapk5jv44F/ywRMSAoAEMMaEmHKptZanekuJETFgQCIkcs6HEFJKnPMUY7TOW+evHWKMMV34NZmJ6C7IzKXWXErO1+nEPJWSCydCJAwxxVJy7623y3nWWs8+xhi/rfc+xpVe9WTmCZRat/Xj/e0xf/7AQe3P52ZiEVLvJiilrNGl5NEbMwup5/3AOkJplHg6lBLruu27BKmdM5QNsSHWmCxGtX3BOvtjTRbsz3w4Dw7vGiPzpLQWyyKWRQI47+2Ts957Z43cHnITcn/ALuT27W7e++fD/gFD9VBaDOJhAQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/591194587c8c24be26d2d27469e430d5/8ac56/aws-cognito-resource-server.webp 240w,
/static/591194587c8c24be26d2d27469e430d5/d3be9/aws-cognito-resource-server.webp 480w,
/static/591194587c8c24be26d2d27469e430d5/e46b2/aws-cognito-resource-server.webp 960w,
/static/591194587c8c24be26d2d27469e430d5/491b1/aws-cognito-resource-server.webp 1218w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/591194587c8c24be26d2d27469e430d5/8ff5a/aws-cognito-resource-server.png 240w,
/static/591194587c8c24be26d2d27469e430d5/e85cb/aws-cognito-resource-server.png 480w,
/static/591194587c8c24be26d2d27469e430d5/d9199/aws-cognito-resource-server.png 960w,
/static/591194587c8c24be26d2d27469e430d5/c929c/aws-cognito-resource-server.png 1218w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/591194587c8c24be26d2d27469e430d5/d9199/aws-cognito-resource-server.png&quot;
            alt=&quot;AWS Cognito Resource Server&quot;
            title=&quot;AWS Cognito Resource Server&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;create-a-client-for-mybff&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#create-a-client-for-mybff&quot; aria-label=&quot;create a client for mybff permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Create a Client for &lt;code class=&quot;language-text&quot;&gt;MyBFF&lt;/code&gt;&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;  &lt;span class=&quot;token comment&quot;&gt;# Client for MyBFF&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;MyBFFUserPoolClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; AWS&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;Cognito&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;UserPoolClient
    &lt;span class=&quot;token key atrule&quot;&gt;DependsOn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; MyServiceUserPoolResourceServer
    &lt;span class=&quot;token key atrule&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;ClientName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; MyBFF
      &lt;span class=&quot;token key atrule&quot;&gt;GenerateSecret&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;AccessTokenValidity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# Hours&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;RefreshTokenValidity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# Days&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;AllowedOAuthFlows&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; client_credentials
      &lt;span class=&quot;token key atrule&quot;&gt;AllowedOAuthFlowsUserPoolClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;AllowedOAuthScopes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; MyService/weather_read
      &lt;span class=&quot;token key atrule&quot;&gt;EnableTokenRevocation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;ExplicitAuthFlows&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; ALLOW_REFRESH_TOKEN_AUTH
      &lt;span class=&quot;token key atrule&quot;&gt;UserPoolId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;!Ref&lt;/span&gt; MyServicesUserPool&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Basically we are &lt;strong&gt;registering a client, with a secret&lt;/strong&gt;, which is only allowed
to trigger the &lt;code class=&quot;language-text&quot;&gt;client_credentials&lt;/code&gt; grant flow with the scopes
&lt;code class=&quot;language-text&quot;&gt;MyService/weather_read&lt;/code&gt;. In other words, we are allowing this client
&lt;code class=&quot;language-text&quot;&gt;MyBFF&lt;/code&gt; to talk to resource server &lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We can check the result in AWS console, in the &lt;strong&gt;App Integration&lt;/strong&gt; tab&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/62eee323255b828a6dcb2b737b41c543/e9d87/aws-cognito-client.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 31.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAyUlEQVQY003Q7Y6EMAgFUN//NcfV6lg+L1b0z6auM9kTAi0JTcOAiNc4vn7GSqRmrMLCxFyJiJ9DZWIR4o6ERcXczX2IfS/LMpcylzLN8/reWM3M1LwXczUXs0okqmJaid7vTVQdGFpr67pO07Qsa1nKVskciA6BniIAsIi7O5xFtm0TkYgY9tZEOwMc4cDx0e74ysw8zyPzyESEmvVv9wtQmRFxnY88T79d19O7/slMRwz7TdCwH9d39BYRlf42R+048n7xG4j4BUKWVebVaeZCAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/62eee323255b828a6dcb2b737b41c543/8ac56/aws-cognito-client.webp 240w,
/static/62eee323255b828a6dcb2b737b41c543/d3be9/aws-cognito-client.webp 480w,
/static/62eee323255b828a6dcb2b737b41c543/e46b2/aws-cognito-client.webp 960w,
/static/62eee323255b828a6dcb2b737b41c543/c9586/aws-cognito-client.webp 1176w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/62eee323255b828a6dcb2b737b41c543/8ff5a/aws-cognito-client.png 240w,
/static/62eee323255b828a6dcb2b737b41c543/e85cb/aws-cognito-client.png 480w,
/static/62eee323255b828a6dcb2b737b41c543/d9199/aws-cognito-client.png 960w,
/static/62eee323255b828a6dcb2b737b41c543/e9d87/aws-cognito-client.png 1176w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/62eee323255b828a6dcb2b737b41c543/d9199/aws-cognito-client.png&quot;
            alt=&quot;AWS Cognito Clients&quot;
            title=&quot;AWS Cognito Clients&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/33b08d76478101c57216fdbcf4541ccd/68638/aws-cognito-client-detail.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 47.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABIUlEQVQoz3WQh27DMAxE/f9fmeEhS9YgNa1BFbbTNEXRhwM4cAcCHJ4zu0/L7THex5krENpIpaRSaO1LiFcDiIfO3gAYgEFKua4rY0xrk9KeUorpIH4QrnIuwylEBIBhW55iGbVgEdXuITmTrAHJrRbWiAAqoSSifd9DCKWUWisR1VpTSoMWS9pzOeknrREAntbaiUpAIooxKq29D29bznnY2ITWhfizbdSscyHE1lrvvUR7nGot5+PGtXyFJZ+1Ns651hoR9d6JyDmXc75MJdp34JMj7EH13mst9O1o1K6nxhiJWon4b1hvjE13Pj/W6b6MN8Vnq4XeFi0WUNzq43PpD9575/xgnVs5l1JKpTjngOiD996HcBTnf/EerbXO+y8VHwYvCFi2ZwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/33b08d76478101c57216fdbcf4541ccd/8ac56/aws-cognito-client-detail.webp 240w,
/static/33b08d76478101c57216fdbcf4541ccd/d3be9/aws-cognito-client-detail.webp 480w,
/static/33b08d76478101c57216fdbcf4541ccd/e46b2/aws-cognito-client-detail.webp 960w,
/static/33b08d76478101c57216fdbcf4541ccd/f992d/aws-cognito-client-detail.webp 1440w,
/static/33b08d76478101c57216fdbcf4541ccd/aa814/aws-cognito-client-detail.webp 1510w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/33b08d76478101c57216fdbcf4541ccd/8ff5a/aws-cognito-client-detail.png 240w,
/static/33b08d76478101c57216fdbcf4541ccd/e85cb/aws-cognito-client-detail.png 480w,
/static/33b08d76478101c57216fdbcf4541ccd/d9199/aws-cognito-client-detail.png 960w,
/static/33b08d76478101c57216fdbcf4541ccd/07a9c/aws-cognito-client-detail.png 1440w,
/static/33b08d76478101c57216fdbcf4541ccd/68638/aws-cognito-client-detail.png 1510w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/33b08d76478101c57216fdbcf4541ccd/d9199/aws-cognito-client-detail.png&quot;
            alt=&quot;AWS Cognito Client Detail&quot;
            title=&quot;AWS Cognito Client Detail&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/d61a42be201d95e75bf04f1e8bf2f776/2f183/aws-cognito-client-detail-hosted-uipng.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 24.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAIAAADKYVtkAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAgElEQVQY022L2wrCMBBE8///6IuKlShp0mx2N3tpRUSpNId5GOYS0pwbItIYZibmfbJUqNAAsQKEnAv3rqp+QFU6k/1X+sbMDInCUhc320a0OcbLCdLNhY4tMQcRcffhmaCkOLWStnUdn9VMVH/i3r9eyvP+mM45XkVkv/moIb4A868kalxbarcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/d61a42be201d95e75bf04f1e8bf2f776/8ac56/aws-cognito-client-detail-hosted-uipng.webp 240w,
/static/d61a42be201d95e75bf04f1e8bf2f776/d3be9/aws-cognito-client-detail-hosted-uipng.webp 480w,
/static/d61a42be201d95e75bf04f1e8bf2f776/e46b2/aws-cognito-client-detail-hosted-uipng.webp 960w,
/static/d61a42be201d95e75bf04f1e8bf2f776/f992d/aws-cognito-client-detail-hosted-uipng.webp 1440w,
/static/d61a42be201d95e75bf04f1e8bf2f776/5b9d2/aws-cognito-client-detail-hosted-uipng.webp 1589w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/d61a42be201d95e75bf04f1e8bf2f776/8ff5a/aws-cognito-client-detail-hosted-uipng.png 240w,
/static/d61a42be201d95e75bf04f1e8bf2f776/e85cb/aws-cognito-client-detail-hosted-uipng.png 480w,
/static/d61a42be201d95e75bf04f1e8bf2f776/d9199/aws-cognito-client-detail-hosted-uipng.png 960w,
/static/d61a42be201d95e75bf04f1e8bf2f776/07a9c/aws-cognito-client-detail-hosted-uipng.png 1440w,
/static/d61a42be201d95e75bf04f1e8bf2f776/2f183/aws-cognito-client-detail-hosted-uipng.png 1589w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/d61a42be201d95e75bf04f1e8bf2f776/d9199/aws-cognito-client-detail-hosted-uipng.png&quot;
            alt=&quot;AWS Cognito Client Detail Hosted UI&quot;
            title=&quot;AWS Cognito Client Detail Hosted UI&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;cloudformation-template-for-client-credentials-grant-flow&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#cloudformation-template-for-client-credentials-grant-flow&quot; aria-label=&quot;cloudformation template for client credentials grant flow permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;CloudFormation Template for Client Credentials Grant flow&lt;/h3&gt;
&lt;p&gt;I’m not setting all the &lt;a href=&quot;https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pool-settings-advanced-security.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Advanced Security&lt;/strong&gt;
features&lt;/a&gt;
configuration available that we would use in a regular User Pool supporting
other flows that deal with real users (Authorization Code, Implicit, etc,). I’m
also not enabling &lt;a href=&quot;https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-waf.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;AWS Web Application Firewall
(WAF)&lt;/strong&gt;&lt;/a&gt;,
which is something that we would do in a real scenario.&lt;/p&gt;
&lt;p&gt;This is the template I am using for the example of this blog post.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;AWSTemplateFormatVersion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2010-09-09&quot;&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;Description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; AWS Cognito with OAuth Client Credentials Grant flow

&lt;span class=&quot;token key atrule&quot;&gt;Resources&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;# Create a user pool&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;MyServicesUserPool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; AWS&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;Cognito&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;UserPool
    &lt;span class=&quot;token key atrule&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;UserPoolName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;MyServicesUserPool&quot;&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;# Disable Self-Service Account Recovery&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;AccountRecoverySetting&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;RecoveryMechanisms&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; admin_only
            &lt;span class=&quot;token key atrule&quot;&gt;Priority&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;# Disable Self-Service Signup&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;AdminCreateUserConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;AllowAdminCreateUserOnly&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;# Just in case a user is created by admin, we require MFA&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;MfaConfiguration&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ON&quot;&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;EnabledMfas&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; SOFTWARE_TOKEN_MFA

  &lt;span class=&quot;token comment&quot;&gt;# Creates a domain with oauth endpoints&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;MyServicesUserPoolDomain&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; AWS&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;Cognito&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;UserPoolDomain
    &lt;span class=&quot;token key atrule&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;Domain&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &amp;lt;your&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;gognito&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;domain&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;UserPoolId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;!Ref&lt;/span&gt; MyServicesUserPool

  &lt;span class=&quot;token comment&quot;&gt;# Resource Server for MyService&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;MyServiceUserPoolResourceServer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; AWS&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;Cognito&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;UserPoolResourceServer
    &lt;span class=&quot;token key atrule&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;Identifier&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; MyService
      &lt;span class=&quot;token key atrule&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; MyService
      &lt;span class=&quot;token key atrule&quot;&gt;Scopes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;         &lt;span class=&quot;token comment&quot;&gt;# Organize scopes&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;ScopeName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; weather_read
          &lt;span class=&quot;token key atrule&quot;&gt;ScopeDescription&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Grantes the ability to read weather
      &lt;span class=&quot;token key atrule&quot;&gt;UserPoolId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;!Ref&lt;/span&gt; MyServicesUserPool

  &lt;span class=&quot;token comment&quot;&gt;# Client for MyBFF&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;MyBFFUserPoolClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; AWS&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;Cognito&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;UserPoolClient
    &lt;span class=&quot;token key atrule&quot;&gt;DependsOn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; MyServiceUserPoolResourceServer
    &lt;span class=&quot;token key atrule&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;AccessTokenValidity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;AllowedOAuthFlows&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; client_credentials
      &lt;span class=&quot;token key atrule&quot;&gt;AllowedOAuthFlowsUserPoolClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;AllowedOAuthScopes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; MyService/weather_read
      &lt;span class=&quot;token key atrule&quot;&gt;ClientName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; MyBFF
      &lt;span class=&quot;token key atrule&quot;&gt;EnableTokenRevocation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;ExplicitAuthFlows&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; ALLOW_REFRESH_TOKEN_AUTH
      &lt;span class=&quot;token key atrule&quot;&gt;GenerateSecret&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;RefreshTokenValidity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;UserPoolId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;!Ref&lt;/span&gt; MyServicesUserPool
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can submit this template as a CloudFormation stack in AWS console and wait for its deployment completion.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/e9cd6d37d591f20bbca01d1210e5501c/a80b8/aws-cloudformation-stack.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 49.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABRklEQVQoz12R247dMAhF8/+f2IfOQzvtuSYx2Ji728TnjNRuYSRLXrANC7ZWAN398lg/Pi+X+woIRL3VCgDMMk65u5rZO7PIXsrSuojFGLnv5Xa7ETXEyiLdwjzUTFXVtLaGtSJWADwesOxlX4h6RGZmKWXby1aQqDWix7qqyonKceTIdmpet21bmFnNPYJ6b9Rb50a9s9z3+qwCpF2dLVikNTocMYtIjgEASyNSs4i4Fvp+e377/P1rQxZ5ADyxdQvP9ExzF9U45RFjwgBARJl53/Yfl+vPy/W2br130T5GjrfMTOQ1vMx8weaeY0Qm1lpbOwaDyMwAWBup6gTC3dz/h5k5MyMTEPdSABEQe+/rttXzR3kaiAg9bc9OB4y4zDITLgAv+OwscrSdsLnbu9AMVV1eriImNoN6x1q/djPXY//qL/wHAO5FIUOPgPIAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/e9cd6d37d591f20bbca01d1210e5501c/8ac56/aws-cloudformation-stack.webp 240w,
/static/e9cd6d37d591f20bbca01d1210e5501c/d3be9/aws-cloudformation-stack.webp 480w,
/static/e9cd6d37d591f20bbca01d1210e5501c/e46b2/aws-cloudformation-stack.webp 960w,
/static/e9cd6d37d591f20bbca01d1210e5501c/f992d/aws-cloudformation-stack.webp 1440w,
/static/e9cd6d37d591f20bbca01d1210e5501c/0bf85/aws-cloudformation-stack.webp 1497w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/e9cd6d37d591f20bbca01d1210e5501c/8ff5a/aws-cloudformation-stack.png 240w,
/static/e9cd6d37d591f20bbca01d1210e5501c/e85cb/aws-cloudformation-stack.png 480w,
/static/e9cd6d37d591f20bbca01d1210e5501c/d9199/aws-cloudformation-stack.png 960w,
/static/e9cd6d37d591f20bbca01d1210e5501c/07a9c/aws-cloudformation-stack.png 1440w,
/static/e9cd6d37d591f20bbca01d1210e5501c/a80b8/aws-cloudformation-stack.png 1497w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/e9cd6d37d591f20bbca01d1210e5501c/d9199/aws-cloudformation-stack.png&quot;
            alt=&quot;AWS CloudFormation Stack&quot;
            title=&quot;AWS CloudFormation Stack&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;At this point we can test the &lt;a href=&quot;https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Token
endpoint&lt;/a&gt;
to get a new &lt;code class=&quot;language-text&quot;&gt;access_token&lt;/code&gt;
&lt;code class=&quot;language-text&quot;&gt;https://[replace-your-domain-here].auth.us-east-1.amazoncognito.com/oauth2/token&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--location&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://replace-your-domain-here.auth.us-east-1.amazoncognito.com/oauth2/token&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;token parameter variable&quot;&gt;--header&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Content-Type: application/x-www-form-urlencoded&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
--data-urlencode &lt;span class=&quot;token string&quot;&gt;&apos;grant_type=client_credentials&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
--data-urlencode &lt;span class=&quot;token string&quot;&gt;&apos;client_id=your_client_id&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
--data-urlencode &lt;span class=&quot;token string&quot;&gt;&apos;client_secret=your_cliend_secret&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here is the result in Postman&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/365d067cfe1facb75669728ff5377023/97bfd/aws-cognito-token-endpoint.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 78.75000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAB3UlEQVQoz6WSaZKbMBCFOYnR3lK3WitL7InHHt//UCnA40yWH6nKq6/EE6CHusWQyUwlFLaM5lzcx7k8Lu2t+cKusMvRMmoE8VcGbWzKpbbOqaRcUq6HKbWlXGvrPoRRSKn0nwzB+6l3D5BzXtd1nqd5nqZ50zLPyzIvy3K5XGqtIXjE8AUcvPdEhIgpJY4Uc+qtlMQxRmYmImYGAPmrxK7BGAMAAQMhBg+IuBsPAN77GGMIYRxHKaX6IudcCGGw1l6v7733V944ipdaa/M8E6LWehxH8ZlirQPwg3Pu8Xj01owxr3it9WFqreuu3jsSUiQAUEodX9q2XWvlGMGDttpYY60VQhxBWxVbQ5CIIsUY41E/7FUNzprv55UiheApInIkIgDvnNVancbxJ6fTabtuyVob6+wgpdy6TeQx+oABHHlg9AQOnfXWeLcRnPX7FHac0VKI4dknpaaSr71cS7x1/uh8q3zv6THlx5TvPd17uvX03vhjyveWbo3fShyOcxuFmMjfGp9LvFa+Vj5nWhjXhN8SLvwc5xiWtN1cE12OxVopC74t56W3KSM5S2DBaKPVb9inOR7pbfE2sVYaK5VW+y6eJ71VJLfxZcQnux++/nJyf0/t/IsG+R/6AcbslX6sZvp4AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/365d067cfe1facb75669728ff5377023/8ac56/aws-cognito-token-endpoint.webp 240w,
/static/365d067cfe1facb75669728ff5377023/d3be9/aws-cognito-token-endpoint.webp 480w,
/static/365d067cfe1facb75669728ff5377023/e46b2/aws-cognito-token-endpoint.webp 960w,
/static/365d067cfe1facb75669728ff5377023/cff29/aws-cognito-token-endpoint.webp 1078w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/365d067cfe1facb75669728ff5377023/8ff5a/aws-cognito-token-endpoint.png 240w,
/static/365d067cfe1facb75669728ff5377023/e85cb/aws-cognito-token-endpoint.png 480w,
/static/365d067cfe1facb75669728ff5377023/d9199/aws-cognito-token-endpoint.png 960w,
/static/365d067cfe1facb75669728ff5377023/97bfd/aws-cognito-token-endpoint.png 1078w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/365d067cfe1facb75669728ff5377023/d9199/aws-cognito-token-endpoint.png&quot;
            alt=&quot;AWS Cognito Token Endpoint&quot;
            title=&quot;AWS Cognito Token Endpoint&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;One thing that we can check is the content of the &lt;code class=&quot;language-text&quot;&gt;access_token&lt;/code&gt; in &lt;a href=&quot;https://jwt.io/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;jwt.io&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/ca41bba3d6e11c445fb8dc58d7b9cb78/636d3/awscognito-jwtio-token.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 42.083333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAA7DAAAOwwHHb6hkAAABRklEQVQY042P6UoDUQyFB/oAKi0KCj6BbyxVEYt2nYL6Li5o64iKXWa5N3PXLDKt+NvwcTgJHJIkh0cne53j/YN2q9VK/lftdmdnZ7dxt6P70dnd8Gw66KbDbjo43ep00p+m08nV5fl172LU7w37veHNL+PBdToZT9I0ERSpRLQIbEy+8UqaOXlBLyLCG/6KWdCJSOKqCG8R5hGyBj3btsEDmbowpXIrMQusv8iuKRhC4hhDXS5jjAkCu7n4Dwmf4rLG+HdxGbORELQvIazFLygUHBWTbw5gjB6KZrM3XH1KteQvRVlBb/lW0aFEB14DaglrZi8chX3zDjP+hnWkB41PgJmhl5pea3zQ+GEJRaIFW6xCaXwJdrHhG4Kqg62czpuwCvSs8LHCmaaZxjnQTNOrRogsTGW+ylffFipn1B8WlHcWiX4AxOyDidtjpQYAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/ca41bba3d6e11c445fb8dc58d7b9cb78/8ac56/awscognito-jwtio-token.webp 240w,
/static/ca41bba3d6e11c445fb8dc58d7b9cb78/d3be9/awscognito-jwtio-token.webp 480w,
/static/ca41bba3d6e11c445fb8dc58d7b9cb78/e46b2/awscognito-jwtio-token.webp 960w,
/static/ca41bba3d6e11c445fb8dc58d7b9cb78/41bb6/awscognito-jwtio-token.webp 1222w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/ca41bba3d6e11c445fb8dc58d7b9cb78/8ff5a/awscognito-jwtio-token.png 240w,
/static/ca41bba3d6e11c445fb8dc58d7b9cb78/e85cb/awscognito-jwtio-token.png 480w,
/static/ca41bba3d6e11c445fb8dc58d7b9cb78/d9199/awscognito-jwtio-token.png 960w,
/static/ca41bba3d6e11c445fb8dc58d7b9cb78/636d3/awscognito-jwtio-token.png 1222w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/ca41bba3d6e11c445fb8dc58d7b9cb78/d9199/awscognito-jwtio-token.png&quot;
            alt=&quot;AWS Cognito Access Token&quot;
            title=&quot;AWS Cognito Access Token&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Things to notice about the
&lt;a href=&quot;https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-the-access-token.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;access_token&lt;/a&gt;
issued by AWS Cognito in a Client Crdentials Grant flow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The subject claim &lt;code class=&quot;language-text&quot;&gt;sub&lt;/code&gt; (subject) is the &lt;code class=&quot;language-text&quot;&gt;client_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;There’s no audience &lt;code class=&quot;language-text&quot;&gt;aud&lt;/code&gt; claim&lt;/li&gt;
&lt;li&gt;There’s a claim &lt;code class=&quot;language-text&quot;&gt;token_use&lt;/code&gt; with value &lt;code class=&quot;language-text&quot;&gt;access&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The &lt;code class=&quot;language-text&quot;&gt;scope&lt;/code&gt; claim has the list of scopes, which in this
case includes the scope &lt;code class=&quot;language-text&quot;&gt;MyService/weather_read&lt;/code&gt;,&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;myservice-setup-resource-server&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#myservice-setup-resource-server&quot; aria-label=&quot;myservice setup resource server permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt; Setup (Resource Server)&lt;/h2&gt;
&lt;p&gt;Now it’s time to build the service &lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt; using ASP.NET Core. I will use Minimal APIs in ASP.NET Core 8.&lt;/p&gt;
&lt;p&gt;Let’s start by creating a &lt;code class=&quot;language-text&quot;&gt;webapi&lt;/code&gt; project for &lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;dotnet new webapi &lt;span class=&quot;token parameter variable&quot;&gt;-o&lt;/span&gt; MyService&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Navigate to folder &lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt;, and open the project with your preferred editor.
Let’s run it from the command line.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;dotnet run --launch-profile https
Building&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.
info: Microsoft.Hosting.Lifetime&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Now listening on: https://localhost:7062
info: Microsoft.Hosting.Lifetime&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Now listening on: http://localhost:5235
info: Microsoft.Hosting.Lifetime&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Content root path: C:&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;temp&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;MyService&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now let’s open the swagger ui in the browser, and execute the operation &lt;code class=&quot;language-text&quot;&gt;GET /weatherforecast&lt;/code&gt; to get weather forecast data as a response.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 872px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a49deda2eed566c89bde89e37236af17/65654/myservice.-swagger-ui.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 112.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAWCAIAAABPIytRAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACdUlEQVQ4y5WS/08SYRzH+SMaA1z/ghRf+qEBWllQrfqtrL/BarSZTouFpeIsRCW1ovVD/0K/6WpzbsyzMEHNdAd3MuTg7rjjOOCe5741NAk27rbee+3ZZ5/ttT3P8/kYzGaz0Wg0mUzGMyb7nbMXeqz2846uLovZYrZYLGbdGBAE2UA2EARB1pHNre9byc1UKpVIJOLxeHx9DdGNQT2OojTOdPpwe2cfw3MZ/CiTPTziEEWVVO0YwGkgADTDExRXoLh8kaXLdb7aaOrEAJsRxTrP8QzFVzhZlhRZlESoz18ZAKhIYgpnvyQKe1ixQHNFhqcrQokHOpzKEMoi3CuKX1ExSwt5unJE8zQPmZqsBVuXDS23FktcHc2SRbYGZVWQ1DqUdeCFNhkWymA3y+3lKhkSpEmQIUGGahTp46IVjAIE23JtSYQ5BsbWuMhKaXaFPmFmmY6tMrFVJrJMN5uRZXrxG4Xm+ZbfhrBcBWSJq9RAHUon1LSpAqlNZquQrSlAbmxGE0Wb5qiAqqo/dw6eBp4Njwf8I8NPRof8I0OPBwcHHvoHHnWmTU7+QkeCLyai06GFcGghPDYVej72cjQQ1KJN3j3AxydfvwlHI/NLs/OLM3OLr0LTwfHQ2MRUR/69WZKkHMn92EZT+4dojsIKbCbPYASDEawWbUtSYGoEK+AEm/yNo1kKI1hclxYZwmJZ4GX1w6fPLpf7+q0b1256e3sv6dA2KrIsVBU1El3y+bx379+7fNXlcNqt3d3nrNaOdJCjSzFPj8d32+fuczkcDrt2OshzC++9Xm//g363+6LNZvs/+e27j3a7zXXF5enzOJ1OHf0Pa0nVavJ53jMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/a49deda2eed566c89bde89e37236af17/8ac56/myservice.-swagger-ui.webp 240w,
/static/a49deda2eed566c89bde89e37236af17/d3be9/myservice.-swagger-ui.webp 480w,
/static/a49deda2eed566c89bde89e37236af17/a8a2c/myservice.-swagger-ui.webp 872w&quot;
              sizes=&quot;(max-width: 872px) 100vw, 872px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/a49deda2eed566c89bde89e37236af17/8ff5a/myservice.-swagger-ui.png 240w,
/static/a49deda2eed566c89bde89e37236af17/e85cb/myservice.-swagger-ui.png 480w,
/static/a49deda2eed566c89bde89e37236af17/65654/myservice.-swagger-ui.png 872w&quot;
            sizes=&quot;(max-width: 872px) 100vw, 872px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/a49deda2eed566c89bde89e37236af17/65654/myservice.-swagger-ui.png&quot;
            alt=&quot;MyService Swagger UI&quot;
            title=&quot;MyService Swagger UI&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We could do the same with &lt;code class=&quot;language-text&quot;&gt;curl&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GET&apos;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://localhost:7062/weatherforecast&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2024-02-10&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureC&quot;&lt;/span&gt;:50,&lt;span class=&quot;token string&quot;&gt;&quot;summary&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Balmy&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureF&quot;&lt;/span&gt;:121&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2024-02-11&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureC&quot;&lt;/span&gt;:48,&lt;span class=&quot;token string&quot;&gt;&quot;summary&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Chilly&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureF&quot;&lt;/span&gt;:118&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2024-02-12&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureC&quot;&lt;/span&gt;:23,&lt;span class=&quot;token string&quot;&gt;&quot;summary&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Mild&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureF&quot;&lt;/span&gt;:73&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2024-02-13&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureC&quot;&lt;/span&gt;:50,&lt;span class=&quot;token string&quot;&gt;&quot;summary&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Warm&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureF&quot;&lt;/span&gt;:121&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2024-02-14&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureC&quot;&lt;/span&gt;:-4,&lt;span class=&quot;token string&quot;&gt;&quot;summary&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Chilly&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureF&quot;&lt;/span&gt;:25&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now &lt;strong&gt;we want to protect &lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt; to only allow authorized clients&lt;/strong&gt; with access tokens issued by the AWS Cognito User pool we have created previously.&lt;/p&gt;
&lt;p&gt;Let’ check the initial &lt;code class=&quot;language-text&quot;&gt;Program.cs&lt;/code&gt; (just removing comments from the initial
template)&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;csharp&quot;&gt;&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; builder &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; WebApplication&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;CreateBuilder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Services&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;AddEndpointsApiExplorer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Services&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;AddSwaggerGen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Environment&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;IsDevelopment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;UseSwagger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;UseSwaggerUI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;UseHttpsRedirection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; summaries &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;Freezing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Bracing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Chilly&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Cool&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Mild&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Warm&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Balmy&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Hot&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Sweltering&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Scorching&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;MapGet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/weatherforecast&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; forecast &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;  Enumerable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Select&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;index &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;WeatherForecast&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            DateOnly&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;FromDateTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DateTime&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Now&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;AddDays&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Shared&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;55&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            summaries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Shared&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;summaries&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ToArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; forecast&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;WithName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;GetWeatherForecast&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;WithOpenApi&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WeatherForecast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;DateOnly&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;/span&gt; TemperatureC&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;?&lt;/span&gt;&lt;/span&gt; Summary&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;/span&gt; TemperatureF &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;TemperatureC &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5556&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And now let’s make the &lt;strong&gt;changes to protect the &lt;code class=&quot;language-text&quot;&gt;/weatherforecast&lt;/code&gt; endpoint&lt;/strong&gt;.
First, and since we want to support JWT tokens, we need to add the nuget package
&lt;a href=&quot;https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.JwtBearer&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Microsoft.AspNetCore.Authentication.JwtBearer&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;dotnet &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; package Microsoft.AspNetCore.Authentication.JwtBearer&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And now let’s check the differences in order to protect our endpoint.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;csharp&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber 0&quot; class=&quot;language-csharp line-numbers&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Security&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Claims&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;Microsoft&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;AspNetCore&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Authorization&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; builder &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; WebApplication&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;CreateBuilder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Register Authentication with JWT Bearer tokens&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Services&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;AddAuthentication&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;AddJwtBearer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Register Authorization Policy based on Scopes&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Services&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;AddAuthorization&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;options &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    options&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;AddPolicy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;WeatherReadPolicy&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; policyBuilder &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        policyBuilder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;RequireAuthenticatedUser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        policyBuilder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;RequireClaim&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;token_use&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;access&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        policyBuilder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;RequireAssertion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;            ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;FindFirstValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;scope&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Split&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token char&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Any&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Equals&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MyService/weather_read&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;/span&gt;builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Services&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;AddEndpointsApiExplorer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Services&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;AddSwaggerGen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Configure the HTTP request pipeline.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Environment&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;IsDevelopment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;UseSwagger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;UseSwaggerUI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;UseHttpsRedirection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; summaries &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;Freezing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Bracing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Chilly&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Cool&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Mild&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Warm&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Balmy&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Hot&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Sweltering&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Scorching&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;MapGet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/weatherforecast&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Authorize&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Policy &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;WeatherReadPolicy&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; forecast &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Enumerable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Select&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;index &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;WeatherForecast&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            DateOnly&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;FromDateTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DateTime&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Now&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;AddDays&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Shared&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;55&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            summaries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Shared&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;summaries&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ToArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; forecast&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;WithName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;GetWeatherForecast&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;WithOpenApi&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WeatherForecast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;DateOnly&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;/span&gt; TemperatureC&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;?&lt;/span&gt;&lt;/span&gt; Summary&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;/span&gt; TemperatureF &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;TemperatureC &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5556&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These are the changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lines 1-2: Just adding some usings&lt;/li&gt;
&lt;li&gt;Lines 6: &lt;strong&gt;Registering the Authentication middleware&lt;/strong&gt;. It requires registering
the &lt;code class=&quot;language-text&quot;&gt;.well-known&lt;/code&gt; url configuration for our user pool, which is in the &lt;code class=&quot;language-text&quot;&gt;appsettings.json&lt;/code&gt; file (see below)&lt;/li&gt;
&lt;li&gt;Lines 7-21: &lt;strong&gt;Registering the Authorization middleware&lt;/strong&gt;, with the policy
&lt;code class=&quot;language-text&quot;&gt;WeatherReadPolicy&lt;/code&gt; to check for the scope &lt;code class=&quot;language-text&quot;&gt;MyService/weather_read&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Lines 38: Applying the &lt;code class=&quot;language-text&quot;&gt;[Authorize]&lt;/code&gt; attribute with the policy
&lt;code class=&quot;language-text&quot;&gt;WeatherReadPolicy&lt;/code&gt; in order to protect the endpoint.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the &lt;code class=&quot;language-text&quot;&gt;appsettings.json&lt;/code&gt; we need to register the metadata address&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;json&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber 0&quot; class=&quot;language-json line-numbers&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;Logging&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;LogLevel&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;Default&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Information&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;Microsoft.AspNetCore&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Warning&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;AllowedHosts&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token property&quot;&gt;&quot;Authentication&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token property&quot;&gt;&quot;Schemes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token property&quot;&gt;&quot;Bearer&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token property&quot;&gt;&quot;MetadataAddress&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://cognito-idp.us-east-1.amazonaws.com/&amp;lt;your-cognito-user-pool-id&gt;/.well-known/openid-configuration&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s call again the endpoint without any authorization, and we should see an
error.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GET&apos;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://localhost:7062/weatherforecast&apos;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;HTTP/1.1 &lt;span class=&quot;token number&quot;&gt;401&lt;/span&gt; Unauthorized
Content-Length: &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
Date: Mon, &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt; Feb &lt;span class=&quot;token number&quot;&gt;2024&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;:21:58 GMT
Server: Kestrel
WWW-Authenticate: Bearer&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As expected, the service returns now a &lt;code class=&quot;language-text&quot;&gt;401 Unauthorized&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let’s call the endpoint with a valid bearer token returned from the Cognito token endpoint&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt; &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GET&apos;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://localhost:7062/weatherforecast&apos;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Authorization: Bearer &amp;lt;your-access-token&gt;&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;HTTP/1.1 &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt; OK
Content-Type: application/json&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;charset&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;utf-8
Date: Mon, &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt; Feb &lt;span class=&quot;token number&quot;&gt;2024&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;:24:16 GMT
Server: Kestrel
Transfer-Encoding: chunked

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2024-02-13&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureC&quot;&lt;/span&gt;:41,&lt;span class=&quot;token string&quot;&gt;&quot;summary&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Cool&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureF&quot;&lt;/span&gt;:105&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2024-02-14&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureC&quot;&lt;/span&gt;:4,&lt;span class=&quot;token string&quot;&gt;&quot;summary&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Freezing&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureF&quot;&lt;/span&gt;:39&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2024-02-15&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureC&quot;&lt;/span&gt;:50,&lt;span class=&quot;token string&quot;&gt;&quot;summary&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Cool&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureF&quot;&lt;/span&gt;:121&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2024-02-16&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureC&quot;&lt;/span&gt;:5,&lt;span class=&quot;token string&quot;&gt;&quot;summary&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Sweltering&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureF&quot;&lt;/span&gt;:40&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2024-02-17&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureC&quot;&lt;/span&gt;:8,&lt;span class=&quot;token string&quot;&gt;&quot;summary&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hot&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureF&quot;&lt;/span&gt;:46&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We got a &lt;code class=&quot;language-text&quot;&gt;200 OK&lt;/code&gt;. Now that we have &lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt;, the Resource Server, behaving as expected, let’s setup the client, i.e, &lt;code class=&quot;language-text&quot;&gt;MyBFF&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;mybff-setup-client&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#mybff-setup-client&quot; aria-label=&quot;mybff setup client permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;code class=&quot;language-text&quot;&gt;MyBFF&lt;/code&gt; Setup (Client)&lt;/h2&gt;
&lt;p&gt;Let’s repeat the ASP.NET Core setup for the Backend-for-frontend &lt;code class=&quot;language-text&quot;&gt;MyBFF&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;dotnet new webapi &lt;span class=&quot;token parameter variable&quot;&gt;-o&lt;/span&gt; MyBFF&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Go to folder &lt;code class=&quot;language-text&quot;&gt;MyBFF&lt;/code&gt;, and using your preferred editor, replace the endpoint
logic of &lt;code class=&quot;language-text&quot;&gt;/weatherforecast&lt;/code&gt; to make a REST API call to &lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt; in order to
get weather forecast data. I am using the &lt;a href=&quot;https://github.com/reactiveui/refit&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Refit
library&lt;/a&gt; to make the REST call, which means
that I need to add the nuget package
&lt;a href=&quot;https://www.nuget.org/packages/Refit.HttpClientFactory&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Refit.HttpClientFactory&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;dotnet &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; package Refit.HttpClientFactory&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And here is the code.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;csharp&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber 0&quot; class=&quot;language-csharp line-numbers&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;Microsoft&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;AspNetCore&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Mvc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;Refit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; builder &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; WebApplication&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;CreateBuilder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Services&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;AddEndpointsApiExplorer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Services&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;AddSwaggerGen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Services&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token generic-method&quot;&gt;&lt;span class=&quot;token function&quot;&gt;AddRefitClient&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;IMyServiceClient&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ConfigureHttpClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;client &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;BaseAddress &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;Uri&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://localhost:7062&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Configure the HTTP request pipeline.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Environment&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;IsDevelopment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;UseSwagger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;UseSwaggerUI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;UseHttpsRedirection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;MapGet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/weatherforecast&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;FromServices&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IMyServiceClient&lt;/span&gt; myServiceClient&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; myServiceClient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;GetWeatherForecast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;WithName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;GetWeatherForecast&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;WithOpenApi&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;record&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WeatherForecast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;DateOnly&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;/span&gt; TemperatureC&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;?&lt;/span&gt;&lt;/span&gt; Summary&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IMyServiceClient&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/weatherforecast&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token return-type class-name&quot;&gt;Task&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;WeatherForecast&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;GetWeatherForecast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s check the differences from the original template:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lines 1-2: Just adding some usings&lt;/li&gt;
&lt;li&gt;Lines 32-38: &lt;strong&gt;Take advantage of Refit library and define an interface to
represent MyService’s REST API client&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Lines 9-10: &lt;strong&gt;Registering the REST API client&lt;/strong&gt; for &lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Lines 23-26: &lt;strong&gt;Call &lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt;&lt;/strong&gt; to get weather forecast&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At this point, if we run &lt;code class=&quot;language-text&quot;&gt;MyBFF&lt;/code&gt; and call its endpoint &lt;code class=&quot;language-text&quot;&gt;/weatherforecast&lt;/code&gt; we
should see an error since we are doing an unauthorized call to &lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt;
because we don’t have any logic yet to pass a JWT bearer token when doing the
call.&lt;/p&gt;
&lt;p&gt;Assuming that &lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt; is running and listening at &lt;code class=&quot;language-text&quot;&gt;https://localhost:7062&lt;/code&gt;,
let’s also run &lt;code class=&quot;language-text&quot;&gt;MyBFF&lt;/code&gt;. In &lt;code class=&quot;language-text&quot;&gt;MyBFF&lt;/code&gt; folder&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;dotnet run --launch-profile https&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;Building&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.
info: Microsoft.Hosting.Lifetime&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Now listening on: https://localhost:7248
info: Microsoft.Hosting.Lifetime&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Now listening on: http://localhost:5006
info: Microsoft.Hosting.Lifetime&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Content root path: C:&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;temp&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;MyBFF&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And now &lt;strong&gt;let’s call &lt;code class=&quot;language-text&quot;&gt;MyBFF&lt;/code&gt; endpoint&lt;/strong&gt; &lt;code class=&quot;language-text&quot;&gt;https://localhost:7248/weatherforecast&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GET&apos;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://localhost:7248/weatherforecast&apos;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;HTTP/1.1 500 Internal Server Error
Content-Type: text/plain; charset=utf-8
Date: Mon, 12 Feb 2024 11:03:38 GMT
Server: Kestrel
Transfer-Encoding: chunked

Refit.ApiException: Response status code does not indicate success: 401 (Unauthorized).
   at Refit.RequestBuilderImplementation.&amp;lt;&gt;c__DisplayClass14_0`2.&amp;lt;&amp;lt;BuildCancellableTaskFuncForMethod&gt;b__0&gt;d.MoveNext() in /_/Refit/RequestBuilderImplementation.cs:line 288
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Http.RequestDelegateFactory.&amp;lt;ExecuteTaskOfTFast&gt;g__ExecuteAwaited|132_0[T](Task`1 task, HttpContext httpContext, JsonTypeInfo`1 jsonTypeInfo)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

HEADERS
=======
Accept: */*
Host: localhost:7248
User-Agent: curl/8.4.0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Note ⚠️&lt;/strong&gt;: detailed exception information is being returned because I’m running
in a Development environment. &lt;strong&gt;In Production we should not return any detailed
information about the exception&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Basically we are getting a &lt;code class=&quot;language-text&quot;&gt;500 Internal Server Error&lt;/code&gt; as a &lt;strong&gt;result of a failed call to MyService, which is returning a &lt;code class=&quot;language-text&quot;&gt;401 Unauthorized&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;MyBFF&lt;/code&gt;&lt;/strong&gt;. We can also check the logs of &lt;code class=&quot;language-text&quot;&gt;MyBFF&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber 0&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;info: Microsoft.Hosting.Lifetime&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Content root path: C:&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;temp&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;MyBFF
info: System.Net.Http.HttpClient.Refit.Implementation.Generated+IMyServiceClient, MyBFF, &lt;span class=&quot;token assign-left variable&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;.0.0, &lt;span class=&quot;token assign-left variable&quot;&gt;Culture&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;neutral, &lt;span class=&quot;token assign-left variable&quot;&gt;PublicKeyToken&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;null.LogicalHandler&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Start processing HTTP request GET https://localhost:7062/weatherforecast
info: System.Net.Http.HttpClient.Refit.Implementation.Generated+IMyServiceClient, MyBFF, &lt;span class=&quot;token assign-left variable&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;.0.0, &lt;span class=&quot;token assign-left variable&quot;&gt;Culture&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;neutral, &lt;span class=&quot;token assign-left variable&quot;&gt;PublicKeyToken&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;null.ClientHandler&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Sending HTTP request GET https://localhost:7062/weatherforecast
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;info: System.Net.Http.HttpClient.Refit.Implementation.Generated+IMyServiceClient, MyBFF, &lt;span class=&quot;token assign-left variable&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;.0.0, &lt;span class=&quot;token assign-left variable&quot;&gt;Culture&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;neutral, &lt;span class=&quot;token assign-left variable&quot;&gt;PublicKeyToken&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;null.ClientHandler&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;101&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      Received HTTP response headers after &lt;span class=&quot;token number&quot;&gt;73&lt;/span&gt;.9603ms - &lt;span class=&quot;token number&quot;&gt;401&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;info: System.Net.Http.HttpClient.Refit.Implementation.Generated+IMyServiceClient, MyBFF, &lt;span class=&quot;token assign-left variable&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;.0.0, &lt;span class=&quot;token assign-left variable&quot;&gt;Culture&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;neutral, &lt;span class=&quot;token assign-left variable&quot;&gt;PublicKeyToken&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;null.LogicalHandler&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;101&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      End processing HTTP request after &lt;span class=&quot;token number&quot;&gt;92&lt;/span&gt;.3572ms - &lt;span class=&quot;token number&quot;&gt;401&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;      An unhandled exception has occurred &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; executing the request.
      Refit.ApiException: Response status code does not indicate success: &lt;span class=&quot;token number&quot;&gt;401&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Unauthorized&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;.
         at Refit.RequestBuilderImplementation.&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&gt;&lt;/span&gt;c__DisplayClass14_0&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;.&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;BuildCancellableTaskFuncForMethod&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;b__&lt;span class=&quot;token operator&quot;&gt;&lt;span class=&quot;token file-descriptor important&quot;&gt;0&lt;/span&gt;&gt;&lt;/span&gt;d.MoveNext&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; /_/Refit/RequestBuilderImplementation.cs:line &lt;span class=&quot;token number&quot;&gt;288&lt;/span&gt;
      --- End of stack trace from previous location ---
         at Microsoft.AspNetCore.Http.RequestDelegateFactory.&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ExecuteTaskOfTFast&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;g__ExecuteAwaited&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;132_0&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;T&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Task&lt;span class=&quot;token variable&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; task, HttpContext httpContext, JsonTypeInfo`1 jsonTypeInfo&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
         at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;HttpContext httpContext&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
         at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;HttpContext httpContext, ISwaggerProvider swaggerProvider&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
         at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;HttpContext context&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To fix it, before calling &lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt;, we need to be sure that we have a valid
&lt;code class=&quot;language-text&quot;&gt;access_token&lt;/code&gt; to pass it as bearer token in the authorization header. Basically
we need the following logic in the REST client:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;check if we have a valid &lt;code class=&quot;language-text&quot;&gt;access_token&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;if no valid &lt;code class=&quot;language-text&quot;&gt;access_token&lt;/code&gt; exists, we need to &lt;strong&gt;call the Authorization
Server passing the &lt;code class=&quot;language-text&quot;&gt;client_id&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;client_secret&lt;/code&gt; to get a new
&lt;code class=&quot;language-text&quot;&gt;access_token&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pass the &lt;code class=&quot;language-text&quot;&gt;access_token&lt;/code&gt; as a bearer token in the &lt;code class=&quot;language-text&quot;&gt;Authorization&lt;/code&gt; header.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We can use the &lt;code class=&quot;language-text&quot;&gt;IdentityModel&lt;/code&gt; library to help us implementing this logic in
&lt;code class=&quot;language-text&quot;&gt;MyBFF&lt;/code&gt;, which means that we need to install the nuget package
&lt;a href=&quot;https://www.nuget.org/packages?q=IdentityModel.AspnetCore&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;IdentityModel.AspnetCore&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;dotnet &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; package IdentityModel.AspnetCore&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, we just need to &lt;strong&gt;register the Access Token Management Service&lt;/strong&gt; provided by the &lt;code class=&quot;language-text&quot;&gt;IdentityModel&lt;/code&gt; library and attach it to the &lt;code class=&quot;language-text&quot;&gt;Refit&lt;/code&gt; http Client.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;csharp&quot;&gt;&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Services&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;AddAccessTokenManagement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;options &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    options&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Clients&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MyBFF&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        RequestUri &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;Uri&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Configuration&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;AUTH_SERVER_TOKEN_ENDPOINT_URL&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        ClientId &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Configuration&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;AUTH_SERVER_MYBFF_CLIENT_ID&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        ClientSecret &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Configuration&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;AUTH_SERVER_MYBFF_CLIENT_SECRET&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Services&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token generic-method&quot;&gt;&lt;span class=&quot;token function&quot;&gt;AddRefitClient&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;IMyServiceClient&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ConfigureHttpClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;client &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;BaseAddress &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;Uri&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://localhost:7062&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;AddClientAccessTokenHandler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MyBFF&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Just be sure that you add the following configuration keys to the configuration source that you are using.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;AUTH_SERVER_TOKEN_ENDPOINT_URL&lt;/code&gt; - For a AWS Cognito domain it should be
&lt;code class=&quot;language-text&quot;&gt;https://[your-chosen-domain].auth.us-east-1.amazoncognito.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;AUTH_SERVER_MYBFF_CLIENT_ID&lt;/code&gt; - the client id&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;AUTH_SERVER_MYBFF_CLIENT_SECRET&lt;/code&gt; - the client secret&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Note ⚠️&lt;/strong&gt;: &lt;strong&gt;Do not store secrets in source control&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now let’s run again &lt;code class=&quot;language-text&quot;&gt;MyBFF&lt;/code&gt;, but this time &lt;strong&gt;increasing the log level to debug&lt;/strong&gt;
to see what’s happening inside the access token management service.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;dotnet run --launch-profile https --Logging:LogLevel:Default&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;Debug&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;Building&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.
dbug: Microsoft.Extensions.Hosting.Internal.Host&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Hosting starting
info: Microsoft.Hosting.Lifetime&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Now listening on: https://localhost:7248
info: Microsoft.Hosting.Lifetime&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Now listening on: http://localhost:5006
info: Microsoft.Hosting.Lifetime&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Content root path: C:&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;temp&lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;MyBFF
dbug: Microsoft.Extensions.Hosting.Internal.Host&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Hosting started&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now let’s call &lt;code class=&quot;language-text&quot;&gt;MyBFF&lt;/code&gt; &lt;code class=&quot;language-text&quot;&gt;/wetherforecast&lt;/code&gt; endpoint&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GET&apos;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://localhost:7248/weatherforecast&apos;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;HTTP/1.1 &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt; OK
Content-Type: application/json&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;charset&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;utf-8
Date: Mon, &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt; Feb &lt;span class=&quot;token number&quot;&gt;2024&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;11&lt;/span&gt;:59:31 GMT
Server: Kestrel
Transfer-Encoding: chunked

&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2024-02-13&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureC&quot;&lt;/span&gt;:13,&lt;span class=&quot;token string&quot;&gt;&quot;summary&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Cool&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2024-02-14&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureC&quot;&lt;/span&gt;:-16,&lt;span class=&quot;token string&quot;&gt;&quot;summary&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Cool&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2024-02-15&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureC&quot;&lt;/span&gt;:34,&lt;span class=&quot;token string&quot;&gt;&quot;summary&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hot&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2024-02-16&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureC&quot;&lt;/span&gt;:28,&lt;span class=&quot;token string&quot;&gt;&quot;summary&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Cool&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2024-02-17&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;temperatureC&quot;&lt;/span&gt;:14,&lt;span class=&quot;token string&quot;&gt;&quot;summary&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hot&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We got a &lt;code class=&quot;language-text&quot;&gt;200 OK&lt;/code&gt; and weather forecast data was returned, which means that the REST call to &lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt; has succeeded. Let’s check the logs&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber 0&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;dbug: Microsoft.Extensions.Hosting.Internal.Host&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Hosting started
info: System.Net.Http.HttpClient.Refit.Implementation.Generated+IMyServiceClient, MyBFF, &lt;span class=&quot;token assign-left variable&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;.0.0, &lt;span class=&quot;token assign-left variable&quot;&gt;Culture&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;neutral, &lt;span class=&quot;token assign-left variable&quot;&gt;PublicKeyToken&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;null.LogicalHandler&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Start processing HTTP request GET https://localhost:7062/weatherforecast
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;dbug: IdentityModel.AspNetCore.AccessTokenManagement.ClientAccessTokenCache&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      Cache miss &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; access token &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; client: MyBFF&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;dbug: IdentityModel.AspNetCore.AccessTokenManagement.TokenEndpointService&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      Requesting client access token &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; client: MyBFF&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;dbug: IdentityModel.AspNetCore.AccessTokenManagement.DefaultTokenClientConfigurationService&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      Returning token client configuration &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; client: MyBFF&lt;/span&gt;info: System.Net.Http.HttpClient.IdentityModel.AspNetCore.AccessTokenManagement.TokenEndpointService.LogicalHandler&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Start processing HTTP request POST https://your-cognito-domain.auth.us-east-1.amazoncognito.com/oauth2/token
info: System.Net.Http.HttpClient.IdentityModel.AspNetCore.AccessTokenManagement.TokenEndpointService.ClientHandler&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Sending HTTP request POST https://your-cognito-domain.auth.us-east-1.amazoncognito.com/oauth2/token
info: System.Net.Http.HttpClient.IdentityModel.AspNetCore.AccessTokenManagement.TokenEndpointService.ClientHandler&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;101&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Received HTTP response headers after &lt;span class=&quot;token number&quot;&gt;549&lt;/span&gt;.6799ms - &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;
info: System.Net.Http.HttpClient.IdentityModel.AspNetCore.AccessTokenManagement.TokenEndpointService.LogicalHandler&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;101&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      End processing HTTP request after &lt;span class=&quot;token number&quot;&gt;556&lt;/span&gt;.8406ms - &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;dbug: IdentityModel.AspNetCore.AccessTokenManagement.ClientAccessTokenCache&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      Caching access token &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; client: MyBFF. Expiration: 02/12/2024 &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;:08:31 +00:00&lt;/span&gt;info: System.Net.Http.HttpClient.Refit.Implementation.Generated+IMyServiceClient, MyBFF, &lt;span class=&quot;token assign-left variable&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;.0.0, &lt;span class=&quot;token assign-left variable&quot;&gt;Culture&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;neutral, &lt;span class=&quot;token assign-left variable&quot;&gt;PublicKeyToken&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;null.ClientHandler&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Sending HTTP request GET https://localhost:7062/weatherforecast
info: System.Net.Http.HttpClient.Refit.Implementation.Generated+IMyServiceClient, MyBFF, &lt;span class=&quot;token assign-left variable&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;.0.0, &lt;span class=&quot;token assign-left variable&quot;&gt;Culture&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;neutral, &lt;span class=&quot;token assign-left variable&quot;&gt;PublicKeyToken&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;null.ClientHandler&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;101&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Received HTTP response headers after &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;.9003ms - &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;
info: System.Net.Http.HttpClient.Refit.Implementation.Generated+IMyServiceClient, MyBFF, &lt;span class=&quot;token assign-left variable&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;.0.0, &lt;span class=&quot;token assign-left variable&quot;&gt;Culture&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;neutral, &lt;span class=&quot;token assign-left variable&quot;&gt;PublicKeyToken&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;null.LogicalHandler&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;101&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      End processing HTTP request after &lt;span class=&quot;token number&quot;&gt;601&lt;/span&gt;.1684ms - &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;From the logs we can see that:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;strong&gt;token management service got a cache miss&lt;/strong&gt; when checking for the
access token&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;token management service has requested a new token&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;The REST call to &lt;code class=&quot;language-text&quot;&gt;MyService&lt;/code&gt; has succeeded&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;token management service has cached the access token&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now let’s call it a 2nd time, hoping this time we get a cache hit and reuse the
access token. Here are the logs we got this time:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber 0&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;info: System.Net.Http.HttpClient.Refit.Implementation.Generated+IMyServiceClient, MyBFF, &lt;span class=&quot;token assign-left variable&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;.0.0, &lt;span class=&quot;token assign-left variable&quot;&gt;Culture&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;neutral, &lt;span class=&quot;token assign-left variable&quot;&gt;PublicKeyToken&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;null.LogicalHandler&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;101&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      End processing HTTP request after &lt;span class=&quot;token number&quot;&gt;658&lt;/span&gt;.9196ms - &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;
info: System.Net.Http.HttpClient.Refit.Implementation.Generated+IMyServiceClient, MyBFF, &lt;span class=&quot;token assign-left variable&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;.0.0, &lt;span class=&quot;token assign-left variable&quot;&gt;Culture&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;neutral, &lt;span class=&quot;token assign-left variable&quot;&gt;PublicKeyToken&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;null.LogicalHandler&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Start processing HTTP request GET https://localhost:7062/weatherforecast
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;dbug: IdentityModel.AspNetCore.AccessTokenManagement.ClientAccessTokenCache&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      Cache hit &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; access token &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; client: MyBFF&lt;/span&gt;info: System.Net.Http.HttpClient.Refit.Implementation.Generated+IMyServiceClient, MyBFF, &lt;span class=&quot;token assign-left variable&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;.0.0, &lt;span class=&quot;token assign-left variable&quot;&gt;Culture&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;neutral, &lt;span class=&quot;token assign-left variable&quot;&gt;PublicKeyToken&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;null.ClientHandler&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Sending HTTP request GET https://localhost:7062/weatherforecast
info: System.Net.Http.HttpClient.Refit.Implementation.Generated+IMyServiceClient, MyBFF, &lt;span class=&quot;token assign-left variable&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;.0.0, &lt;span class=&quot;token assign-left variable&quot;&gt;Culture&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;neutral, &lt;span class=&quot;token assign-left variable&quot;&gt;PublicKeyToken&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;null.ClientHandler&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;101&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      Received HTTP response headers after &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;.1808ms - &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;
info: System.Net.Http.HttpClient.Refit.Implementation.Generated+IMyServiceClient, MyBFF, &lt;span class=&quot;token assign-left variable&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;.0.0, &lt;span class=&quot;token assign-left variable&quot;&gt;Culture&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;neutral, &lt;span class=&quot;token assign-left variable&quot;&gt;PublicKeyToken&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;null.LogicalHandler&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;101&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      End processing HTTP request after &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;.8902ms - &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Confirmed! We got a cache hit, and the &lt;code class=&quot;language-text&quot;&gt;access_token&lt;/code&gt; is being reused&lt;/strong&gt;. When the token expires, we will get again a cache miss, and a new token will be requested.&lt;/p&gt;
&lt;p&gt;In this blog post I am using ASP.NET Core as an example, but the principles used here can be used whatever the programming language you are using. I am also not assuming anything about the host where the services are running - it can be On-Premise, in an EC2 instance, in a AWS Lambda + API Gateway, etc. - it works in whatever host.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this blog post I tried to &lt;strong&gt;show how simple and easy it is to authorize Service-to-Service calls by using OAuth2 with Client Credentials grant flow&lt;/strong&gt;,  using &lt;strong&gt;AWS Cognito&lt;/strong&gt; as the Authorization Server, and &lt;strong&gt;ASP.NET Core&lt;/strong&gt; APIs as both Resource Servers or Clients.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[AWS Lambda - HTTP APIs and Concurrent Requests]]></title><description><![CDATA[In this blog post I will discuss some considerations when hosting a HTTP API
in AWS Lambda.
]]></description><link>https://bfcamara.com/posts/aws-lambda-httpapi/</link><guid isPermaLink="false">https://bfcamara.com/posts/aws-lambda-httpapi/</guid><pubDate>Thu, 15 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 328px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/03a048afef54fc4f9b4e96a07de96660/d5c60/Amazon_Lambda-Http-Api.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 100%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACoUlEQVQ4y2O4kSZMNmLAEBK5kSGGQOkixGsWuZ7Mfy2B83oS7/UknmuJXNcTefDoR9KcLnI9iederfnbHZNerW14vbbh7fb+hz1+YP2iBDWLXotlfTI1+sXiohsZYreL1e6U6bzdNfVWtvSNVMEbacLXwQiv5ilRT2cmXY1guJ7CfzWK8ems5Kezkq/GslxPF7uZJnw7A7fm6wlc95sd3h+Y+273tCeTI67Gst3KlX27fcL1TMk76YJXUoQPRgvexBdgKQLXUwVvZIi/2zXlQYna1SiGp3PSX89JOhrKsjpY6EiM0M10fFElfCND7EGT7dPpsXtaog8GMTwoVjo2u3aJL9/5JCHczoZ4O4HrQaPtl5tHN2YYn5tbeSxNfq4Tw57WuCcTQ2/Es19HDXZ0zdeTeF+uaXjcF3B9ZvbR5pDL/XHHQ5kelGq83tp7I00UX1Rdjed80Gz/fmPTsSCG7S3xhyud32xovZsneyWK6fniwsf9wVejmUHJDqvmW4kcL9c3Hy6xXuPCcLcv5OWclMdTIp/MSLoSyXCnRPPtzsmghJTMB09zDIgkncR7Nl9nS0fGrhCu60m87zZ33C7Xv5kp8Xb7xJuZEtfi2Z9Mi/lwbMWjCSHXEjghaY4Bbu2NeLZzU7MvlJvfjGK43+zwck39tXjOq3Fsz+dnP54SdTWG+Wo004MO9+eLC6/FsUEczwBN1Yncd2vNPx+YfadA4Ua29JutvfcarK8nct9IFbydr/h219TbxRo3MyUeTwh9sbTkWiyKZtHridz3mx3e7Jz8cnXdm81dzxfkQP0Glno8MfTttgmvVtW+3THxUa//tQQuVGeDMiPftXhoZrwez4WW264n815PFQDL8oECCDNLIpUBqFEKdgIMieBNnkQXQwA1eTs2PX7KYAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/03a048afef54fc4f9b4e96a07de96660/8ac56/Amazon_Lambda-Http-Api.webp 240w,
/static/03a048afef54fc4f9b4e96a07de96660/1009d/Amazon_Lambda-Http-Api.webp 328w&quot;
              sizes=&quot;(max-width: 328px) 100vw, 328px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/03a048afef54fc4f9b4e96a07de96660/8ff5a/Amazon_Lambda-Http-Api.png 240w,
/static/03a048afef54fc4f9b4e96a07de96660/d5c60/Amazon_Lambda-Http-Api.png 328w&quot;
            sizes=&quot;(max-width: 328px) 100vw, 328px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/03a048afef54fc4f9b4e96a07de96660/d5c60/Amazon_Lambda-Http-Api.png&quot;
            alt=&quot;AWS Lambda - HTTP Concurrent Requests&quot;
            title=&quot;AWS Lambda - HTTP Concurrent Requests&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Are you &lt;strong&gt;hosting your HTTP API in a AWS Lambda?&lt;/strong&gt; Are you aware of AWS Lambda
concurrency model regarding HTTP concurrent requests? Let’s investigate.&lt;/p&gt;
&lt;h2 id=&quot;http-apis&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#http-apis&quot; aria-label=&quot;http apis permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;HTTP APIs&lt;/h2&gt;
&lt;p&gt;When you build a HTTP API using your preferred language and HTTP framework, you
&lt;strong&gt;expect that the HTTP framework will live in a process which will handle
multiple concurrent requests&lt;/strong&gt;, right?&lt;/p&gt;
&lt;p&gt;When it comes to AWS Lambda that doesn’t happen: &lt;strong&gt;one instance of a AWS Lambda
processes one HTTP request at a time&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;You are maybe asking now: &lt;strong&gt;what happens then if a second HTTP request comes in
while still processing the first request?&lt;/strong&gt; Well, the second request will be
handled by a different AWS Lambda instance. This 2nd AWS Lambda instance can be
a new one, if no instances are ready, or an existing one that is idle (not
processing requests) and ready to process the new request (because it has
handled a recent previous request). This is all done magically and under the
hood by the AWS Lambda service.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Is this really a problem?&lt;/strong&gt; I don’t think so. However, I think it is
counterintuitive at first because it’s not what we are used to when handling
HTTP requests. &lt;strong&gt;I think it’s a smart design indeed, because the computing becomes
more predictable since every instance only handles one request at a time&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;So, what are really the consequences of this design? &lt;strong&gt;Maybe we will have more
cold starts than we were expecting, particularly in cases where we have a burst
in concurrent requests&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;cold-starts&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#cold-starts&quot; aria-label=&quot;cold starts permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Cold Starts&lt;/h2&gt;
&lt;p&gt;A cold start happens when a new AWS Lambda instance is required to be created to
handle the request coming in, mostly because there are no AWS Lambda instances
ready available. When this happens, &lt;strong&gt;the AWS Lambda service needs to spin up a
new execution environment&lt;/strong&gt; with the memory, runtime, and configuration specified
in the function. Once finished, AWS Lambda runs any initialization code - in
HTTP APIs means running the bootstrap of the framework, typically registering
services in Dependency Injection (DI) containers, configuring HTTP midleware,
etc (the code in &lt;code class=&quot;language-text&quot;&gt;Execute initialization code&lt;/code&gt; below).&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 890px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/f6785576b40593fc95bb239a02ce51b7/4ef49/aws-lambda-new-execution-environment.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 22.083333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAA1ElEQVQI11WNTUvDQBRF8/93btSF4EqhDVQEQa24dKOLVqnVZkqiMSUdlDCTN006X+9K3AmHuzh3cRLYhlR18eFGKz1ed1elmwhKs/Ys61/K0uY3Sty14ravHrrinsR0t74mmW2238ZQAqeU2pwKfzj7OV7Qee5PFuroqT6Y02Oe+/exfE71a2qLKa0uv+aT/m3UyWWjjbX7BACYETzYI3oEO2z0YBdCcBH+jxCg9nFWq1o2n1VdbyUzJwADHBn/GQwzDw9HcBwafhd10ZLRuiUyAH4BO7DbecvegdUAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/f6785576b40593fc95bb239a02ce51b7/8ac56/aws-lambda-new-execution-environment.webp 240w,
/static/f6785576b40593fc95bb239a02ce51b7/d3be9/aws-lambda-new-execution-environment.webp 480w,
/static/f6785576b40593fc95bb239a02ce51b7/8d1ba/aws-lambda-new-execution-environment.webp 890w&quot;
              sizes=&quot;(max-width: 890px) 100vw, 890px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/f6785576b40593fc95bb239a02ce51b7/8ff5a/aws-lambda-new-execution-environment.png 240w,
/static/f6785576b40593fc95bb239a02ce51b7/e85cb/aws-lambda-new-execution-environment.png 480w,
/static/f6785576b40593fc95bb239a02ce51b7/4ef49/aws-lambda-new-execution-environment.png 890w&quot;
            sizes=&quot;(max-width: 890px) 100vw, 890px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/f6785576b40593fc95bb239a02ce51b7/4ef49/aws-lambda-new-execution-environment.png&quot;
            alt=&quot;AWS Lambda Execution Environment&quot;
            title=&quot;AWS Lambda Execution Environment&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;small&gt;&lt;em&gt;(Source: &lt;a href=&quot;https://docs.aws.amazon.com/lambda/latest/operatorguide/execution-environments.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;AWS&lt;/a&gt;)&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;When an instance finishes to handle a HTTP request, &lt;strong&gt;the instance is kept warm
and ready to handle another HTTP request&lt;/strong&gt;. In subsequent HTTP requests, if a warm
instance is available, only the &lt;code class=&quot;language-text&quot;&gt;Execute handler code&lt;/code&gt; is invoked.  If no HTTP
request comes in for a while, the AWS Lambda service will eventually destroy the instance
after a while of inactivity.&lt;/p&gt;
&lt;p&gt;We can build something really quick to show this behavior. I am going to
ilustrate the steps with a ASP.NET Core 6 Minimal API. You need to have
installed the &lt;a href=&quot;https://aws.amazon.com/visualstudio/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;AWS Toolkit for Visual Studio 2022&lt;/a&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a new &lt;strong&gt;AWS Serverless Application (.NET Core - C#)&lt;/strong&gt; in Visual Studio 2022&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 946px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/759856ae2e3c150ccddbf8dc48cfe871/36c33/vs-create-new-serverless-proj.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 73.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACyUlEQVQ4y3WTW2/bRhCF9T9SWFwuyeVlKZLiXZRs0ZJsy4jdWkkMNGiNIEAR9KVo3tKn/vQv2JUcBwHyMNjb7JkzZ2YmcaIJw5AoighURBAEdp/nBWmaMpvNSHSC1tqe4zgiDkN0qhmGgfl8TpIkZMYvSZhIP7CAWseo8AUwjmNrSZygQmV9gkDheRJPSvwgwPd9hBBIKe2bWSehUpRVxbBc0ncdq9WKxWJhHz3ftwyVUjiOY+8MiOu6J5AAz/OO+zDGDxQT42zoV3VNVVY0TU1eFGRCYII9MzEfzZpnuQUSrmsDGRPCxXUF0nWZmMdZoui6lrIsrU5ZMUcLwVYpmn5B13WURUYchbjSs+CBFMcgnkQFvg1iUzYRsmxGVVVWVOOUphpHSHY65OFuR/vhfxZP/3H36wOvb3Zc3+xZ7N8ybnastrd0q5FyXhwBjTazVNtqFUVhNTMVNTrFqeZ6O7J988T4+In7+3uu3v/N5duPLB8+crvfs95ccT5u6Nr2CDidOuRpRNs0FjDPc8tQuJI08tmse4rfv1C++4fV+QXD+ZpuWFEst5R1Q94M6HxOFJ6q7Eyn6DSlrmsLaNiZ1KXVSpLrkPrqQHX7nouLNc31O/LxnvDigXlRoHSO6ytbkG8MDUjf9zZdc2lTlh5RIFl0BfHhX/TdJ9q+p+6X1N2CrB9J0owwLfDCBE+6LxqmJ4YGyFTrmaGpYDGL6K4PNHdPjJeX9DdvqHcH9PbR/knyEk/FL4DT6dTqZhia1fRa+h3Dvi2IDp/Rr/+ibVvmw8i8WZDWA1Gi8ePZCdB7YRhFoWVlRs0AmtGz3e9Lyjym3PxGcfVIP6zom4pmfUO2/5OmbdFlh2ub+xWuFEyeZ/FHO46UZ6dAnP2COHuF40xxhMAU0pzNX+GcMYtH+vIPlF8cGZqe+5lJq413su+DHs/GJ/BSIlUj3YCvsRXNUuzNjTkAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/759856ae2e3c150ccddbf8dc48cfe871/8ac56/vs-create-new-serverless-proj.webp 240w,
/static/759856ae2e3c150ccddbf8dc48cfe871/d3be9/vs-create-new-serverless-proj.webp 480w,
/static/759856ae2e3c150ccddbf8dc48cfe871/30833/vs-create-new-serverless-proj.webp 946w&quot;
              sizes=&quot;(max-width: 946px) 100vw, 946px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/759856ae2e3c150ccddbf8dc48cfe871/8ff5a/vs-create-new-serverless-proj.png 240w,
/static/759856ae2e3c150ccddbf8dc48cfe871/e85cb/vs-create-new-serverless-proj.png 480w,
/static/759856ae2e3c150ccddbf8dc48cfe871/36c33/vs-create-new-serverless-proj.png 946w&quot;
            sizes=&quot;(max-width: 946px) 100vw, 946px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/759856ae2e3c150ccddbf8dc48cfe871/36c33/vs-create-new-serverless-proj.png&quot;
            alt=&quot;VS 2022 New Serverlesss Project&quot;
            title=&quot;VS 2022 New Serverlesss Project&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Select the &lt;strong&gt;Blueprint ASP.NET Core Minimal API&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 934px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/e42f4d0575473cfd894432a10f18b78b/078fe/vs-create-serverless-select-blueprint.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 73.33333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAA7DAAAOwwHHb6hkAAADHElEQVQ4y22TXW/cRBiF9542VaSipFl7x/b4a/xtb5x1dkl2k/VmU7aVyALJQosS2gKCK4T4G6hJqv7eB3koHwIujkaeOT7z6n3e6cVZQRglxGmGH+f4YUSaFdQHDWW1T7Vfk5YFWVmSlxVJmhJ3/ixn8skR1bAmSjKSLCfNMnpeXmPd/Eb/+j27L9/x5MUtW5dveXB5x9bmHVubex5e3X3QPVudLu94uLnnweUtH33xlkdXtzz6+j0ibeiFSiFUhQhy6skxh7MFo9kZRXOMFWZadpjjqBzhJ+xKxZ5U9D/IcCNMV2H6KY4X0PODkHEuOCn7FGlImiQUWUqWxMQq1GsWR+RZgue7VJYgdWxsW+DaFtIWSEtgCYGULj0vCKnrmlE9pKwqqqqiLEuKoiDPc6SUSNdDeR5Hvs8kVARBQBCGRFGkFUcRtnRxdKAfaAhxHGulaaoPj+cLnl+sCaKEMC8ZB4qxinBViFJdqI9lWZimiWkYCNvB9Xx65kDQjCc8W61oFwuenp+TDWvKswum65ccXbxgfnWDmq2Iiopx09A0DQcHB/i+z2Aw0KF+qAhVRG9g2ag4Ic8ypCtxpYOQHv70GcH8M7zZc1S7xhov8UJFpBSO4+C6HrZt/0+gsBg1Y9p2zsnJCbPpFM/zGY4OaZdPtY5PW2Sg2N+vOT09ZTqdMhwO8Tzvv4GmsPTwLhYtk/GEqqy0qWv0qK4pi5wizzD6exrAaHRAFEc4tq2DhBCYpvF3oLBsDaXryWg0ojk81BQ7OF1FHaiOqOu65EXnqynLSvu7sw6MZQk8P6Qbwb+gnC+XzKYz5vO5NhZlybxtmUwmlFWpK+kqXK1WnC0WtPM5rpRsb2/z8ePH9I0B3Qj2OtyO6+sf9vp9+oaBYZg4jtSVdf3s9pWKuL6+0Rcsl0tevX7DZvMVV5sN6/XntMtzLFvSsx2J7frY0tPBf6r7thxXr8KR5OWQb66/5aAZs/x0xevvfuD7H3/i519+5ebVG9Zfbuhmuteh169BOv+S/Me+1L16srv7BwTDYGdnB8MwsG2LgWliW5am/juR49QrJK/h3QAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/e42f4d0575473cfd894432a10f18b78b/8ac56/vs-create-serverless-select-blueprint.webp 240w,
/static/e42f4d0575473cfd894432a10f18b78b/d3be9/vs-create-serverless-select-blueprint.webp 480w,
/static/e42f4d0575473cfd894432a10f18b78b/7d4d8/vs-create-serverless-select-blueprint.webp 934w&quot;
              sizes=&quot;(max-width: 934px) 100vw, 934px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/e42f4d0575473cfd894432a10f18b78b/8ff5a/vs-create-serverless-select-blueprint.png 240w,
/static/e42f4d0575473cfd894432a10f18b78b/e85cb/vs-create-serverless-select-blueprint.png 480w,
/static/e42f4d0575473cfd894432a10f18b78b/078fe/vs-create-serverless-select-blueprint.png 934w&quot;
            sizes=&quot;(max-width: 934px) 100vw, 934px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/e42f4d0575473cfd894432a10f18b78b/078fe/vs-create-serverless-select-blueprint.png&quot;
            alt=&quot;VS 2022 AWS Blueprint ASP.NET Core Minimal API&quot;
            title=&quot;VS 2022 AWS Blueprint ASP.NET Core Minimal API&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Change the code to &lt;strong&gt;add some delay while serving a HTTP request&lt;/strong&gt; to give us
time to launch new requests.&lt;/p&gt;
&lt;p&gt;On file &lt;code class=&quot;language-text&quot;&gt;Program.cs&lt;/code&gt; replace the line&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;csharp&quot;&gt;&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;MapGet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Welcome to running ASP.NET Core Minimal API on AWS Lambda&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;by the following code&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;csharp&quot;&gt;&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;MapGet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Wait 5 seconds&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; Task&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Delay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Welcome to running ASP.NET Core Minimal API on AWS Lambda\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Publish to AWS Lambda&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 842px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/993182e2cd05bc64515cd16992e2fbc5/99072/vs2022-publish-to-aws-lambda.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 45.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABgklEQVQoz1WS23LaMBCG/R4YfD5LNmDLR8JMmLotpIT0su//IF9HSiDm4puVdnb+/bUrK0kSlqRp+oTO5XlOVe3ZVi1VqUhiSZaW5OmeKBQEfkrgZwRBhhXHMUvCMCSKogf6rgWbpmEYBqZxYppGuq5FNS1CSIoiR4iCPM+w7JWNZrVasV5viKIY3/fxfP8zep5x2fcD84/fXC4XbrcbHx9/OZ/PzPPMMIymUV3XWG7g4IYuju8QJAGHw8E4kVJQliWyrEzUCCmN8PHlSJZlpqHGcRyD67pYQe7hazKPsAhQqqHve6qqYrfb0Uv5LSjEl5vx4X6z2TxhrddrPrFxHJdGdYzDwHa/57WuOQlBWhRIIYygUoq2bSmKwnAXvbu0dEKj7eqlzD9nTqcT4+HAP6V4HUeGaTJL0Y61YFM3ZmG2bT/E7vFJMIlj3n7N/Lleeb++83a+cDwezQimaaLrOqSUpnY5uyeH9yfrbrpwu9vTte3XQr5np9Fn/Td1/dLZUvA/0OEOu2RvQOAAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/993182e2cd05bc64515cd16992e2fbc5/8ac56/vs2022-publish-to-aws-lambda.webp 240w,
/static/993182e2cd05bc64515cd16992e2fbc5/d3be9/vs2022-publish-to-aws-lambda.webp 480w,
/static/993182e2cd05bc64515cd16992e2fbc5/6366e/vs2022-publish-to-aws-lambda.webp 842w&quot;
              sizes=&quot;(max-width: 842px) 100vw, 842px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/993182e2cd05bc64515cd16992e2fbc5/8ff5a/vs2022-publish-to-aws-lambda.png 240w,
/static/993182e2cd05bc64515cd16992e2fbc5/e85cb/vs2022-publish-to-aws-lambda.png 480w,
/static/993182e2cd05bc64515cd16992e2fbc5/99072/vs2022-publish-to-aws-lambda.png 842w&quot;
            sizes=&quot;(max-width: 842px) 100vw, 842px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/993182e2cd05bc64515cd16992e2fbc5/99072/vs2022-publish-to-aws-lambda.png&quot;
            alt=&quot;Publish to AWS Lambda&quot;
            title=&quot;Publish to AWS Lambda&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Give a name to your stack (a stack is a group of resources representing a
serverless app).&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 897px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/dba620611dbb4c25354d9eed9524888f/3a737/vs2022-publish-to-aws-lambda-stack-name.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 65.41666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACG0lEQVQ4y6WS208TQRyF+0xCnwDZ6+x9u91CL7vdpYRyESzgBcuDSJXwFxjji1FjvBXaRBP/5s/srIgQ6osPX05mJnPmd3Km4vYfY539QHs+RXk2QTuZUh1eMnd0Iak+HVM9GjN3dMn8cML8cHrN8ZTq8YSFk+8oo5+k2/tUnKzPcneInj2heXBG6/CM9sNz4r1TmofnNAcjkkfn1PdGqMkBy+0By52bKJ0BC6u7dNdyKnHN5v7qIv3GPZqRTysOaNUDqe04pBWHJM2Y1ZqHpS7djbaEqSzSTlMqQS0mimoYho6wLGzHxXYcTGFhCoHze23ZtjwvKM+uEcLCMAVh3KDihxHdLCdNUvIsp9vtUqvVCMOQehTRSTpkWUa9XkdRFHRdRwiBaZqlCoEwzVJtl4obhPTW14miiF6vx+bmJhv9Dfr9PmtrOSsrK39I0oRGo4FhGNLstqFpO1Rsx6Pd6RAEPkmSsLu7y87ODlvbW3LaPC+nLgxHL08ZDAaoqjrb0PN8PD+QMX3fv4HneYRBKLWYqjDSNG1mZGloWg6GaWLourw0i6uJ/jabaShkU+I/sUpDw7LLxdUrd1BcuIpcpFE1TTauqKrcK9B1o2zZdv0ywj8ozMIgIE0TXNel1WrJorppKovstNvyWxnCpuL4ITK25Ui9TfGqohnsPdjn85dvpFnOq9dvGF9O+Dq+4MPHT7x9956T0xcoms4vv/2GatJKq1gAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/dba620611dbb4c25354d9eed9524888f/8ac56/vs2022-publish-to-aws-lambda-stack-name.webp 240w,
/static/dba620611dbb4c25354d9eed9524888f/d3be9/vs2022-publish-to-aws-lambda-stack-name.webp 480w,
/static/dba620611dbb4c25354d9eed9524888f/10735/vs2022-publish-to-aws-lambda-stack-name.webp 897w&quot;
              sizes=&quot;(max-width: 897px) 100vw, 897px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/dba620611dbb4c25354d9eed9524888f/8ff5a/vs2022-publish-to-aws-lambda-stack-name.png 240w,
/static/dba620611dbb4c25354d9eed9524888f/e85cb/vs2022-publish-to-aws-lambda-stack-name.png 480w,
/static/dba620611dbb4c25354d9eed9524888f/3a737/vs2022-publish-to-aws-lambda-stack-name.png 897w&quot;
            sizes=&quot;(max-width: 897px) 100vw, 897px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/dba620611dbb4c25354d9eed9524888f/3a737/vs2022-publish-to-aws-lambda-stack-name.png&quot;
            alt=&quot;AWS Stack name&quot;
            title=&quot;AWS Stack name&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You can follow the deployment progress and once finished you should see the
Stack view tab&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/d292d324711a30479197e8b721e03f12/1628f/vs2022-publish-to-aws-lambda-report.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 56.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABvElEQVQoz2VSWXajMBDkHIMNBoSFsQAJs0gsTmbuf6eaV42T57x8NEKt7qrqJQrhE0v4hJ93TGOAbR20vkOpCtlFIU1zXNJCzixTyPMSqtC4lje5Xy6FxH1ZZG2HQuUobhl0c0WlNcqSifnLMmQZ7QKtNZxzuN9JSJIESXJGkiTfFjFAKSXBt9sNVVWhrmtJej/5plQpcSQ6n89I0/SXRfe7kQTbP+AeA9rOwbQWnetRmw5ZXqAoClF5Op3ECPau6gdg0zSigkYVtOv1CmOM+LS0oJQquq4TclZhGiNv/Gc8SWkREwm6rCuWZcG2bRiGAc467PuOJSzonZPezfOMefZwvcX6b8S27kL2rjgiOlmmacY0TZLUdS3YChIQjIHHYDLEcYzTKcayWgQfYGRAStQROOKHLCEE+NnLOY0j+v4hgPR1bSsxLJeDUUWOj+eAddmEkFXyTQDJzmDvgyj03sNaK20I3sudJOMwSn/pr+sKf/cBwR8VfG3HD4XszTQegOwhQamubdrX3h1lseQ4/oPn84F92wWMPuIIIHeKgWQ2phH5x6T1q4xjVdg/Ah/rkaBpKrlTWaWPSdP/H9I2RkRB5L3IAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/d292d324711a30479197e8b721e03f12/8ac56/vs2022-publish-to-aws-lambda-report.webp 240w,
/static/d292d324711a30479197e8b721e03f12/d3be9/vs2022-publish-to-aws-lambda-report.webp 480w,
/static/d292d324711a30479197e8b721e03f12/e46b2/vs2022-publish-to-aws-lambda-report.webp 960w,
/static/d292d324711a30479197e8b721e03f12/46ece/vs2022-publish-to-aws-lambda-report.webp 1232w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/d292d324711a30479197e8b721e03f12/8ff5a/vs2022-publish-to-aws-lambda-report.png 240w,
/static/d292d324711a30479197e8b721e03f12/e85cb/vs2022-publish-to-aws-lambda-report.png 480w,
/static/d292d324711a30479197e8b721e03f12/d9199/vs2022-publish-to-aws-lambda-report.png 960w,
/static/d292d324711a30479197e8b721e03f12/1628f/vs2022-publish-to-aws-lambda-report.png 1232w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/d292d324711a30479197e8b721e03f12/d9199/vs2022-publish-to-aws-lambda-report.png&quot;
            alt=&quot;AWS Stack view&quot;
            title=&quot;AWS Stack view&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Test your endpoint in the browser&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The stack that was created includes an API in AWS API Gateway. You can check
the URL in the Lambda page that will trigger the function.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 833px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/e5172620741b108e58e8238e69527941/5205c/aws-Lambda-trigger-api-gateway-url.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 91.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACSUlEQVQ4y5WT3W7cIBCFef8n6m3velWpVVqpkVJpG+/axgZsAwMYvKcC7GTzo6i19GkwjIeZOWM2SoXT4wXNpUNz6SEXgiFXsQRNDtq6anfMBzDvPcIN67o+EdMVKSVsKSGlWNYpxhc+rykBbzdCCAjZOoL58QndpcH53KJtWzTnM4ZxfPZ7B+aD3x3eOrmJl0CcD3DOgZzDkUA+fzdDolzqirA+O8RYrVpM6eO2bU/EGEvww9f7AGsJRFQuZA93E37/lFCzKAe5TzETU/k4Z2SJij04KsgBnfMQQoJzDjVNYNO8oOccoxAvnG95Xdbrs3xx3MVieTO+US7urP8NM9aWUnNZeZ174awt5D1bzuuadmE+guVSByEgpETHeRmL8XyC6BrwcQQfMkPxmZcF0zx/CJvnGVKpQr4hZymkQtdzaGPqzVRVtP8AG9sGzof6R2wb1hjLTW3XY150FeEdXoh020MhRAlwqEallwQfCNbpJ3Fu5/RQ+naUjglhOVjuzeGUBQIiHr5rfP3cQageHZcYZguuNDq5gCuDxXpcbwb+ChTLpnmCmhS00fA5IBFiWuHMBtFbDOMAMRv0yqKVGsNkSvCZApQJmChCugSjcyLXmqGlOhphD5i2iEUk9I8GahKw5OHXBJcJ1eb38qQI/fsBy+lUsmRZydKPnVpyQnPvcPdlABcdmk6gGRaceoU/vUIzzFDaw12B7tsdxK97HA+TUkLIKkweoTLczueOIG4B4yhAPsC4Cvm1vFsfoMlD+xV+u9a/LUb8BXZccPZFz+tTAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/e5172620741b108e58e8238e69527941/8ac56/aws-Lambda-trigger-api-gateway-url.webp 240w,
/static/e5172620741b108e58e8238e69527941/d3be9/aws-Lambda-trigger-api-gateway-url.webp 480w,
/static/e5172620741b108e58e8238e69527941/184c4/aws-Lambda-trigger-api-gateway-url.webp 833w&quot;
              sizes=&quot;(max-width: 833px) 100vw, 833px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/e5172620741b108e58e8238e69527941/8ff5a/aws-Lambda-trigger-api-gateway-url.png 240w,
/static/e5172620741b108e58e8238e69527941/e85cb/aws-Lambda-trigger-api-gateway-url.png 480w,
/static/e5172620741b108e58e8238e69527941/5205c/aws-Lambda-trigger-api-gateway-url.png 833w&quot;
            sizes=&quot;(max-width: 833px) 100vw, 833px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/e5172620741b108e58e8238e69527941/5205c/aws-Lambda-trigger-api-gateway-url.png&quot;
            alt=&quot;API Gateway URL Trigger&quot;
            title=&quot;API Gateway URL Trigger&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Click on the link and you should wait aprox. 5 seconds until you have the
answer in your browser.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 512px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/9d6506b398a409b6dfd26a478a2797a0/01e7c/aws-lambda-call-url-browser-result.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 28.333333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA30lEQVQY052M3U6DQBBGeQJYuLe7/G53F7ZYQ1KgpSat0RgT3/9pjgGNKXqlFyffzMk3E/TDxHS+8Pr2jt890O47Ltdnrk8vnKZHhnHi0B859OOSXdczjGfG48R8O+f9vsM1LXmhCeraY2yNdQ3GOCpt8L5l9tY6nKupG49zzYIxFld7vN8tvUpvSbMcpTLuNpLAWoOUErmRWGMpywKtNWVeLD5LFdbOviLLUpRSpHnGttJYY4iiiDAMlxQiIpgXIcRCGIXf+VkQq4OV+/JJkqwIfor/EMfx74e38nb+Kx+H+KJxpSH/ZAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/9d6506b398a409b6dfd26a478a2797a0/8ac56/aws-lambda-call-url-browser-result.webp 240w,
/static/9d6506b398a409b6dfd26a478a2797a0/d3be9/aws-lambda-call-url-browser-result.webp 480w,
/static/9d6506b398a409b6dfd26a478a2797a0/bd5dd/aws-lambda-call-url-browser-result.webp 512w&quot;
              sizes=&quot;(max-width: 512px) 100vw, 512px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/9d6506b398a409b6dfd26a478a2797a0/8ff5a/aws-lambda-call-url-browser-result.png 240w,
/static/9d6506b398a409b6dfd26a478a2797a0/e85cb/aws-lambda-call-url-browser-result.png 480w,
/static/9d6506b398a409b6dfd26a478a2797a0/01e7c/aws-lambda-call-url-browser-result.png 512w&quot;
            sizes=&quot;(max-width: 512px) 100vw, 512px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/9d6506b398a409b6dfd26a478a2797a0/01e7c/aws-lambda-call-url-browser-result.png&quot;
            alt=&quot;AWS Lambda HTTP result&quot;
            title=&quot;AWS Lambda HTTP result&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Launch 10 concurrent requests&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;At this point we should have a AWS Lambda instance ready to handle more
requests. So let’s launch 10 simultaneous requests to see what happens. Open
a bash or a windows subsystem for linux (wsl) and run the following command&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;seq&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;xargs&lt;/span&gt; -I&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-P&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;url_api_gateway&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The requests are launched concurrently, wait aprox. 5 seconds, and you will
see something like this.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b9d45f6e22f9c8c41b7cbe625ef0d1d9/3fca6/aws-lambda-launch-10-requests.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 31.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAA7CAAAOwgEVKEqAAAABHklEQVQY042PW0sCURSFj6WRkUaheZlxvMyYTg9ieRmvzUmQ3k0TSg1FHB3t/z9+oYJB0OXhY2/W3izWEtGiJFXvEit1iBaeCKYlvpjFabzCmVLCr5TxKyXOE5UDFymLoFYl8E0LaFWEKh2i7Tmh2oxwbUHYconU18SbLtfWgqS9IViccZR7w2uO8OZHnNyO8Zlf7DRzzHF+hDCki9ZccNNZo8sVhlxiPK7Q7SVKfY7Z3XB5N0GknhF6H5H5he3dkGu0hoNhr9HtFRl7uTPL2CvUxgKz+8HV/Tsi3cdjvPyJUOWMyMMEVU5R2g7xhova2pBoLQmVpyTbDoHCeJfgX4Yi10Pke+xmdogwXvFktwz3NdLbKoP9sz447D8ZfgKOaLqm/D88MQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/b9d45f6e22f9c8c41b7cbe625ef0d1d9/8ac56/aws-lambda-launch-10-requests.webp 240w,
/static/b9d45f6e22f9c8c41b7cbe625ef0d1d9/d3be9/aws-lambda-launch-10-requests.webp 480w,
/static/b9d45f6e22f9c8c41b7cbe625ef0d1d9/e46b2/aws-lambda-launch-10-requests.webp 960w,
/static/b9d45f6e22f9c8c41b7cbe625ef0d1d9/01adf/aws-lambda-launch-10-requests.webp 1112w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/b9d45f6e22f9c8c41b7cbe625ef0d1d9/8ff5a/aws-lambda-launch-10-requests.png 240w,
/static/b9d45f6e22f9c8c41b7cbe625ef0d1d9/e85cb/aws-lambda-launch-10-requests.png 480w,
/static/b9d45f6e22f9c8c41b7cbe625ef0d1d9/d9199/aws-lambda-launch-10-requests.png 960w,
/static/b9d45f6e22f9c8c41b7cbe625ef0d1d9/3fca6/aws-lambda-launch-10-requests.png 1112w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/b9d45f6e22f9c8c41b7cbe625ef0d1d9/d9199/aws-lambda-launch-10-requests.png&quot;
            alt=&quot;AWS Lambda - Launch concurrent requests&quot;
            title=&quot;AWS Lambda - Launch concurrent requests&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Monitoring concurrent executions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now it’s time to check what happened in terms of number of instances.
Probably you were expecting that the instance that served our first request
in browser would be used to serve all the concurrent requests. But as I’ve
mentioned before, it’s not what happened. We can check the Monitor -&gt;
Metrics tab in the function page.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 528px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b589600f77889644f835b6546ed8f19d/4af8e/aws-monitor-lambda-concurrent-executions.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 177.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAkCAYAAACJ8xqgAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAEQ0lEQVRIx61Wa08bRxT1b2krpUpTEKqANoIgRYqqfqn6qX8yPyFKSihxABtDEwLB7/XaJvZ6n7Pvnd1T3etd26SmMVVHurrjmb1nzsw9c8elvWe/Yv3xz3jyy+/Yfvob1rafYn1rB482d/Dd5i6+39zB2tYu1refYOOnPTz64THWt3bxcONHfPVgDd883MDX367jwdomtvaeoXRSOUX17C8cHlXw5vgU5aMKDspHqJ6coPL6JaqnNfz59hgv/tjHq4NDHFVreH1Yxv5hGeXjCl682sfBm7eo1M5RrZ2jBABhGEDYBoStw3UFhOfBtgyYoyEsy4QjBHTDgGFZcH0PtmPDsm34gQ/TtiBcF0EYwgt8lMIohmUaGNTP2YRtQjdMaJMJPo01GKbJwbbjsJnWFIzMtCxYjpP3bYw1DaUojpmB4wUQfsgrjcbaFGABaBWjxUtxkkA3dNTr17j4cIlms8XW7vagWS4834freew9z+P+9Pe8Px/zc0Bdx+XVFS6vPuK63sTH6zquGw20ugo6XQXdXg/tToe9ovTQURS0u12ogwEUGuupUBQFPbU/BSSqar+PwfCGP+oPh9ynjxvNFgfUGw32FERe7Q/QHww4TlFVqKqKVruDUhTFnKX/q3FSigRwZkcjBEEAYk5zZPGCXzQao3MjQuPxGIZBSckB6cCFEAyWZdnKjNI05RhD1+E4zhwwiiJelRoBfslkmrJRo1gikyTJFJCEKaVcGYxvVyIRJSkFMFAxPmNIg8XElwEzhLFkUOoTRhiGPHcL8D5nR+yYIaYM03z7t7acpemMKY3f5aVM4AZUDCJkWTrNehRBLp4hsXNcH77v82QYhLwIZTCVkscpeOozlgslhRMkJdcCxxE5oOMgjCKomsW3hiSUSDlj+29WsBtZHsYToxC2YA1NtDFs25mtuorRDlzPhT7RYJrGPCk0QdspDnfVVpx7HCe8wK0sc2KQrSSdRaPY2V3+L8JeFHgBmOYJmjEsZHFfdgUgxc8BFxjet9295TRlvVHZIiMZzXx+tSiw8PT2kELSPCkyzfj72ZaRJFBvdFiahsQPEJOAowiBEDNhp0nCGiUQekM4iXnlCcafMLkZohRLCb1eh9lqYdxoQW82YbXbsDod2N0ugkEfXqOBSEqQoOhg+LxJ0Dlj3w/gOTY8V0wBJ+/fY3h+DvX0FAPytRqUahU3797Ba7chLi7gUQE9O0Okabc0SIBUsS1HwBZinhTfshDYNlXLuYURJG2VMiglwtEI9odLjJ8/h10uF1nh7dOxOTNAx4EkCXAxum1LS5emwej2EGd3AdrO6hrM5UWPBRVZaksZ3qtiZ1SxE0TJHYDLrt6ya1hcLwZMZM4wWw441db0/0vgBxDC5dfMdV2WCf2mHRSvG5U8En2WZXczHOiCqy7VRsd2eCxdqMrLPAO67j/PkP/SLTFRePcz/9l3BeDfDEa1r6I9KOoAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/b589600f77889644f835b6546ed8f19d/8ac56/aws-monitor-lambda-concurrent-executions.webp 240w,
/static/b589600f77889644f835b6546ed8f19d/d3be9/aws-monitor-lambda-concurrent-executions.webp 480w,
/static/b589600f77889644f835b6546ed8f19d/83811/aws-monitor-lambda-concurrent-executions.webp 528w&quot;
              sizes=&quot;(max-width: 528px) 100vw, 528px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/b589600f77889644f835b6546ed8f19d/8ff5a/aws-monitor-lambda-concurrent-executions.png 240w,
/static/b589600f77889644f835b6546ed8f19d/e85cb/aws-monitor-lambda-concurrent-executions.png 480w,
/static/b589600f77889644f835b6546ed8f19d/4af8e/aws-monitor-lambda-concurrent-executions.png 528w&quot;
            sizes=&quot;(max-width: 528px) 100vw, 528px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/b589600f77889644f835b6546ed8f19d/4af8e/aws-monitor-lambda-concurrent-executions.png&quot;
            alt=&quot;AWS Lambda Monitor&quot;
            title=&quot;AWS Lambda Monitor&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;As you can see the AWS Lambda service has created 10 execution environments.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Check number of cold starts&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;On total we have made 11 requests, one initially in the browser, and then 10
with &lt;code class=&quot;language-text&quot;&gt;curl&lt;/code&gt;. Let’s see what the logs are saying (AWS CloudWatch logs).&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/54ed0084328ae8cc84ef72fb748b1e9c/d9ed0/aws-lambda-concurrent-logs.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 57.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAA7BAAAOwQG4kWvtAAACfUlEQVQoz1WSy4sbRxjE9X/nHvDFJrGTQ07J1SSBQCCGYExIIKxXXusxK2lGj5Fm+qGZnu6eGUm7klbWL6hFEnxoqrppqqvq644wCu0K7Naz9iWy0pRNRVkbitpgWovdOprHFvfg6fl3dN0bhvVf+MMWu20wG4vftTwdn+jEox6D/g3TuM9iFjHo3YT9cPCefu+Gyegj8+mQVTohnfd59/4r3t684I/bb8lHXaLuhNu/I/LVAjjR0VqRLVPKYo2tTODZakm+WrJapgFLrdg9bNk1O86vvuf86gf45jvKL74k/q3PYOhJozW62NMpTIUQkso6fN0ghEIqHVYmJEppKuc57B85Lv7kOPmd/eQt50PLm19LXjyXvPw65/mzBT/+VNIpyhKR51RVRe194EIIpBDkuUApibWW/bbhcfAz27vX7O9/4WG34cwhxNxvW86bCvhEZ5UMmUVdxCxCLUZMh11m9x+Y398xiz6g0zHFKma9SljLHJ2lFFpSrBLyJEJmmllcUaSKx8OBTmkMSgqsrfDeBYdSXqKq4LIyBmddQFuVeGexpsQ5S7E2pMsCmWvkVHL6dLp0aELEylqc8yFm6FCqwL2vaZqWum5omoa2bf9Da2v02uMri55Ljqfj/4KXnrz3ZFkeBnERzLIsdHs5t9bhnAv8gs47ytKSiwpTlKiZ5On0dBmKQeT/OnSfC+bXh+q6Du6d94FfRH3tMcYhlcWWBj1XV8GyqkJn1nnqpglfSGmNXq8RUgWBtt1cI7ctm80mVNBurpFz4Si1QSTiKpjHMdl4jJpOyScxycce016f6SBiORoj4hiZJAE/40kc7ke39yR3Y9apYn/Y8w+7RHB+sRxuwwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/54ed0084328ae8cc84ef72fb748b1e9c/8ac56/aws-lambda-concurrent-logs.webp 240w,
/static/54ed0084328ae8cc84ef72fb748b1e9c/d3be9/aws-lambda-concurrent-logs.webp 480w,
/static/54ed0084328ae8cc84ef72fb748b1e9c/e46b2/aws-lambda-concurrent-logs.webp 960w,
/static/54ed0084328ae8cc84ef72fb748b1e9c/47d61/aws-lambda-concurrent-logs.webp 1415w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/54ed0084328ae8cc84ef72fb748b1e9c/8ff5a/aws-lambda-concurrent-logs.png 240w,
/static/54ed0084328ae8cc84ef72fb748b1e9c/e85cb/aws-lambda-concurrent-logs.png 480w,
/static/54ed0084328ae8cc84ef72fb748b1e9c/d9199/aws-lambda-concurrent-logs.png 960w,
/static/54ed0084328ae8cc84ef72fb748b1e9c/d9ed0/aws-lambda-concurrent-logs.png 1415w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/54ed0084328ae8cc84ef72fb748b1e9c/d9199/aws-lambda-concurrent-logs.png&quot;
            alt=&quot;AWS CloudWatch Logs&quot;
            title=&quot;AWS CloudWatch Logs&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The intial request (browser) was served by a new execution environment, so we
had a cold start. A cold start is easy to identify in the logs by searching
for a &lt;code class=&quot;language-text&quot;&gt;Init Duration&lt;/code&gt; in the &lt;code class=&quot;language-text&quot;&gt;REPORT&lt;/code&gt; log.&lt;/p&gt;
&lt;p&gt;Next, when we launched 10 concurrent requests, the first request comming in
reuses the execution environment that was created for the initial request
completed in the browser (the instance was kept warm). &lt;strong&gt;For the remaining 9
requests the AWS Lambda service has created new 9 execution environments,
hence 9 cold starts&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When building synchronous APIs like a HTTP API, &lt;strong&gt;we want to avoid cold starts,
particularly if it’s a customer facing API&lt;/strong&gt;, because it will include more latency
in the whole request-reply flow. But a cold start is almost inevitable if we
want a scale to zero approach and avoiding to pay for resources when there is no
activity (HTTP requests).&lt;/p&gt;
&lt;h2 id=&quot;minimizing-cold-starts&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#minimizing-cold-starts&quot; aria-label=&quot;minimizing cold starts permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Minimizing Cold Starts&lt;/h2&gt;
&lt;p&gt;To minimize the impact of cold start we can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reduce the number of cold starts&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reduce the time of a cold start&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To &lt;strong&gt;reduce the number of cold starts&lt;/strong&gt; we can use &lt;a href=&quot;https://docs.aws.amazon.com/lambda/latest/dg/provisioned-concurrency.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Provisioned
Concurrency&lt;/strong&gt;&lt;/a&gt;.
Provisioned concurrency initializes a requested number of execution environments
so that they are &lt;strong&gt;prepared to respond immediately to your function’s invocations&lt;/strong&gt;.
Be aware that configuring provisioned concurrency &lt;strong&gt;incurs charges to your AWS
account&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;To &lt;strong&gt;minimize the time spent in a cold start&lt;/strong&gt; there are some things we can do:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;keep our package small&lt;/li&gt;
&lt;li&gt;minimize library dependencies&lt;/li&gt;
&lt;li&gt;adjust memory function (you can use &lt;a href=&quot;https://docs.aws.amazon.com/lambda/latest/operatorguide/profile-functions.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;AWS Lambda Power
Tuning&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;be lazy in initialization&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;can-your-http-api-live-with-cold-starts&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#can-your-http-api-live-with-cold-starts&quot; aria-label=&quot;can your http api live with cold starts permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Can your HTTP API live with Cold Starts?&lt;/h2&gt;
&lt;p&gt;It really depends. First, we need to &lt;strong&gt;measure the cost of a cold start in terms
of latency&lt;/strong&gt;. For example, the logs above are showing that a cold start takes
aprox. 500ms (for a very simple scenario). A cold start duration varies based on
programming language, runtime, etc.&lt;/p&gt;
&lt;p&gt;Second, we need to &lt;strong&gt;understand how our API is being used by consumers, who are
these consumers, and what are the patterns of usage during the day, day of week,
etc&lt;/strong&gt;. Based on that knowledge we can have an idea of what is the impact of a
cold start in the flow in which we are using our function.&lt;/p&gt;
&lt;p&gt;If we anticipate problems caused by cold starts, &lt;strong&gt;we should analyze what is the
cost (money) of configuring provisioned concurrency&lt;/strong&gt;. Furthermore, &lt;strong&gt;consider
using &lt;a href=&quot;https://docs.aws.amazon.com/lambda/latest/dg/provisioned-concurrency.html#managing-provisioned-concurency&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Provisioned Concurrency with Application Auto
Scaling&lt;/a&gt;&lt;/strong&gt;
to adjust the number of provisioned instances based on usage. &lt;strong&gt;Nevertheless, we
need to be aware that we will be charged by using provisioned concurrency&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;aws-serverless-alternatives-to-aws-lambda&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#aws-serverless-alternatives-to-aws-lambda&quot; aria-label=&quot;aws serverless alternatives to aws lambda permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;AWS Serverless alternatives to AWS Lambda&lt;/h2&gt;
&lt;p&gt;If we are not confortable with the concurrency execution model provided by AWS
Lambda, we can always use some alternatives in AWS:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://aws.amazon.com/apprunner/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;AWS App Runner&lt;/strong&gt;&lt;/a&gt; - a fully managed
container application service with auto scaling based on Max Concurrency - we
define the max number of requests that will trigger the scale-up process. The
AWS App Runner uses &lt;strong&gt;the normal execution model where a container instance
can serve multiple concurrent requests. There is always at least one instace
provisioned&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://aws.amazon.com/fargate/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Fargate&lt;/a&gt;&lt;/strong&gt; with &lt;a href=&quot;https://aws.amazon.com/ecs/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;AWS
ECS&lt;/a&gt; or &lt;a href=&quot;https://aws.amazon.com/eks/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;AWS EKS&lt;/a&gt;
(Kubernetes) - We are probably already using Kubernetes or any other container
orchestration engine, so we can always use it to host our HTTP API. This route
provides more flelibility and full control, however is the route that is more
complex.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;conclusion&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;When analyzing a specific scenario, &lt;strong&gt;AWS Lambda is typical the option that I
consider first in AWS when going serverless&lt;/strong&gt; . It’s &lt;strong&gt;really simple to use&lt;/strong&gt;,
&lt;strong&gt;integrates seamlessly with a lot of AWS Services&lt;/strong&gt; (SQS, S3, SNS, CloudWatch,
API Gateway, etc.), and provides a lot of great features specially when it comes
to scalability: &lt;strong&gt;scale-up or scale-down&lt;/strong&gt; (scale to zero).&lt;/p&gt;
&lt;p&gt;If we want a &lt;em&gt;“scale to zero”&lt;/em&gt; approach, then &lt;strong&gt;we need to be aware of cold
starts&lt;/strong&gt;, particularly in case of synchronous APIs, where it can cause some
impact in terms of latency. If the scenario being analyzed cannot live with cold
starts, &lt;strong&gt;I would consider using AWS App Runner&lt;/strong&gt; which has a very interesting
&lt;a href=&quot;https://aws.amazon.com/apprunner/pricing/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;pricing model&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Regarding &lt;strong&gt;Kubernetes&lt;/strong&gt; (AWS EKS), I think it makes totally sense when it’s an
initiative enterprise wide. The learning curve is not negligenciable (even when
we don’t need to install and administer the cluster like in AWS EKS), and
typically we need to spend some time configuring the cluster until we have all
the knobs needed. For example, if we want to have auto-scale based on events we
might need to have &lt;a href=&quot;https://keda.sh/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;KEDA&lt;/a&gt; installed (that’s exactly what
Microsoft did with &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/container-apps/overview&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Azure Container
Apps&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;See you next time. I will continue to explore other scenarios like gRPC and
WebSockets.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Visual Studio 2022 - Remote Testing]]></title><description><![CDATA[This post shows how Remote Testing works in Visual Studio 2022, by running and
debugging a unit test in a WSL Ubuntu distribution.
]]></description><link>https://bfcamara.com/posts/vs2022-remote-testing/</link><guid isPermaLink="false">https://bfcamara.com/posts/vs2022-remote-testing/</guid><pubDate>Tue, 21 Dec 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/93456fa50ae253d20dda829d47de1d89/5a190/vs2022-remote-testing.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 42.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABi0lEQVQoz23LzW7UMBQF4DwGRYnt62SS2L6OHf9M8+M0k5lJWSAY0SI2PAUS7y80hUUXfDqLoyOdjPNaCaG0rVQAKAHKGI/exxiPMT52xgqUSmqNncZOKd0IAQCtaIXCrHeP1sS26VrplDSi1qK1ojUavRQWldPaK9lLdK0OSlghTAjHdT0ty1M2PIVhjtN0nE7DMvvRGes757q0jD7YtIz7fh3m6Rz8q+mU643p0pLmlIZxytb0Nbo9umt0e28uvblYvZ2Wmzfn3pyNnqdpmpclhfArz89VdWhbjZgX5COh2brf9ucfl/VlW1/O67d5/KLldjl9v26vnz/9nIdnREwpDdMke7MRIopCas3LkvIyK1sWtxiD6zslVYMoqwOLRzeOYV0X76zq0AfX1DVjLGcMKEVEACCMZTllFaW/Pzz4qiKcl7xkDAA4vOGcV82hbhoAoIQweoeI7O+5pvRG6ACQk38ovYcQSgry9rkX+k6HCJwT4JmgtAF4oP8HAIyx90tB6Wbt4VAXvPwDbZNdx0UA53sAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/93456fa50ae253d20dda829d47de1d89/8ac56/vs2022-remote-testing.webp 240w,
/static/93456fa50ae253d20dda829d47de1d89/d3be9/vs2022-remote-testing.webp 480w,
/static/93456fa50ae253d20dda829d47de1d89/d00b9/vs2022-remote-testing.webp 800w&quot;
              sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/93456fa50ae253d20dda829d47de1d89/8ff5a/vs2022-remote-testing.png 240w,
/static/93456fa50ae253d20dda829d47de1d89/e85cb/vs2022-remote-testing.png 480w,
/static/93456fa50ae253d20dda829d47de1d89/5a190/vs2022-remote-testing.png 800w&quot;
            sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/93456fa50ae253d20dda829d47de1d89/5a190/vs2022-remote-testing.png&quot;
            alt=&quot;Visual Studio 2022 - Remote Testing&quot;
            title=&quot;Visual Studio 2022 - Remote Testing&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Several months ago I wrote a &lt;a href=&quot;/posts/vs2019-debugging-unit-test-in-container/&quot;&gt;blog post explaining how could we debug a unit
test running in a Linux container using Visual Studio
2019&lt;/a&gt;. In that post I mentioned that
the experience is far from being great in VS2019. It was possible, but it
required some manual steps.&lt;/p&gt;
&lt;p&gt;When we want to debug a unit test running in a Linux container, our
&lt;strong&gt;expectation is to have the same experience as when debugging locally&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go to Test Explorer&lt;/li&gt;
&lt;li&gt;Right Click on the Test and select Debug&lt;/li&gt;
&lt;li&gt;The debugger starts and stops in a breakpoint inside the test&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That’s exactly what &lt;strong&gt;Visual Studio 2022 brought to us with &lt;a href=&quot;https://docs.microsoft.com/en-us/visualstudio/test/remote-testing?view=vs-2022&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Remote
Testing&lt;/a&gt;&lt;/strong&gt;. Let’s see how it works.&lt;/p&gt;
&lt;p&gt;Create a &lt;a href=&quot;https://xunit.net/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;xUnit&lt;/a&gt; test project.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 936px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/850a7efa9fa9279a33eb30d877d5237d/6d2da/vs2022-create-xunit-test-project.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 70%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABMklEQVQoz42SbU7DMAyGexJgTezYThsnbdpRwTbYh8YRuAD3vwLqxgRj3bRH+RFFeZw3iYvOWAIw1pqyNCfK09xOgYiOqLRYvDw+fTG/7T/2+91iuVytVovF63r9vt1strsdMU2XABhla2EpvutyP++DakypaZq2bfu+zzkz8y25BPSqbdOICBE7RACEC6ZlA6ihTimpaoxKNJHzKJ+t/5xsoct5GIYYYzpkvmQsHc7rnmRU1fkw1DF6EX8FZkbEidgiUodQ1XVVVV784fL/uXpnEdGgGoKGEVV1iNNf/EeeGSiQxJjf9rjRG39Va8GxLxz7O3bb42sfOm9WmgdrjVShAMf2PpmIRJhc8jQgiHU0xr5HNsaoxtxlrTfPzSe5BMQFUoXk7xljRmQgZx0ACZJ8AxfCg5HqwFAMAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/850a7efa9fa9279a33eb30d877d5237d/8ac56/vs2022-create-xunit-test-project.webp 240w,
/static/850a7efa9fa9279a33eb30d877d5237d/d3be9/vs2022-create-xunit-test-project.webp 480w,
/static/850a7efa9fa9279a33eb30d877d5237d/40732/vs2022-create-xunit-test-project.webp 936w&quot;
              sizes=&quot;(max-width: 936px) 100vw, 936px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/850a7efa9fa9279a33eb30d877d5237d/8ff5a/vs2022-create-xunit-test-project.png 240w,
/static/850a7efa9fa9279a33eb30d877d5237d/e85cb/vs2022-create-xunit-test-project.png 480w,
/static/850a7efa9fa9279a33eb30d877d5237d/6d2da/vs2022-create-xunit-test-project.png 936w&quot;
            sizes=&quot;(max-width: 936px) 100vw, 936px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/850a7efa9fa9279a33eb30d877d5237d/6d2da/vs2022-create-xunit-test-project.png&quot;
            alt=&quot;xUnit test project&quot;
            title=&quot;xUnit test project&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Choose .NET 6.0&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/385a76fe51aa0a16042843075e235693/91b29/vs2022-create-xunit-proj-net6.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 67.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABC0lEQVQoz52RW07DMBBFvREoseflcR6Wo7h1aZrywS4Q+18GSkoBQSktR/djRvLVnRmbqrLWutXCw8JH7X4DZqwDUzkUr6WUsi19SsMw5JyHnFOfljeAPyEiRGBvKgsa6sNhOjxN4ziWUsZxnPb73e4xhMDMcB7nSEzlgEVijE3biggTe6/e+xBC23aqetFsQbzm9SalPsYoIqel4FgcxxSRs8lISC/3dw0iMtP31T7rM+aVww7x2bnqFHUdX5Itwo2cDgZIN3uPZkCadbsXxZumS4D/GNqGpjPA/srk5ebvHze3rIZEARCcuyxnrWrI676rd9v+NfCGRGYz+oCif4q8sgb2tfhIUpM2bwOlfeINhi4QAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/385a76fe51aa0a16042843075e235693/8ac56/vs2022-create-xunit-proj-net6.webp 240w,
/static/385a76fe51aa0a16042843075e235693/d3be9/vs2022-create-xunit-proj-net6.webp 480w,
/static/385a76fe51aa0a16042843075e235693/e46b2/vs2022-create-xunit-proj-net6.webp 960w,
/static/385a76fe51aa0a16042843075e235693/b4d37/vs2022-create-xunit-proj-net6.webp 983w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/385a76fe51aa0a16042843075e235693/8ff5a/vs2022-create-xunit-proj-net6.png 240w,
/static/385a76fe51aa0a16042843075e235693/e85cb/vs2022-create-xunit-proj-net6.png 480w,
/static/385a76fe51aa0a16042843075e235693/d9199/vs2022-create-xunit-proj-net6.png 960w,
/static/385a76fe51aa0a16042843075e235693/91b29/vs2022-create-xunit-proj-net6.png 983w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/385a76fe51aa0a16042843075e235693/d9199/vs2022-create-xunit-proj-net6.png&quot;
            alt=&quot;xUnit test project .NET 6.0&quot;
            title=&quot;xUnit test project .NET 6.0&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;For demonstrating purposes, let’s create the same test used when demonstrating how to debug in Visual Studio 2019. This is a &lt;strong&gt;simple test that asserts that the test is running in a Linux container&lt;/strong&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;  &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Fact&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Test_is_running_in_linux_container&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

      Assert&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;RuntimeInformation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;IsOSPlatform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OSPlatform&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Linux&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now add a new file &lt;code class=&quot;language-text&quot;&gt;testEnvironments.json&lt;/code&gt; to the root of the solution&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// value must be 1&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;environments&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;WSL-Ubuntu&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;wsl&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;wslDistribution&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Ubuntu-20.04&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Basically I am &lt;strong&gt;adding a new test environment to run my tests in a WSL Ubuntu
20.04 distribution&lt;/strong&gt;. To check the list of distributions you can run &lt;code class=&quot;language-text&quot;&gt;wsl
--list&lt;/code&gt; in a command prompt. In Test Explorer you now have a dropdown with the
list of test environments. Let’s select the test environment just added,
&lt;code class=&quot;language-text&quot;&gt;WSL-Ubuntu&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/aa7893970eba1d699742b89787d358fb/307e7/vs2022-select-test-environment.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 36.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABDElEQVQY022P22rDMAyG8xwjlg+yfIwPcdx0bdpusMtt7/86oxmFDvYhxH8hiU9DnVtKtS2tliXG3OriQ1rKfD2fj6fT9e39sm2llN6X1to8zznn4EPJpZQylLZsl8vp9Xg49G07f399tnX9yOkmxIsi41OMMYSQUgrBCyn4E4NQmpw3pBHRGFtq5ZwrKTtqqdDGrIiERg7AARhj4ziyce+MDX9OcQ47iKiNVZrMVF3tzhsbnQ12mpwPTmmFiEKIAYAzxgCAcy527stKkfNoLGqSLmtCZUiRNkaTISRNRFLKIaVpXQ85Z//AWuusJWOAi7vKbgh73dMDABjilHrviPhsjohEep/4ffZ/fgCTIz7DI1yQnwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/aa7893970eba1d699742b89787d358fb/8ac56/vs2022-select-test-environment.webp 240w,
/static/aa7893970eba1d699742b89787d358fb/d3be9/vs2022-select-test-environment.webp 480w,
/static/aa7893970eba1d699742b89787d358fb/e46b2/vs2022-select-test-environment.webp 960w,
/static/aa7893970eba1d699742b89787d358fb/f9905/vs2022-select-test-environment.webp 1354w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/aa7893970eba1d699742b89787d358fb/8ff5a/vs2022-select-test-environment.png 240w,
/static/aa7893970eba1d699742b89787d358fb/e85cb/vs2022-select-test-environment.png 480w,
/static/aa7893970eba1d699742b89787d358fb/d9199/vs2022-select-test-environment.png 960w,
/static/aa7893970eba1d699742b89787d358fb/307e7/vs2022-select-test-environment.png 1354w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/aa7893970eba1d699742b89787d358fb/d9199/vs2022-select-test-environment.png&quot;
            alt=&quot;VS2022 - Select Test Environment&quot;
            title=&quot;VS2022 - Select Test Environment&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: if you don’t see the new environment, then close Visual Studio and
launch it again. This is an experimental feature and I have experienced some
issues while playing with it. We could also add environments connected to docker
containers running locally on Docker Desktop, or even remote environments
connected by SSH.&lt;/p&gt;
&lt;p&gt;Put a breakpoint in the test that you want to debug and select it in Test
Explorer to start debugging it.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/8b807ff4dfb017a9bbb9a5cc23212b95/aa878/vs2022-start-debug-test.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 28.333333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABBklEQVQY022LS26DMBQAOUcwDu/58/AfGxxoAgnZVFE3vf9tqlaq1EVHo9lNk3Md85RjCb6MqU5lKeVS4vR2WffH/Xrb3l+v5/OY61RrzTnHGJ1zMcSYUrNe11rnFEK9zPtjv98faZ427z6tQSJF1sZsjfHOjWPy3gshAABRCCGadVvrXJdlmaZCRJosouTn3kkpEAGlHGyvJAdgXcc6fmrbU9u2jLWMNcdxxBjzOJLWXddx3nHOGedBqQ8UQilXcgohGIqGwqB/SiSQEJsQInzTA8D5F8Z51DrRwKEfUGzG7t7t3m/O7t7v3t+MuQ6mISJA1Fr/nc+cS6VgsFIpRDj3/T8CfAEEbTpxfScW5gAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/8b807ff4dfb017a9bbb9a5cc23212b95/8ac56/vs2022-start-debug-test.webp 240w,
/static/8b807ff4dfb017a9bbb9a5cc23212b95/d3be9/vs2022-start-debug-test.webp 480w,
/static/8b807ff4dfb017a9bbb9a5cc23212b95/e46b2/vs2022-start-debug-test.webp 960w,
/static/8b807ff4dfb017a9bbb9a5cc23212b95/47c81/vs2022-start-debug-test.webp 1385w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/8b807ff4dfb017a9bbb9a5cc23212b95/8ff5a/vs2022-start-debug-test.png 240w,
/static/8b807ff4dfb017a9bbb9a5cc23212b95/e85cb/vs2022-start-debug-test.png 480w,
/static/8b807ff4dfb017a9bbb9a5cc23212b95/d9199/vs2022-start-debug-test.png 960w,
/static/8b807ff4dfb017a9bbb9a5cc23212b95/aa878/vs2022-start-debug-test.png 1385w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/8b807ff4dfb017a9bbb9a5cc23212b95/d9199/vs2022-start-debug-test.png&quot;
            alt=&quot;VS2022 - Start Debug Test&quot;
            title=&quot;VS2022 - Start Debug Test&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Debugger stops at the breakpoint&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a807d9d94b5d344f9728fa8d78c6d0ce/9f9a4/vs2022-debugging-unit-test.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 28.333333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABA0lEQVQY03WM20rDQBiE8xph//33fMombJpkY1pSL3qwBpTeeNH38Ub0pSUFxRuHj4EZmCnqehg2D6kZ27TdTvs+Txvn56qKdZNznvf73fx4Oj/lnPuuG3Nu2zalFKpQ101xu369nt/fXj5v14/tdOz6zks1EiIBhFLIOOVKGe+8dd5ZaxARABApIi20ikpUWkWjozZGSkGRUc45ojZGSOmqGFJCKSllAAhACaFlScqSFOsHW28YQ8YY4uqcrZW3xvqgjY0pH87TsgzPy7gs4+UyHk/d4dgV7Ef8rt+I69hKH3ohZi6008Erf8d5FYIOQf87ppTGGH0IFoAhEqDwB0JWvgGtWTk25zGXewAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/a807d9d94b5d344f9728fa8d78c6d0ce/8ac56/vs2022-debugging-unit-test.webp 240w,
/static/a807d9d94b5d344f9728fa8d78c6d0ce/d3be9/vs2022-debugging-unit-test.webp 480w,
/static/a807d9d94b5d344f9728fa8d78c6d0ce/e46b2/vs2022-debugging-unit-test.webp 960w,
/static/a807d9d94b5d344f9728fa8d78c6d0ce/f992d/vs2022-debugging-unit-test.webp 1440w,
/static/a807d9d94b5d344f9728fa8d78c6d0ce/9fbc2/vs2022-debugging-unit-test.webp 1560w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/a807d9d94b5d344f9728fa8d78c6d0ce/8ff5a/vs2022-debugging-unit-test.png 240w,
/static/a807d9d94b5d344f9728fa8d78c6d0ce/e85cb/vs2022-debugging-unit-test.png 480w,
/static/a807d9d94b5d344f9728fa8d78c6d0ce/d9199/vs2022-debugging-unit-test.png 960w,
/static/a807d9d94b5d344f9728fa8d78c6d0ce/07a9c/vs2022-debugging-unit-test.png 1440w,
/static/a807d9d94b5d344f9728fa8d78c6d0ce/9f9a4/vs2022-debugging-unit-test.png 1560w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/a807d9d94b5d344f9728fa8d78c6d0ce/d9199/vs2022-debugging-unit-test.png&quot;
            alt=&quot;VS2022 - Debugging&quot;
            title=&quot;VS2022 - Debugging&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;And the test passes.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/6dde25e74efb7a61e20c09965cb45236/c4451/vs2022-test-passing.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 30.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABBUlEQVQY003LyW6DMBSFYZ4jeLjX2HgeYodATKBSpfT9H6lq1EWOvsXZ/EPMpVxvPtXoYmv31tbaltt1uZZWW3v0vm2P3nspJaUUY3TOWWNDCN77oS71OI9979u6ruu27/t9e6zOvbT2ORvrYmm11hhDztk5J6WUk1RSSSmHXOLP6/s4zudx9L23W9NaU0onxpRSDFDZOBmLs0IhAHEk5ELISAihdLCcn5xTRAQQQiAiY4xzDgBm1ohCexdD8noOWgWtopndrGZECTAIgIn/DwDgfSilAOCNlcbJSW7Of6V05nSmePxJzxAWawcOwD5izrkQIoTAGFNag5iA85HSy4fxjTD2C1SZOT76GM8KAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/6dde25e74efb7a61e20c09965cb45236/8ac56/vs2022-test-passing.webp 240w,
/static/6dde25e74efb7a61e20c09965cb45236/d3be9/vs2022-test-passing.webp 480w,
/static/6dde25e74efb7a61e20c09965cb45236/e46b2/vs2022-test-passing.webp 960w,
/static/6dde25e74efb7a61e20c09965cb45236/f992d/vs2022-test-passing.webp 1440w,
/static/6dde25e74efb7a61e20c09965cb45236/a7dc3/vs2022-test-passing.webp 1450w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/6dde25e74efb7a61e20c09965cb45236/8ff5a/vs2022-test-passing.png 240w,
/static/6dde25e74efb7a61e20c09965cb45236/e85cb/vs2022-test-passing.png 480w,
/static/6dde25e74efb7a61e20c09965cb45236/d9199/vs2022-test-passing.png 960w,
/static/6dde25e74efb7a61e20c09965cb45236/07a9c/vs2022-test-passing.png 1440w,
/static/6dde25e74efb7a61e20c09965cb45236/c4451/vs2022-test-passing.png 1450w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/6dde25e74efb7a61e20c09965cb45236/d9199/vs2022-test-passing.png&quot;
            alt=&quot;VS2022 - Test Passing&quot;
            title=&quot;VS2022 - Test Passing&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Change the environment to &lt;code class=&quot;language-text&quot;&gt;&amp;lt; Local Windows Environment &gt;&lt;/code&gt; and you will see that
the test fails.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/722b3c7c00731048ef239f8f7f886be8/d318f/vs2022-test-fails.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 26.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAIAAADKYVtkAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA3ElEQVQY003LTWrDMBBAYd8jkTQz0ugnsS3ZtSO5wY5DCoFC6S267qq9fqmhJR9v+6qcn3Oe8zj1XR7HqZQp51KehrWN3TDE1J3KuZScUuz7vmkavwmb6rZ8vN+/7tfP15fv5fx2ykMIAaRcpHTMewXaHdk5tmyZtdbiQXUj1/iWuXau8dZbY5RSQikkCs4BUd0mEw7EhjQSIWkCBLmpvJJS7IXYCbEDUP8Q8egPqE2wbm7jGuO1i5fYrileYprrenC+ktthrTWG4e+WvzNYH9BYrQlBEcBjGpEQfwB8sDCPYQFyigAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/722b3c7c00731048ef239f8f7f886be8/8ac56/vs2022-test-fails.webp 240w,
/static/722b3c7c00731048ef239f8f7f886be8/d3be9/vs2022-test-fails.webp 480w,
/static/722b3c7c00731048ef239f8f7f886be8/e46b2/vs2022-test-fails.webp 960w,
/static/722b3c7c00731048ef239f8f7f886be8/e6c83/vs2022-test-fails.webp 1421w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/722b3c7c00731048ef239f8f7f886be8/8ff5a/vs2022-test-fails.png 240w,
/static/722b3c7c00731048ef239f8f7f886be8/e85cb/vs2022-test-fails.png 480w,
/static/722b3c7c00731048ef239f8f7f886be8/d9199/vs2022-test-fails.png 960w,
/static/722b3c7c00731048ef239f8f7f886be8/d318f/vs2022-test-fails.png 1421w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/722b3c7c00731048ef239f8f7f886be8/d9199/vs2022-test-fails.png&quot;
            alt=&quot;VS2022 - Test Failing&quot;
            title=&quot;VS2022 - Test Failing&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Thank you Visual Studio 2022 for greatly simplify this experience of remote testing.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Migrating Azure Pipelines from Classic to YAML]]></title><description><![CDATA[This post summarizes some hints and caveats of migrating Classic Azure Pipelines to YAML.]]></description><link>https://bfcamara.com/posts/migrate-az-pipelines-from-classic-to-yaml/</link><guid isPermaLink="false">https://bfcamara.com/posts/migrate-az-pipelines-from-classic-to-yaml/</guid><pubDate>Wed, 20 Oct 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 308px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/efd9d914e0881c3b2ece5faebad71ef0/2ece4/post-azpipelines.drawio.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 78.75000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAAsTAAALEwEAmpwYAAACuklEQVQ4y42Ua0sUYRTH5yv0LvoAgR8g6DMEEQQVQZKW9aKIehdERBKhgZV2A19EpKZlUYEQJYmh2w3EXVNr3fuuMzuzl9ndaS8zuzszv5hZd1Mz6w+HOXDO83uec54zj8A62bbd+lpWwxzVTZvu0TSHexOcHJA4eD1B38uMG7Nsu7XOkcAmrQ829Wy2wP7uuAt9NqNxflDm2li6lf9XoLl2osm5DMd6fHT1LXD2jp+O2yJHehPcepVlylfiykiKa0//A+iU5uj+6xi7j0+z54yH/VeDtN+UaL8p0tkvcvGR4pbcBG5bsrkGfDqdpK1jmn2Xl+nsl+i6q3DqXppjfasu7MyDJIsx/d/AZsAB944FuTCYoHMgxen7aRd85MYqPeMKZcNqwTZLaPbgdy9sjFoj0S9WuTSs0nVH5uiNGLs7PjM6JbqxWt3auofrYc0xmQvqKLm663tDRfae99J2wsOOA5M8fJNo9LtuYVl/2h9j48gX1pmcLxFRqlTrFmcHlth1eIqdhz7wfCbDdhIGP0qcGPVz4WWQcy8aNh0okC/aZDSzlRhL15hbTvIjECWZlFgVRcQtTHi/kiOQLvMpqvE1ruFPlfkaK4Bdw7ZqGEYVw9Apaio/lhfQtDya9pNCoUA+n29ZuVwmGo0iBFJlaqbFl5hGMN3wfXGVrJojny+4C0ulEtmsytLS8rblqqqK8E3WSRVrLMg6IbWGqtv4M9UtFzgnME2TSqXCxMQE4+PjDA0N4ff73biiKAiBhIyUqxBIKHyPiCyGJRJy2h2fjeMEkUiEer1x+ysrK/h8Prxer7uRo2w2i/Du7Rs+eWYZGX7Mk5Fhxp4M89Hj2TBjTaADMQxj3Z9lIssy8Xjc3Wx+fh6hWCyRy+UxqlUcv1LR0XV9w1PW9DOZjAuVJIlQKEQ4HHYvoylN0/gFR0mOc6cIfqYAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/efd9d914e0881c3b2ece5faebad71ef0/8ac56/post-azpipelines.drawio.webp 240w,
/static/efd9d914e0881c3b2ece5faebad71ef0/6882a/post-azpipelines.drawio.webp 308w&quot;
              sizes=&quot;(max-width: 308px) 100vw, 308px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/efd9d914e0881c3b2ece5faebad71ef0/8ff5a/post-azpipelines.drawio.png 240w,
/static/efd9d914e0881c3b2ece5faebad71ef0/2ece4/post-azpipelines.drawio.png 308w&quot;
            sizes=&quot;(max-width: 308px) 100vw, 308px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/efd9d914e0881c3b2ece5faebad71ef0/2ece4/post-azpipelines.drawio.png&quot;
            alt=&quot;YAML Azure Pipelines&quot;
            title=&quot;YAML Azure Pipelines&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;-cicd-pipelines-as-code&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#-cicd-pipelines-as-code&quot; aria-label=&quot; cicd pipelines as code permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;🌲 CI/CD Pipelines as Code&lt;/h2&gt;
&lt;p&gt;If you have started using Azure DevOps several years ago (maybe its name was Visual
Studio Team Services by then), then you are probably still using the &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/devops/pipelines/get-started/pipelines-get-started?view=azure-devops#define-pipelines-using-the-classic-interface&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Classic
Build and
Release&lt;/a&gt;
pipelines to fulfill your CI/CD needs. There is nothing wrong with these Classic
Pipelines but the trend over the years has been to follow the &lt;strong&gt;Everything as
Code&lt;/strong&gt; approach, including &lt;strong&gt;CI/CD Pipelines as Code&lt;/strong&gt;, and &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/devops/pipelines/get-started/pipelines-get-started?view=azure-devops#define-pipelines-using-yaml-syntax&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Azure Pipelines also supports it by using YAML Pipelines&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are obvious &lt;strong&gt;advantages in having CI/CD Pipelines as Code&lt;/strong&gt;, in which its
definitions live in a source control repo as YAML text files:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;we can &lt;strong&gt;use the same code flow for CI/CD&lt;/strong&gt;, for example using pull requests to make a
change in the pipeline and require a review from a specific group of
people;&lt;/li&gt;
&lt;li&gt;it’s &lt;strong&gt;easier to check the history&lt;/strong&gt; of changes&lt;/li&gt;
&lt;li&gt;we can use the &lt;strong&gt;same tooling we are used for source control&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;it’s &lt;strong&gt;easier to reuse and share&lt;/strong&gt; pipelines common blocks&lt;/li&gt;
&lt;li&gt;it’s &lt;strong&gt;easier to collaborate&lt;/strong&gt; on pipeline definitions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Over the last few days I have been working in a migration to transform
Classic Build and Release pipelines into YAML Pipelines.&lt;/p&gt;
&lt;h2 id=&quot;️-unify-build-and-release-pipelines&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%EF%B8%8F-unify-build-and-release-pipelines&quot; aria-label=&quot;️ unify build and release pipelines permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;🤼‍♂️ Unify Build and Release Pipelines&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;In the Classic approach the Build and the Release are two different pipelines&lt;/strong&gt;.
The Classic Build doesn’t support multi stages and typically finishes by
publishing the build output artifacts. Following is an example of a Classic
Build pipeline.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/d1e873b8fbe352bb7994205961833b9e/5c744/azure-devops-classic-build.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 49.16666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABlUlEQVQoz42RSYvbQBCF9UcmHlu7bW2t1uqx5EVLS/JMyISQUyCQQzww///6QlWw8RAfcng01RTfe1WlrVdLuI7NWi1dOLYFx7Hgug7/hYEP2zIx+/SA+eMM3nqNpWPD0BcwDR22acJY6Nz7/dsrNGou8gzV9gllkcMyDeiL+VWL+SO/BPgoHZ5rwSoVZtM7HpwAv37+gOb5PmIhEIUBAt9j11uRAZnSeytOZxmw3RXcIIZhmng7/4bm+x6nSxOJRMbI0gRJIiFjcRX90ehkeisRhZAiRBT8XQMDqbFrG5ymEdM4oO9aDKrHYb9jlZsCcSogwpABFxGQVrXf1RAi4v2/nc/QRBgwcBwUlOrQHA9omyN2dcXJiyJj4CXRRRQkz1JsnzZcX4HUSLDTacTYTVB9j2FQDCYoA2V0F0gJ62r7L3AYekz9BNUo9F3DY9dVxcA8TxEnNPJ/AumylKZrW6i+470dD3vUlC7PkKYS8s7IVNOxNmXxEUgFHePr6xd8fnnmg4zDwCaksswh8/juyAQj81vgH7LIRfpziBGNAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/d1e873b8fbe352bb7994205961833b9e/8ac56/azure-devops-classic-build.webp 240w,
/static/d1e873b8fbe352bb7994205961833b9e/d3be9/azure-devops-classic-build.webp 480w,
/static/d1e873b8fbe352bb7994205961833b9e/e46b2/azure-devops-classic-build.webp 960w,
/static/d1e873b8fbe352bb7994205961833b9e/b732a/azure-devops-classic-build.webp 1206w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/d1e873b8fbe352bb7994205961833b9e/8ff5a/azure-devops-classic-build.png 240w,
/static/d1e873b8fbe352bb7994205961833b9e/e85cb/azure-devops-classic-build.png 480w,
/static/d1e873b8fbe352bb7994205961833b9e/d9199/azure-devops-classic-build.png 960w,
/static/d1e873b8fbe352bb7994205961833b9e/5c744/azure-devops-classic-build.png 1206w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/d1e873b8fbe352bb7994205961833b9e/d9199/azure-devops-classic-build.png&quot;
            alt=&quot;Classic Build Pipeline&quot;
            title=&quot;Classic Build Pipeline&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The build artifacts are then consumed by a classic Release pipeline&lt;/strong&gt; where we
have the different stages (DEV, QA, PROD, etc.) to where we want to deploy.
Following is an example of a Classic Release pipeline.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/f7c79bc44512bdda1d263da62ad9f238/636d3/azure-devops-classic-release.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 41.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABc0lEQVQoz2WSUXLbMAxEdY7KoiSSIAhKtCS7lhU7aTNxfjKZyT16/wNsB0zqfuQDQ5EDvl2sWJ0kQSQiSQSHAO8tnLNlv88DhiRwtkdrGnStAXkHDlTOhANcmmHnK3w+YplGVL/nCcP4ebFrm9Js+w7jOGLbztjWE8YhFZhC/5dBHgR8fQO9/4FZ39DUP1BNrx94WE94vF6Q84ghRQyREKMgxoi+a4srXVUokIdpdsWhdw7sLRJZWLMrotXTr3NR1GYtvWiaBsuUcTz+BA8TiMK9JwlDmMFiMU6EQATmUEonqV4uT2iaGt3XKKrS7GocDwvW8wNknItbjUPFNLeo2bkeIVD5jipAVGKrHp9vMLu6gP6VAg/LjPN2geSljK7nCtSRyTn0fQsiV/Yp21ISGdXt5bkAvgEPE9Zt+3QocgfGL4f6Goh8+YkimrmHsKB6vd2+AY2pMdAeSz4j5T048B2ozylFhicLZiquJEZIDJgOEX8BFufo7M9t0/gAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/f7c79bc44512bdda1d263da62ad9f238/8ac56/azure-devops-classic-release.webp 240w,
/static/f7c79bc44512bdda1d263da62ad9f238/d3be9/azure-devops-classic-release.webp 480w,
/static/f7c79bc44512bdda1d263da62ad9f238/e46b2/azure-devops-classic-release.webp 960w,
/static/f7c79bc44512bdda1d263da62ad9f238/41bb6/azure-devops-classic-release.webp 1222w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/f7c79bc44512bdda1d263da62ad9f238/8ff5a/azure-devops-classic-release.png 240w,
/static/f7c79bc44512bdda1d263da62ad9f238/e85cb/azure-devops-classic-release.png 480w,
/static/f7c79bc44512bdda1d263da62ad9f238/d9199/azure-devops-classic-release.png 960w,
/static/f7c79bc44512bdda1d263da62ad9f238/636d3/azure-devops-classic-release.png 1222w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/f7c79bc44512bdda1d263da62ad9f238/d9199/azure-devops-classic-release.png&quot;
            alt=&quot;Classic Release Pipeline&quot;
            title=&quot;Classic Release Pipeline&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The team was not using any dependency between classic release stages, and the
deployments to all stages (except to DEV) were being triggered manually, as we
can see in the image below.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 857px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/6a4a4752b933607501d8cede56b58bb7/3cd52/azure-pipelines-classic-release-depoy-manually.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 86.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAIAAABSJhvpAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACLElEQVQ4y21S2W7bMBD0j1SnxeXukpRISpbvq3GOxnHaphfQAn3qW4H+/1tBKU7VJMCAoLia2dljxHaSxJEQhTEaijGAIIRinBPKcZ6VpTFGSxBSCKMVEybRm2Kc26piwtEDkdbceN/UAYrJGFWVpvaOCPMszdIkTeI0ibMkztIkiaMkjvrH0XY6KSvrvLdVkDZG5VmmldYdM0+TQoBRXBSCEHuVJIl7idHy+jMxIzGh7IESulN0l3BnQqLHEEoIVXQY2Y9fjKLddm009zGUQivebtaaGQohBYAINffRJwmUMHp/NSNCxdSnZcIOEqU0BktLlaPKc+V5YOpM/npxxYRN7Tfr1XIxn03bqtRMiACuNs3M6FKgynQpFIfH/8j743dF6J1dr5bz6VSC4CcjhForo3QeWhsHxWeZ7483mkmCAFF07Y25M48SehWtmQlBAr0kn05HQtlOGgkiiaMozXpa+C9A9GB8JNCZeSZLWCzX6/3BORcVSkpQwUvhmulk+bae75rFrl3ulWIZ9m+Y+e4Y8iAyUTHOizxlCralyO3mgz/9ocOv+u73ePOTjUUocEi+vb0mlIpQdRUqFSoMrsXYLS7b6x/N4Wtz+GZ3D6wNPst8ub+XIIar03cFQLS1O94ctqv5xW51ud+8MudPi3dy0IN/awSiqkrvrHPWWeu945dzPi22wzKeyBJEaXTbTiaNz9Mkz9JX5tzOWnqZuTu14tAFpvB5rnY4qr8qdrAQN19TwQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/6a4a4752b933607501d8cede56b58bb7/8ac56/azure-pipelines-classic-release-depoy-manually.webp 240w,
/static/6a4a4752b933607501d8cede56b58bb7/d3be9/azure-pipelines-classic-release-depoy-manually.webp 480w,
/static/6a4a4752b933607501d8cede56b58bb7/a145c/azure-pipelines-classic-release-depoy-manually.webp 857w&quot;
              sizes=&quot;(max-width: 857px) 100vw, 857px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/6a4a4752b933607501d8cede56b58bb7/8ff5a/azure-pipelines-classic-release-depoy-manually.png 240w,
/static/6a4a4752b933607501d8cede56b58bb7/e85cb/azure-pipelines-classic-release-depoy-manually.png 480w,
/static/6a4a4752b933607501d8cede56b58bb7/3cd52/azure-pipelines-classic-release-depoy-manually.png 857w&quot;
            sizes=&quot;(max-width: 857px) 100vw, 857px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/6a4a4752b933607501d8cede56b58bb7/3cd52/azure-pipelines-classic-release-depoy-manually.png&quot;
            alt=&quot;Classic Release - Trigger Manually&quot;
            title=&quot;Classic Release - Trigger Manually&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;With the YAML approach we can have multi stages&lt;/strong&gt; which allows us to have in a
single pipeline both the Build (as the first stage) and each of the deployment stages
(DEV, QA, PROD. etc.). &lt;strong&gt;The main difference is that in the YAML approach we can
have just a pipeline definition instead of two in classic&lt;/strong&gt; (Build definition and Release
definition).&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/57b210669e3c737faafd90bf49ca20cd/712f7/azure-pipelines-single-yaml.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 45.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABhUlEQVQoz0WQV87bMBCEdRVbhaIsiUUsogpJ9e4/yXOSt5wnSDlAjhrY+uMA87DAzjeDXUdEMYxClCYYoySJQeAHvhf4HoQhDIF7vbjXi++5twiCwPc9F4YgSPk1zeMkcVqMoiiyurZGZ5ScVt9zX9gp7zl7noviyNOfLtM3D0AHNytOY4zSM/tUCIIQBDcY3mAIAYDhfz0M/jUC7g2GjjJK5XLb1nHopnEY+m7ou8Yaa7QxWrc1E5ngLJcil0IKruvKaC2lzCh1elVIye/H/tS2zNOxb+PQF7k83vbff379+Pn965fPBCMpOMto29hx6AWjGSWO6WbBs3Vd5nkap9E8jy9LJRiTiu8ft6HrBGeUYEowwagqi7oqCUZpEjt9awRnx76ty7wsc1Wos0EKzgVrGiMYwyh9wXVVGl0TjFCaONboXIoPb/f78UiYxmEc+saaxtpcCdM+tgSjf3Cq68oa8w431mSUdF3T1r01+nyVyqWSUkimupyJjGL8ai6UKovihP8Ca95zUx7VVUMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/57b210669e3c737faafd90bf49ca20cd/8ac56/azure-pipelines-single-yaml.webp 240w,
/static/57b210669e3c737faafd90bf49ca20cd/d3be9/azure-pipelines-single-yaml.webp 480w,
/static/57b210669e3c737faafd90bf49ca20cd/e46b2/azure-pipelines-single-yaml.webp 960w,
/static/57b210669e3c737faafd90bf49ca20cd/a110d/azure-pipelines-single-yaml.webp 1181w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/57b210669e3c737faafd90bf49ca20cd/8ff5a/azure-pipelines-single-yaml.png 240w,
/static/57b210669e3c737faafd90bf49ca20cd/e85cb/azure-pipelines-single-yaml.png 480w,
/static/57b210669e3c737faafd90bf49ca20cd/d9199/azure-pipelines-single-yaml.png 960w,
/static/57b210669e3c737faafd90bf49ca20cd/712f7/azure-pipelines-single-yaml.png 1181w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/57b210669e3c737faafd90bf49ca20cd/d9199/azure-pipelines-single-yaml.png&quot;
            alt=&quot;YAML Pipelines&quot;
            title=&quot;YAML Pipelines&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We can also specify dependencies between stages, specifying that each deployment
stage depends on the build stage, as we can see in the image below.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/951c1202d32f41f84739b855cc1184fa/b6529/azure-pipelines-yaml-stage-dependencies.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 63.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABJUlEQVQoz42SCW7CMBBFcxNAkJB4ncXxQoBKBdL736h1LNGASqj0FNmZefLXaCqtlTW6a/dgjRSdUlJ0rRCtlqLZbbt237X7zXq1Wa9yVXR1vW3qXS41TaWVNIBGK6OVVhLBaiXr3XZO7q53D+fpWkkph+MpBm+tBmtg+iLY/1AprZkZEQiBCWk6INj59RWVFG06htt4YULH5B0P58Pl+plNgt7xkqyESDGMt2vvmAmD73vH0XvHRPhWluKeM0dF7AMPQ2Ki97GLfIcR0yGM4zX4nhB875Zk/SQTRu8/TqcUA4It4V8PTHaPL0McfEwewTLhcvIcuzQVEOwwpK/xdkixzG9efaKalk4YlZe0gGDL5I3+/fknWT6fj45p3lq2ddn8kb8BN5eSQ0E2M7cAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/951c1202d32f41f84739b855cc1184fa/8ac56/azure-pipelines-yaml-stage-dependencies.webp 240w,
/static/951c1202d32f41f84739b855cc1184fa/d3be9/azure-pipelines-yaml-stage-dependencies.webp 480w,
/static/951c1202d32f41f84739b855cc1184fa/e46b2/azure-pipelines-yaml-stage-dependencies.webp 960w,
/static/951c1202d32f41f84739b855cc1184fa/983e9/azure-pipelines-yaml-stage-dependencies.webp 1049w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/951c1202d32f41f84739b855cc1184fa/8ff5a/azure-pipelines-yaml-stage-dependencies.png 240w,
/static/951c1202d32f41f84739b855cc1184fa/e85cb/azure-pipelines-yaml-stage-dependencies.png 480w,
/static/951c1202d32f41f84739b855cc1184fa/d9199/azure-pipelines-yaml-stage-dependencies.png 960w,
/static/951c1202d32f41f84739b855cc1184fa/b6529/azure-pipelines-yaml-stage-dependencies.png 1049w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/951c1202d32f41f84739b855cc1184fa/d9199/azure-pipelines-yaml-stage-dependencies.png&quot;
            alt=&quot;YAML Pipeline Stage Dependencies&quot;
            title=&quot;YAML Pipeline Stage Dependencies&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;️-convert-task-groups-into-templates&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%EF%B8%8F-convert-task-groups-into-templates&quot; aria-label=&quot;️ convert task groups into templates permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;🏗️ Convert Task Groups into Templates&lt;/h2&gt;
&lt;p&gt;Using the Classic approach, &lt;strong&gt;the team has built several &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/devops/pipelines/library/task-groups?view=azure-devops&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Task
Groups&lt;/a&gt;&lt;/strong&gt;
over the years, which encapsulate sequences of tasks to run in a classic build or
release pipeline.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/0e0620b0e56fb1c7a0fb540cadba4b0e/c6ff8/azure-pipelines-task-groups.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 66.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABxUlEQVQoz11SSY4bMQzsf9huqRft1E6p2zZmLnNJMJlLkP+/JZAUOEEAHgSSpSqyOD3BA2jJOWdMKcnZLgRn+yY4o2T+N5RslW1dpOCyv6fP6AFASbEudFvXfduk4JTMZL4NzL6tlMzbShdK5tuVzDcphLOglJjw40sJbpQSnCkp2L5RMq8LHbFQ4p2VrUHaJpAJzpq63jzlH1/BwvP5qAXPo+YUB8OIhRLMKXjnnX3cz/OoRy3386i1FMzTr3fUxhwVU/QxhJxiTrGNJ7gSfDADGDC6FgzBxxhSDDH4NvPbx09nzXkeBXPBnFMqmL2znO1ayYWSFINz1jnbCAvWgjnFWjDFMH07vxtQPZ+x452Fvu/1dr0MsAXjLBxdasFcCxqtbtfL9Hm8gzUdm3oNay05R7ZvZL69wLaDsSNrV2i0mnKnKj0FYObrZfg0rHrJBqOHNO+s0Uq35ZupYgbQ2PfkexNn+8vkhZLgHRj9B9w3b8GMnqlgDt497me36kixWfW6qoWS8amz8LifBfPZBxzVBgZjcooxNKssmBftX2YwRqvhYoohBL+tS2OuJTdJ3QBMCXNa+5X8J1srOQhC8EP8vq2/AXujhAE9RTleAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/0e0620b0e56fb1c7a0fb540cadba4b0e/8ac56/azure-pipelines-task-groups.webp 240w,
/static/0e0620b0e56fb1c7a0fb540cadba4b0e/d3be9/azure-pipelines-task-groups.webp 480w,
/static/0e0620b0e56fb1c7a0fb540cadba4b0e/e46b2/azure-pipelines-task-groups.webp 960w,
/static/0e0620b0e56fb1c7a0fb540cadba4b0e/a9e21/azure-pipelines-task-groups.webp 1088w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/0e0620b0e56fb1c7a0fb540cadba4b0e/8ff5a/azure-pipelines-task-groups.png 240w,
/static/0e0620b0e56fb1c7a0fb540cadba4b0e/e85cb/azure-pipelines-task-groups.png 480w,
/static/0e0620b0e56fb1c7a0fb540cadba4b0e/d9199/azure-pipelines-task-groups.png 960w,
/static/0e0620b0e56fb1c7a0fb540cadba4b0e/c6ff8/azure-pipelines-task-groups.png 1088w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/0e0620b0e56fb1c7a0fb540cadba4b0e/d9199/azure-pipelines-task-groups.png&quot;
            alt=&quot;Azure Pipeline Task Groups&quot;
            title=&quot;Azure Pipeline Task Groups&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Using the &lt;strong&gt;YAML approach these task groups were converted into &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;YAML
templates&lt;/a&gt;&lt;/strong&gt;.
We have decided also to use an isolated git repository to host all these
templates to allow to reuse them in different projects and/or repos.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 871px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/ddbd262efecfc6245a88b64249d75b1d/9d5da/azure-pipelines-yaml-templates-repo.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 74.58333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACC0lEQVQoz42TSW7cMBBFdREPLQ6iSFEcRQ2UKFFyx0gWzsZJkCD3P0fCpt1oGAgQ4K8IvKr/q1gFFbamtGEUghJjJFqOIKhJVWGIEKTlY8sobxip8MP93ePD/cP9HYJAScFoXXxjbGJ06p1z3eBcwyiCgFSYVNhZKxrGaC1abpQSLRdty2gNyxNGECNYnP3QUmKV6jrrXEcqBEEJQckYXcOMYIlgiRGsMMoVK4wQBFnF/PkHa7iR0nVWtByCEkEAQVnXpB9HIdqWN6A85YpZoDzll0K9/qScp87WdNYYLXPtlF+b7JPRumH0KtFyrUTDaPH9JbYNNVoPveudnf3IGwZBWWEU/LR4Pw6966zRKksrOftpj5vRqvj1/EUwZrRxzva964yuMIIQVBgt3u9x2+OWUCm0klpJJcXspzXMWsliPF4pTcNM1bXEl8DZdoa3dZ3GoTP6BvbbGhL8dXnhlGmlEqsUrUmeJEYw+Pnp2J/2+PzpvMxzbq6kCMu8x5jg3/PzxbZOe+6dVvKt8wU+9rjv2/nY/TRe4WVOji62p4HWpDNmGocEa5U7XzPHbZ2G/kPmmG37aaSEYAgxhvnf3MIxZQ72PfA7PK5heYNrUmWrt8rwGsK2hjWEvKQM++k/4C2E83Ece4zbao2+7vkysM3of8MYAiVEuhdrO2v55UIYrWlNtBKdNX+v6g9w86g4jylmFwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/ddbd262efecfc6245a88b64249d75b1d/8ac56/azure-pipelines-yaml-templates-repo.webp 240w,
/static/ddbd262efecfc6245a88b64249d75b1d/d3be9/azure-pipelines-yaml-templates-repo.webp 480w,
/static/ddbd262efecfc6245a88b64249d75b1d/81b74/azure-pipelines-yaml-templates-repo.webp 871w&quot;
              sizes=&quot;(max-width: 871px) 100vw, 871px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/ddbd262efecfc6245a88b64249d75b1d/8ff5a/azure-pipelines-yaml-templates-repo.png 240w,
/static/ddbd262efecfc6245a88b64249d75b1d/e85cb/azure-pipelines-yaml-templates-repo.png 480w,
/static/ddbd262efecfc6245a88b64249d75b1d/9d5da/azure-pipelines-yaml-templates-repo.png 871w&quot;
            sizes=&quot;(max-width: 871px) 100vw, 871px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/ddbd262efecfc6245a88b64249d75b1d/9d5da/azure-pipelines-yaml-templates-repo.png&quot;
            alt=&quot;Pipeline YAML Templates Repo&quot;
            title=&quot;Pipeline YAML Templates Repo&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;motivation to use YAML templates is the same of Task Groups: encapsulate common logic&lt;/strong&gt; in templates to be able to use it in several pipeline definitions (we want pipeline definitions to be very thin, delegating the heavy work to templates).&lt;/p&gt;
&lt;h2 id=&quot;-use-environments-in-yaml&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#-use-environments-in-yaml&quot; aria-label=&quot; use environments in yaml permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;💻 Use Environments in YAML&lt;/h2&gt;
&lt;p&gt;In the classic approach the team was mostly relying on
&lt;a href=&quot;https://www.iis.net/downloads/microsoft/web-deploy&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;msdeploy&lt;/a&gt; to deploy
packages to VMs. &lt;strong&gt;With YAML Pipelines we can use the concept of
&lt;a href=&quot;https://docs.microsoft.com/en-us/azure/devops/pipelines/process/environments?view=azure-devops&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Environment&lt;/a&gt;&lt;/strong&gt;,
which is a collection of resources that we can target easily with
&lt;strong&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/azure/devops/pipelines/process/deployment-jobs?view=azure-devops&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Deployments&lt;/a&gt;&lt;/strong&gt;
from a Pipeline.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 767px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/4bf288ea141511aad1b59a9108259a6d/6c2f2/azure-pipeline-environments.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 82.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAIAAABSJhvpAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACJklEQVQ4y3WSyY7UQAyG8xgINMyks1dS+5JKLa5KengCTogDj8ORV0bpNOkRMJIPlu2v/Nuuou6G56dPaBgIwX3bdG1D8FRXFzT0eHdKNPRKCDyNbVN3Xds3VVs991XZV2Whhn5AA2dUCj6NqKmrYejbpu67Ft2cPdJ3fdfWddVUZY1oI6ERoeGh0BNanNtyer1uxuhL+VJdyrq6XMqX8uW5ri6Hvwfrunr68NF//fzjV/n959O3nwUTom1qSvCIhqHvphEdRvDEKBkROiPTiARnjNF+QLtahAqinKD4y5fXGLySQgouBReMLc7mFbSSWkmjlVZSSbHmlCEqyQ8rRqMEIXY2lGDB2d0YVVbCFrecY/Dbmq/butjZu4Uzyhk9ygrLRkKpnc2D5Iwzqq2ENWSI3i0QY4I4G33zg1by4ItFCIwno9X53h2eZUweQvgDw2y0W+wx3R1mYpGCJgBGyV+y0xUyxBAcQDyyCWJOcHYqBFGMYmvMX52NVhBDTmDne0oKHoOHGB+yHZWEkvlf2ChIMcMOKymObd/goKQU/AZLQhmjs9FvYUHPbacY/HVbX6+bnU3wDmI4y4ppGgVnp7Y321Zpg9upXE6w5nSDfYK4f4QDJtPE2X9hCWtcUwr+Lbx3fsB4Gt+Bj85r8D4n2NY8G3089FgYfl82bHGf2C057Tezs/FuCd49ZiZ4ogQbrY5j3I1zpcXirFvsyRitFjsvdj7LfgNhncvUlcRFpQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/4bf288ea141511aad1b59a9108259a6d/8ac56/azure-pipeline-environments.webp 240w,
/static/4bf288ea141511aad1b59a9108259a6d/d3be9/azure-pipeline-environments.webp 480w,
/static/4bf288ea141511aad1b59a9108259a6d/e0ad8/azure-pipeline-environments.webp 767w&quot;
              sizes=&quot;(max-width: 767px) 100vw, 767px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/4bf288ea141511aad1b59a9108259a6d/8ff5a/azure-pipeline-environments.png 240w,
/static/4bf288ea141511aad1b59a9108259a6d/e85cb/azure-pipeline-environments.png 480w,
/static/4bf288ea141511aad1b59a9108259a6d/6c2f2/azure-pipeline-environments.png 767w&quot;
            sizes=&quot;(max-width: 767px) 100vw, 767px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/4bf288ea141511aad1b59a9108259a6d/6c2f2/azure-pipeline-environments.png&quot;
            alt=&quot;Environments&quot;
            title=&quot;Environments&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We just need to &lt;strong&gt;add resources to environments&lt;/strong&gt; (VMs in this scenario) and specify which checks should be performed.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 853px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/eac605d8aeed0afd4e6ff3ddd8d487b1/66caf/azure-pipeline-env-checks.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 30.41666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA+ElEQVQY03XQOW7DMBAFUJ0jhQ2R1C5xG3Eo0lpI23JSGEiV1DlKihw8EASoCQK8Yj4wU8xPqrJAAxmjlKQZo/9jOTmfajh9fr98/Ojn120ZEwCNaAXvQKsizyhJGSWMkmM4olZimhfwQbmAbhy9T9pOSA1d2wjeNXW1a+ua87apq7oqDxbN22O9DAZBgpZ5niVKqRCjNWawaNGAVlpJNP31Fp1FNGDRWDQ9aO+G18c9hiXG4JytyiIBO6zP9zjP63q/xiAlV0IAaj/7abxM0yUsc1gWi33fwzSNUvCubaTg2/FWBk3ZhmSU5BnbMPa3sP3zPW7LjP4CVmZCX0IqkfsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/eac605d8aeed0afd4e6ff3ddd8d487b1/8ac56/azure-pipeline-env-checks.webp 240w,
/static/eac605d8aeed0afd4e6ff3ddd8d487b1/d3be9/azure-pipeline-env-checks.webp 480w,
/static/eac605d8aeed0afd4e6ff3ddd8d487b1/d8b1f/azure-pipeline-env-checks.webp 853w&quot;
              sizes=&quot;(max-width: 853px) 100vw, 853px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/eac605d8aeed0afd4e6ff3ddd8d487b1/8ff5a/azure-pipeline-env-checks.png 240w,
/static/eac605d8aeed0afd4e6ff3ddd8d487b1/e85cb/azure-pipeline-env-checks.png 480w,
/static/eac605d8aeed0afd4e6ff3ddd8d487b1/66caf/azure-pipeline-env-checks.png 853w&quot;
            sizes=&quot;(max-width: 853px) 100vw, 853px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/eac605d8aeed0afd4e6ff3ddd8d487b1/66caf/azure-pipeline-env-checks.png&quot;
            alt=&quot;Environment Checks&quot;
            title=&quot;Environment Checks&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Adding a VM resource to an environment means that &lt;strong&gt;this VM needs to have the
Azure Pipeline Agent running&lt;/strong&gt; on that VM, which means that is much easier to
perform some tasks on the target server (in the classic approach these tasks
were being performed via msdeploy which is not easy to configure to make
it work correctly when interacting remotely from the the build server).&lt;/p&gt;
&lt;h2 id=&quot;-use-approvals-instead-of-manual-trigger-deployments&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#-use-approvals-instead-of-manual-trigger-deployments&quot; aria-label=&quot; use approvals instead of manual trigger deployments permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;💂 Use Approvals instead of Manual Trigger Deployments&lt;/h2&gt;
&lt;p&gt;As mentioned earlier, in the classic approach, the team was using &lt;strong&gt;Manual
Trigger Deployments&lt;/strong&gt;. As I am writing this post, YAML Pipelines don’t support
Manual Trigger Deployments, despite the fact that is a &lt;a href=&quot;https://developercommunity.visualstudio.com/t/manually-triggered-stages-in-yaml-multi-stage-pipe/697467&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;feature requested by
many&lt;/a&gt;
for a long time.&lt;/p&gt;
&lt;p&gt;The best workaround to simulate a manual trigger deployment is to use
&lt;strong&gt;Environment Approval checks with a timeout&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 904px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/51e11bcf8fd670783145fb7b1adbd925/d9217/azure-pipelines-env-approvals-timeout.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 55.00000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABrUlEQVQoz3WR23LTMBCG/Swkoe3EtuSTbMs5+ECJE/oESXoRW7JjWc7BdpteUDoMAwzw0ozREKBDd76Lvfn3/3dX4uUu2WwoSfM8I8kmSTZZRlmxzbNsMY9v3s3n8Wzk4ZGHPexi1xGMPByGvvS12NKMHo+H0+m+beq2beqmzii5Xa8n4/HNIvanE6AqAghUCIEGgaFrEADp/u6OkJTzcrerGGNlyRgrKElvV0uEHbyYXb+JojAIAj8MA8dGijy8ury4uryAQJWOTz8oTRNRaZL+glKyXi1d1/H9aRSFURSKEZbZWZ6R9p8/Ftu8rg+8KjkvecVFioqX4/HIsZGNLBtZjo2QZSryUJGHqiKrityJv5/2eZ61Tb3f7xgrROyq4owVHsb93qtBv/d60B/0e6I508V+/PCF0pSQf/gTezrBrmOZBrJMZJmWaQhELz2cPhGS/FeMsRvHs3j21jR0CNS/t9U1aBq69K15Sl9wxtgN/Kk4kmUa3Z9+o0HQ7fy+bgklz8UkXa+Wjo0MDSryUIPQdWwI1PPDNQg650N9oC+IbRtpQDUMXdegsHrGTx54wtGDEf4eAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/51e11bcf8fd670783145fb7b1adbd925/8ac56/azure-pipelines-env-approvals-timeout.webp 240w,
/static/51e11bcf8fd670783145fb7b1adbd925/d3be9/azure-pipelines-env-approvals-timeout.webp 480w,
/static/51e11bcf8fd670783145fb7b1adbd925/82aba/azure-pipelines-env-approvals-timeout.webp 904w&quot;
              sizes=&quot;(max-width: 904px) 100vw, 904px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/51e11bcf8fd670783145fb7b1adbd925/8ff5a/azure-pipelines-env-approvals-timeout.png 240w,
/static/51e11bcf8fd670783145fb7b1adbd925/e85cb/azure-pipelines-env-approvals-timeout.png 480w,
/static/51e11bcf8fd670783145fb7b1adbd925/d9217/azure-pipelines-env-approvals-timeout.png 904w&quot;
            sizes=&quot;(max-width: 904px) 100vw, 904px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/51e11bcf8fd670783145fb7b1adbd925/d9217/azure-pipelines-env-approvals-timeout.png&quot;
            alt=&quot;Approvals Timeout&quot;
            title=&quot;Approvals Timeout&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;However, be aware that the &lt;strong&gt;stage will be in a Waiting state while the approval is pending&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 699px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/ff9a2a403220fa6902a0bef7d7b25ba9/3fe45/azure-pipelines-waiting-approval.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 132.08333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAaCAIAAAA44esqAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACzUlEQVQ4y5VU227jNhTUjzSOZFu2xNs5hxRF3WxZju14vUgR57LYDYINWrR96EvRov2BPval/eNCVuosbBVogYFAkRxyZnhIj5IqZkywmLNoNAziaKqU5CwOfF9wNgnHYTgGJYXgUohp+xsKzgRn4Xjk/TCZ6DjCJEldJqWw1uBhqkutTUxi9Hg0vBxcDAN/GPijYTAaBl17PBp6qyJTPPZHUSQIQSFA+0XQhAgKpJBSIMAw8P3LwSv814bX7PZKqcHFV0EQTMLxAWGHcDzqZE/C0L8cXA4uTuC52++5IsljmySEAErJ1l7r8AtwUPIcHr18jEESwHq7q6rSpZYOmk9ACEdoeoX3eZ2RZIyxg0H+JbOdCgBSIqjehbzvNo1RIo6ifJHVzdzoNjZCQFSkVJKZ+dXMGgOHzhN4i7ufgCyLJuW83O22y8Wi2zzPMmety9Or9XLZLGxiEJTR5FKL/yzkPX/6YI2Oo2lZFJv1qlnU3Vh3yIbQaMpcmhjdiTea3nZ+fHzUmngc63a0zfA4ZjRpTW2nFOeaW/Ldfq8JWRydRIoICSpdNtV2v9tuzSGMM/LdLSFwFp+QD1HLYtZ8/vXP7f5Z8ogQ/w8ZMXe2WdTz+XzZ1Efbb+SH+3uNwPrIbTyJNUZbgy61bQQn53zz/h2BOt8ZEQzKZLZa3n1bFJXqy8y7rj8pgZxFvZ7Lqn755Y/1zUeQ7HyC91LeaKF6ZRNhZk3pTJG7q2XT4/lptiEpe8mGgKwjY+oyS23SU9tJnnIWC96jyqBM683Dj7/fPjyB5D2eqyLv3qQ+z6osqw/f/Nxcf+3a1OmUXP47WRO6RDsDZe7q+duF+09kQwrTUudV2wDo8VyWRT+ZEBVPZ6vn3/5avb/n8bSnPN9tr9tnmbNjAR2BoPIsu7l/utrsZmXRIzvPXDSdTCehFLyTcARnrZzUoLOmLHJzViR/A/uSNW1CjNy5AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/ff9a2a403220fa6902a0bef7d7b25ba9/8ac56/azure-pipelines-waiting-approval.webp 240w,
/static/ff9a2a403220fa6902a0bef7d7b25ba9/d3be9/azure-pipelines-waiting-approval.webp 480w,
/static/ff9a2a403220fa6902a0bef7d7b25ba9/32d5d/azure-pipelines-waiting-approval.webp 699w&quot;
              sizes=&quot;(max-width: 699px) 100vw, 699px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/ff9a2a403220fa6902a0bef7d7b25ba9/8ff5a/azure-pipelines-waiting-approval.png 240w,
/static/ff9a2a403220fa6902a0bef7d7b25ba9/e85cb/azure-pipelines-waiting-approval.png 480w,
/static/ff9a2a403220fa6902a0bef7d7b25ba9/3fe45/azure-pipelines-waiting-approval.png 699w&quot;
            sizes=&quot;(max-width: 699px) 100vw, 699px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/ff9a2a403220fa6902a0bef7d7b25ba9/3fe45/azure-pipelines-waiting-approval.png&quot;
            alt=&quot;Waiting Approvals&quot;
            title=&quot;Waiting Approvals&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The only drawback with this workaround is that &lt;strong&gt;the whole pipeline is shown as Queued while not all stages complete&lt;/strong&gt; (and also that that the time elapsed is still counting), which might not reflect exactly what the team wants.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/4e29a5dada4022ecd9e8190ff91bd7cd/2c95d/azure-pipelines-queue-state.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 31.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA30lEQVQY023PvU7DMBQFYL8KSVDa2Nc/107spEkcksZpaanYQGJkYYO1E+LNkUACq6r0Lfecs1xyXOcPp+ev8/kpzKfB+2Hwfef7rms322nUqNLk5jZLryIb273sls+P98e2cRyE4IJDvMjSJEuTi/MXwbAvVjkHqAzWzpbGoJLAKAcWA1oALRgt4pAsDSJimKfxzvuubWpnqxKV1Kj+abS2crVztopz4vud1upwv1/CXBotOCgpUMk/UoqA+DqNb9tpsJWMKhJCWK9y+fOq4ACMXmCMGkprzhsAQQsWVd+er0cYrqItkQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/4e29a5dada4022ecd9e8190ff91bd7cd/8ac56/azure-pipelines-queue-state.webp 240w,
/static/4e29a5dada4022ecd9e8190ff91bd7cd/d3be9/azure-pipelines-queue-state.webp 480w,
/static/4e29a5dada4022ecd9e8190ff91bd7cd/e46b2/azure-pipelines-queue-state.webp 960w,
/static/4e29a5dada4022ecd9e8190ff91bd7cd/ac796/azure-pipelines-queue-state.webp 1099w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/4e29a5dada4022ecd9e8190ff91bd7cd/8ff5a/azure-pipelines-queue-state.png 240w,
/static/4e29a5dada4022ecd9e8190ff91bd7cd/e85cb/azure-pipelines-queue-state.png 480w,
/static/4e29a5dada4022ecd9e8190ff91bd7cd/d9199/azure-pipelines-queue-state.png 960w,
/static/4e29a5dada4022ecd9e8190ff91bd7cd/2c95d/azure-pipelines-queue-state.png 1099w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/4e29a5dada4022ecd9e8190ff91bd7cd/d9199/azure-pipelines-queue-state.png&quot;
            alt=&quot;Pipeline Queued&quot;
            title=&quot;Pipeline Queued&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If the approval times out, the stage is skipped, and the user has the option  to rerun the stage manually&lt;/strong&gt;. You can play with the timeout value to accommodate your team preference of showing the Pipeline as “Queued” or “Completed” (even if some stages were skipped).&lt;/p&gt;
&lt;h2 id=&quot;-stage-completed-notification&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#-stage-completed-notification&quot; aria-label=&quot; stage completed notification permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;📧 Stage Completed Notification&lt;/h2&gt;
&lt;p&gt;Finally, some team members are used &lt;strong&gt;to be notified when a classic deployment is completed&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/63fead105d8b8b40c56f78255a1a6fa7/b6e34/azure-pipelines-subscription-deploy-completed.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 44.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABOklEQVQoz42O2W6CUBRF+Yoq051AA9yR6YJimzi0/kQVEsEUTdv/f2usCbHRhyYr5+Hss7OO0fcf31+f/ak/nc9de+i69p8cj53Rde16vZrNyqqaLxZVWeii0OVfiju0zrfbN6NtD1LwMAgYpTQKXcd2Hdu2THM8MscjyxzbpulY1i2ubZujJ8GZsdu9x0pyziBwEQQIAil4WWgpeBIrJUUYTD2CfY8MTHwPIygFN/b7neBMCn5ZQQCBm8bqdbPerJab1XJeFnmaZGmcp8lAkWecRpwzo2lqpWSaxASjqzwKA51nhc51nmVpwmg0nfjDXwiC30NHCG40dZ3EcawkRhBBAFyHYIQxukwECUa+R67Ro3JTZ2ny8lxV81mepZxR3yODBwL31vnArKSUnNEoYDRkNPIIvi88LP8AW8xo7Uxp/lsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/63fead105d8b8b40c56f78255a1a6fa7/8ac56/azure-pipelines-subscription-deploy-completed.webp 240w,
/static/63fead105d8b8b40c56f78255a1a6fa7/d3be9/azure-pipelines-subscription-deploy-completed.webp 480w,
/static/63fead105d8b8b40c56f78255a1a6fa7/e46b2/azure-pipelines-subscription-deploy-completed.webp 960w,
/static/63fead105d8b8b40c56f78255a1a6fa7/33ecb/azure-pipelines-subscription-deploy-completed.webp 1103w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/63fead105d8b8b40c56f78255a1a6fa7/8ff5a/azure-pipelines-subscription-deploy-completed.png 240w,
/static/63fead105d8b8b40c56f78255a1a6fa7/e85cb/azure-pipelines-subscription-deploy-completed.png 480w,
/static/63fead105d8b8b40c56f78255a1a6fa7/d9199/azure-pipelines-subscription-deploy-completed.png 960w,
/static/63fead105d8b8b40c56f78255a1a6fa7/b6e34/azure-pipelines-subscription-deploy-completed.png 1103w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/63fead105d8b8b40c56f78255a1a6fa7/d9199/azure-pipelines-subscription-deploy-completed.png&quot;
            alt=&quot;Subscribe Deployment Completed&quot;
            title=&quot;Subscribe Deployment Completed&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;However, for YAML Pipelines, in the Notifications page, we have &lt;strong&gt;only available the notifications that a stage is waiting for an approval or &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/utility/manual-validation?view=azure-devops&amp;#x26;tabs=yaml&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;manual validation&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/3176e458a02fc595c6f8fadd7620c651/d69c4/azure-pipelines-subscriptions.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 35%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAzklEQVQY04XQa07DMBAE4JyDxLvrdxyndm03bqsK2kIrENz/PggiRahUIH1/Z7SzjR/cOoacYgyBEBEYAiOEf/XWNH5wfnBaSaMVAjNaWaOBdXMLJ7yLEKTgzehdbw2wjhMAa0tef7y/XS8vr9fL8+m439Vt3dzYbaec4lc4hvHxcFBSCE6c0PWm5LTwgxOcpOB3NXUq59PTVHLdlDoVrWTXPrCunS333yAEJXmTUyw5zfWcUApaXrLM+43T92bX27BaxTBaoxHYz/Af5vAnXgk9QmwBBvoAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/3176e458a02fc595c6f8fadd7620c651/8ac56/azure-pipelines-subscriptions.webp 240w,
/static/3176e458a02fc595c6f8fadd7620c651/d3be9/azure-pipelines-subscriptions.webp 480w,
/static/3176e458a02fc595c6f8fadd7620c651/e46b2/azure-pipelines-subscriptions.webp 960w,
/static/3176e458a02fc595c6f8fadd7620c651/0a92e/azure-pipelines-subscriptions.webp 1002w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/3176e458a02fc595c6f8fadd7620c651/8ff5a/azure-pipelines-subscriptions.png 240w,
/static/3176e458a02fc595c6f8fadd7620c651/e85cb/azure-pipelines-subscriptions.png 480w,
/static/3176e458a02fc595c6f8fadd7620c651/d9199/azure-pipelines-subscriptions.png 960w,
/static/3176e458a02fc595c6f8fadd7620c651/d69c4/azure-pipelines-subscriptions.png 1002w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/3176e458a02fc595c6f8fadd7620c651/d9199/azure-pipelines-subscriptions.png&quot;
            alt=&quot;YAML Pipeline Notifications&quot;
            title=&quot;YAML Pipeline Notifications&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I hope the events of stage state change will be available in the future. Nevertheless it’s possible to have this notification via &lt;a href=&quot;https://docs.microsoft.com/en-us/azure/devops/service-hooks/overview?view=azure-devops&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Service Hooks&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 649px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/3985e8cf4cf9c2d568625d822abdf941/7762d/azure-pipelines-stage-completed.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 96.25000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAIAAAAf7rriAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACT0lEQVQ4y22SZ27bQBSEeQ6LW0mK3MYuib1Jomy4KLJhJ/mb+x8iWNJB1IABAS7eh7czs8bry/N+O4z77W7bHw77x6fDOI7r1SqJozSJkzi6qzSJf359Gk3T2q7whG87LoIAIYgRBObCXDwAcwHMBZ5OLgQBguB4fDP6vovWZTmewjRjnsuZ57pLzpjgjDOPc0YIuuUhND8+TkbbNsx1OHMl83ylfF8JzoMgiMIg8FUY+JTo4Vv4dDoaXdtKwZWUSkklma+kbVFgLiAwZxGMCEa38PvpaPRdu0rjIs/Xq1WRZ5tViqCJoTamhQACpkWwRQnSv/9gYL7/eDW616/y8W3XNW2jNfT90Pd1U3Vd2/ddXZdt06RJfL0ZmO+//xhl3UopdtvtMPRJHCnBtVcplJKBr5QSkylBL2PT8OcvoyyLKAy5t0RTAcA0teHJ81yV7m3xcH7nyTN4ehw13LVNWdcYY4TgdzxYT8w5EYwF83TmZzCCYBz3Rp5nebYZ9vu6riT3MAQUowsRHOkOlxCAazjLNlVVb4rSojrSaxIji5IoUI51kfb/zX3XMcYgWNySs1zbphjfgbPNuqiqvKro5PZWlOA49IVw7m3ONkkctcOwtO159EoWJYGSjNl34KLI82wThNHdqLRnQhTnFrl+Yd+embu0KdZv8Ex06okSPH8tSgjBWroy3eLhMBpFUdgWZcxjnnuuwFfrNFFSpHEsBXMd2106nutIwderhDNPw33Xcs44Z5o/k69UHIVSiigMpODzIWdMCh5Hoa/ky8vzX1g2uRzJZ/Z3AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/3985e8cf4cf9c2d568625d822abdf941/8ac56/azure-pipelines-stage-completed.webp 240w,
/static/3985e8cf4cf9c2d568625d822abdf941/d3be9/azure-pipelines-stage-completed.webp 480w,
/static/3985e8cf4cf9c2d568625d822abdf941/df8c5/azure-pipelines-stage-completed.webp 649w&quot;
              sizes=&quot;(max-width: 649px) 100vw, 649px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/3985e8cf4cf9c2d568625d822abdf941/8ff5a/azure-pipelines-stage-completed.png 240w,
/static/3985e8cf4cf9c2d568625d822abdf941/e85cb/azure-pipelines-stage-completed.png 480w,
/static/3985e8cf4cf9c2d568625d822abdf941/7762d/azure-pipelines-stage-completed.png 649w&quot;
            sizes=&quot;(max-width: 649px) 100vw, 649px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/3985e8cf4cf9c2d568625d822abdf941/7762d/azure-pipelines-stage-completed.png&quot;
            alt=&quot;Stage Completed Service Hook&quot;
            title=&quot;Stage Completed Service Hook&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;For now, and since the team was using &lt;a href=&quot;https://slack.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Slack&lt;/a&gt;, we have configured &lt;a href=&quot;https://slack.com/apps/AFH4Y66N9-azure-pipelines&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Azure Pipelines Slack App&lt;/a&gt; to &lt;strong&gt;post a slack message when any stage is completed&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 592px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/bbcb71822f2300013394f1a6c0147a2d/1b853/azure-pipelines-slack-subscription.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 86.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAIAAABSJhvpAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABg0lEQVQ4y42TWW6kMBBAc4oEDN73FbANDZ3MzHXmGDl6xBC1Wq20BunJH6V6qkXll/YNtm8QAAwggUTU5VrmbarrfLku20ddrvP6ftl+1eWa6yWkomzsEAVw5+VOpgASZUOe17JsdV7TNGsbuXJUGK6c0F7qwKQ9zEe5Q0xob/zApCVcY6Z6xACkTYfv+VkGkPqUt48/QjnKDSSix7zHvEPsnqeVmbRxrGNecl2ZtIgpiPkt+4HHynGoLoyvLbxv76wstR/Lgqg8eiZcQ8zbk7IfsrKh6fA+LWLHwKcqH9sOKRufDqfHHPTknAyptrHMW5lX4wehfRqrDcNZ2YYxTVXqoE0QysWhuDCeXRhXLqTcMwmMAVQgIgCk7ZPOHytz7csw92vln39ff1+6BoH/L6zFkOzHBInYr5IIKPT+/os841tuGySNH6Y5DiVNNY01phzHGobCpH3Gt9w0UNngUz5+z450UntpAlfuQGj/s9w2iEurbNyjynFpuXJHxk2+RW7yF7fPh8z2OJrHAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/bbcb71822f2300013394f1a6c0147a2d/8ac56/azure-pipelines-slack-subscription.webp 240w,
/static/bbcb71822f2300013394f1a6c0147a2d/d3be9/azure-pipelines-slack-subscription.webp 480w,
/static/bbcb71822f2300013394f1a6c0147a2d/0be55/azure-pipelines-slack-subscription.webp 592w&quot;
              sizes=&quot;(max-width: 592px) 100vw, 592px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/bbcb71822f2300013394f1a6c0147a2d/8ff5a/azure-pipelines-slack-subscription.png 240w,
/static/bbcb71822f2300013394f1a6c0147a2d/e85cb/azure-pipelines-slack-subscription.png 480w,
/static/bbcb71822f2300013394f1a6c0147a2d/1b853/azure-pipelines-slack-subscription.png 592w&quot;
            sizes=&quot;(max-width: 592px) 100vw, 592px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/bbcb71822f2300013394f1a6c0147a2d/1b853/azure-pipelines-slack-subscription.png&quot;
            alt=&quot;Slack Subscription&quot;
            title=&quot;Slack Subscription&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;That’s all for now.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[C# Static fields inline initialization - Be Lazy]]></title><description><![CDATA[This post explores static field inline initialization in C# and how can we have full control of the exact moment when they get initialized.]]></description><link>https://bfcamara.com/posts/static-field-inline-initialization/</link><guid isPermaLink="false">https://bfcamara.com/posts/static-field-inline-initialization/</guid><pubDate>Sun, 04 Apr 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/2ff3010bf673126b4869d595d17ba394/a3767/lazy.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 73.33333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAB2HAAAdhwGP5fFlAAABZElEQVQoz2NgoCZgZAQTIACjGRkgiARDUNmEtTIyszPzyDAwMjNxCDNzSXPyivCKyLALyDKwS7PzyDKxceFzLa+ofHGmGQOTbGyodnW+iaSe38wm7b4aw+QE2/wMGy4hObhKLJqFJBUnVqsz8pvMalDZO0NGRt+rs0xbQd9xVbdcYbI6AwMfMyNum7mElWY26+ammbeU6JVnG85p0V7SpS6t55WRZGNhocnAwMCEz+usvHKq2hq6uhyCysw8CjJq+pq6OtJK6nxS2tyCEoQCjIVLWVFUSVFMREyET0hEVVlUXUWYX1hCWFyCm5ePgGZWDh5LfT4pKWFrA15rQ15dDUErA15mHil9TQEpCT5wtOPWzMzKLiPOycDAKSnKqSTDwcAqKCXBKSDIoyjNLiXGycDAgj91MXGwszAwMLGxMrOzszCzsHJzMXNzMbOysrKzszIyMTPQHBCVHgkCVlZWJiYmXNIA2jopBD2YWycAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/2ff3010bf673126b4869d595d17ba394/8ac56/lazy.webp 240w,
/static/2ff3010bf673126b4869d595d17ba394/d3be9/lazy.webp 480w,
/static/2ff3010bf673126b4869d595d17ba394/e46b2/lazy.webp 960w,
/static/2ff3010bf673126b4869d595d17ba394/efe91/lazy.webp 1210w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/2ff3010bf673126b4869d595d17ba394/8ff5a/lazy.png 240w,
/static/2ff3010bf673126b4869d595d17ba394/e85cb/lazy.png 480w,
/static/2ff3010bf673126b4869d595d17ba394/d9199/lazy.png 960w,
/static/2ff3010bf673126b4869d595d17ba394/a3767/lazy.png 1210w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/2ff3010bf673126b4869d595d17ba394/d9199/lazy.png&quot;
            alt=&quot;Be Lazy&quot;
            title=&quot;Be Lazy&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;-the-root-cause-of-the-failing-test&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#-the-root-cause-of-the-failing-test&quot; aria-label=&quot; the root cause of the failing test permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;✅ The root cause of the failing test&lt;/h2&gt;
&lt;p&gt;In my &lt;a href=&quot;/posts/chasing-failed-test/&quot;&gt;previous post&lt;/a&gt; I have described the
troubleshooting experience of a failed unit test in CI/CD pipeline which was
passing on my machine. Today I want to explore what was causing the failure when
the test was running in Release mode, and passing when running in Debug mode.&lt;/p&gt;
&lt;p&gt;Basically the root cause was a &lt;strong&gt;static field inline initialization&lt;/strong&gt; that
was being initialized before some condition to happen.&lt;/p&gt;
&lt;h2 id=&quot;️-explaining-the-issue-with-a-simple-scenario&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%EF%B8%8F-explaining-the-issue-with-a-simple-scenario&quot; aria-label=&quot;️ explaining the issue with a simple scenario permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;✂️ Explaining the issue with a simple scenario&lt;/h2&gt;
&lt;p&gt;Let’s imagine that we have the following implementation in a class with the
responsibility to resolve some URLs.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;csharp&quot;&gt;&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UrlResolver&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token type-list&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;IUrlResolver&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ICache&lt;/span&gt; cache&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;UrlResolver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ICache&lt;/span&gt; cache&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cache &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cache &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;ArgumentNullException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;nameof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cache&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ResolveUrl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; moduleName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; cacheKey &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token interpolation-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;$&quot;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token expression language-csharp&quot;&gt;moduleName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;_url_cache_key&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; moduleUrl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cache&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cacheKey&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;moduleUrl &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            moduleUrl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ResolveUrlInternal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;moduleName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            cache&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cacheKey&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; moduleUrl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; moduleUrl&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ResolveUrlInternal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; moduleName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token interpolation-string&quot;&gt;&lt;span class=&quot;token string&quot;&gt;$&quot;https://somedomain.com/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token expression language-csharp&quot;&gt;moduleName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the context of an ASP.NET Core application, this class is used inside
controllers and it is being injected in its constructors as an
&lt;code class=&quot;language-text&quot;&gt;IUrlResolver&lt;/code&gt;. We are registering these services in the Startup class, and
everything works as expected.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;csharp&quot;&gt;&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;services&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token generic-method&quot;&gt;&lt;span class=&quot;token function&quot;&gt;AddSingleton&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ICache&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; MyCacheImplementation&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
services&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token generic-method&quot;&gt;&lt;span class=&quot;token function&quot;&gt;AddSingleton&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;IUrlResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; UrlResolver&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The point here is that &lt;strong&gt;the &lt;code class=&quot;language-text&quot;&gt;UrlResolver&lt;/code&gt; has a dependency of a &lt;code class=&quot;language-text&quot;&gt;ICache&lt;/code&gt; and it
requires an implementation of it&lt;/strong&gt;. Otherwise we are not able to create an
instance of a &lt;code class=&quot;language-text&quot;&gt;UrlResolver&lt;/code&gt; due the following code in its constructor.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;csharp&quot;&gt;&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;UrlResolver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ICache&lt;/span&gt; cache&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cache &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cache &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;ArgumentNullException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;nameof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cache&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;-now-the-legacy-code&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#-now-the-legacy-code&quot; aria-label=&quot; now the legacy code permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;🦹 Now the legacy code&lt;/h2&gt;
&lt;p&gt;Now let’s imagine that we have some legacy code that has some &lt;strong&gt;static public
methods&lt;/strong&gt; that need need to consume an instance of a &lt;code class=&quot;language-text&quot;&gt;UrlResolver&lt;/code&gt;. Since these
methods are static, one option is to use a static field to keep the
&lt;code class=&quot;language-text&quot;&gt;UrlResolver&lt;/code&gt; instance. But to create an instance of it, we need to pass an
instance of an &lt;code class=&quot;language-text&quot;&gt;ICache&lt;/code&gt;. &lt;strong&gt;This legacy code is using a Service Locator pattern
to resolve instances of specific services, including the cache service&lt;/strong&gt;. So, we
could do something like this&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;csharp&quot;&gt;&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LegacyModuleUrlResolver&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IUrlResolver&lt;/span&gt; urlResolver
      &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;UrlResolver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ServiceLocator&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;GetCache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ResolveModuleUrl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; moduleName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; urlResolver&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ResolveUrl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;moduleName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This code is assuming that when we create the &lt;code class=&quot;language-text&quot;&gt;UrlResolver&lt;/code&gt; we have an instance of
&lt;code class=&quot;language-text&quot;&gt;ICache&lt;/code&gt; being returned by the Service Locator. Again. In the context of an
ASP.NET Core, everything works fine becasue the Service Locator is being initialized
and built during the Startup. &lt;strong&gt;So, what is the chance of passing a null reference of
ICache when creating the static field?&lt;/strong&gt;. Very unlikely.&lt;/p&gt;
&lt;h2 id=&quot;-and-now-the-failing-test&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#-and-now-the-failing-test&quot; aria-label=&quot; and now the failing test permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;👎 And now the failing test&lt;/h2&gt;
&lt;p&gt;Now, let’s imagine the following test.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;csharp&quot;&gt;&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Fact&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Some_test_that_should_pass&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Arrange&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; moduleName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;my_module_name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; services &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;ServiceCollection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token generic-method&quot;&gt;&lt;span class=&quot;token function&quot;&gt;AddSingleton&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ICache&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Substitute&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token generic-method&quot;&gt;&lt;span class=&quot;token function&quot;&gt;For&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ICache&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    ServiceLocator&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;services&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Act&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; url &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; LegacyModuleUrlResolver&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ResolveModuleUrl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;moduleName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Assert&lt;/span&gt;
    url&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Should&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Be&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://somedomain.com/my_module_name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;What do you think? Does it pass? Or does it fail?&lt;/strong&gt; Well, it really depends of the
target framework and configuration. For example, in .NET Core 3.1 the test passes in
both Debug and Release mode. In .NET 4.7.2, the test passes in Debug mode,
but it fails in Release (exactly the behavior I got in CI/CD pipeline issue).&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/d26939e08de64aa4018b3adfa0cf450d/9b36d/test-failing.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 47.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABmklEQVQoz32O2XKbQBBF+RAhZnr2TZaEkMBgYytiG0YYK7H//1NSyJWUKw+5daqf+tzu6O39Y5puIczjnRDmcJ2bdrg0Q3Pn0vRN67PT4ykv9+lpt8+s22mzsW4bffz6nN9u0/TuhzAMIYSpbYe2HfrO9/3Yd75rh95P1WuXFfWxfM2r8yGvD0Wd5s/R7efnPN+u19n7axincZy8v/bD2PV+mZ0/n9v65cK5wAglSYKSBAAoWRI1XXgsq+q5zosyOxb501NeFlVR/bj0RflyPObpIdsfMsYZuRsAgP8kSjfOWGeMlUJRJhDHUgMgEMZhLZWTnFPJidXcKI4QWn9LBIRSygihSiqpHEiqLF3HyRph+bBzh4ybjdBCWWU2llCCMPpbEbElnFKm5LKC73KyRgmA3LqH4367sy7dizQFqxlnXDBKSbxaxXH8HxkjSmK0zAUAtBQiAgkGDIxjIN9ltciKfb2NKZEbzbUgWmGpsNJUaWUWhDbcOML4P5cNlkRZhhKMCeGCSkEJYYhK4BozjahETGGmMIY4Xv0GMV5uTx+5uCEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/d26939e08de64aa4018b3adfa0cf450d/8ac56/test-failing.webp 240w,
/static/d26939e08de64aa4018b3adfa0cf450d/d3be9/test-failing.webp 480w,
/static/d26939e08de64aa4018b3adfa0cf450d/e46b2/test-failing.webp 960w,
/static/d26939e08de64aa4018b3adfa0cf450d/f992d/test-failing.webp 1440w,
/static/d26939e08de64aa4018b3adfa0cf450d/882b9/test-failing.webp 1920w,
/static/d26939e08de64aa4018b3adfa0cf450d/a62af/test-failing.webp 2087w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/d26939e08de64aa4018b3adfa0cf450d/8ff5a/test-failing.png 240w,
/static/d26939e08de64aa4018b3adfa0cf450d/e85cb/test-failing.png 480w,
/static/d26939e08de64aa4018b3adfa0cf450d/d9199/test-failing.png 960w,
/static/d26939e08de64aa4018b3adfa0cf450d/07a9c/test-failing.png 1440w,
/static/d26939e08de64aa4018b3adfa0cf450d/29114/test-failing.png 1920w,
/static/d26939e08de64aa4018b3adfa0cf450d/9b36d/test-failing.png 2087w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/d26939e08de64aa4018b3adfa0cf450d/d9199/test-failing.png&quot;
            alt=&quot;Test failing&quot;
            title=&quot;Test failing&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The main question here is: &lt;strong&gt;in what moment the static field inline
initialization runs?&lt;/strong&gt; We should only assume that it will run
before it’s needed. &lt;strong&gt;But we can’t control when the CLR will run
the static initialization&lt;/strong&gt;. And if the initialization fails due a null instance
of &lt;code class=&quot;language-text&quot;&gt;ICache&lt;/code&gt;, the type will get unused for the whole application with a
&lt;code class=&quot;language-text&quot;&gt;TypeInitializationException&lt;/code&gt; and doesn’t recover from this state, which is not good.&lt;/p&gt;
&lt;p&gt;If we use a &lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-constructors&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;static
constructor&lt;/a&gt;
the results are consistent and the test starts succeeding in all configurations.
But again, we can’t control when the CLR will call the static constructor. We just know that
it will run before it’s needed.&lt;/p&gt;
&lt;h2 id=&quot;-lets-have-full-control-and-be-lazy&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#-lets-have-full-control-and-be-lazy&quot; aria-label=&quot; lets have full control and be lazy permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;👍 Let’s have full control and be lazy&lt;/h2&gt;
&lt;p&gt;When having these scenarios of depending of some services during the
initialization, we may want to have full control when the initialization
happens, and &lt;strong&gt;we want to initialize just before we really need it (being really
really lazy). We can use a different approach with a
&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.lazy-1?view=net-5.0&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Lazy&amp;lt;T&gt;&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;csharp&quot;&gt;&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LegacyModuleUrlResolver&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Lazy&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;IUrlResolver&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; urlResolver &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;Lazy&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;IUrlResolver&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;UrlResolver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ServiceLocator&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;GetCache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            LazyThreadSafetyMode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;PublicationOnly&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ResolveModuleUrl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; moduleName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; urlResolver&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Value&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ResolveUrl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;moduleName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By using a &lt;code class=&quot;language-text&quot;&gt;Lazy&amp;lt;T&gt;&lt;/code&gt; we have full control when the initialization will happen.
In this case the initialization will occur the first time the static method
&lt;code class=&quot;language-text&quot;&gt;ResolveModuleUrl&lt;/code&gt; is called, when evaluating the &lt;code class=&quot;language-text&quot;&gt;Value&lt;/code&gt; property of the lazy
instance of &lt;code class=&quot;language-text&quot;&gt;urlResolver&lt;/code&gt;. I am also using the option
&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.threading.lazythreadsafetymode?view=net-5.0&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;LazyThreadSafetyMode.PublicationOnly&lt;/code&gt;&lt;/a&gt;
to not cache the exception if for some reason the initialization fails, to
prevent the &lt;code class=&quot;language-text&quot;&gt;TypeInitializationException&lt;/code&gt; described earlier.&lt;/p&gt;
&lt;p&gt;This was a simple explanation why the test was failing. In reality the test
was much more complex, involving several assemblies provided by several
nuget packages. One of the methods in the test was swallowing
exceptions, so it was being completely silence, and the test was failing due an
assert. This made the diagnostics even harder. &lt;strong&gt;Net-net, sometimes it’s good to
have full control when things happen and to be lazy in initialization until we
really need it&lt;/strong&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Chasing a failed test in CI/CD pipeline]]></title><description><![CDATA[This post describes the troubleshooting experience of having a test failing in CI/CD pipeline, which was not easy to reproduce locally in my machine.]]></description><link>https://bfcamara.com/posts/chasing-failed-test/</link><guid isPermaLink="false">https://bfcamara.com/posts/chasing-failed-test/</guid><pubDate>Sun, 14 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/8f47d32dc011e8785799691c8a2e3af5/0f98f/pipeline_man_walking.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAMEAv/EABUBAQEAAAAAAAAAAAAAAAAAAAEC/9oADAMBAAIQAxAAAAF2oSacQCf/xAAaEAEAAwADAAAAAAAAAAAAAAABAAIDERMi/9oACAEBAAEFAjWdxHYma6XfK625/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAGxAAAQQDAAAAAAAAAAAAAAAAAAECITIDEKH/2gAIAQEABj8CnGUKdGtVRZ1//8QAHBAAAwABBQAAAAAAAAAAAAAAAAERQSExUWGB/9oACAEBAAE/IcEPSicmcsoDrgUVsU9cjW4//9oADAMBAAIAAwAAABCI7//EABcRAAMBAAAAAAAAAAAAAAAAAAABESH/2gAIAQMBAT8QUaph/8QAFhEBAQEAAAAAAAAAAAAAAAAAAQAR/9oACAECAQE/EFRy1v/EABwQAQEAAgMBAQAAAAAAAAAAAAERACExccGB8P/aAAgBAQABPxBAiQVGPMB+1iAPfHGXaPzrINqxNQ9zWjoa53jT423P/9k=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/8f47d32dc011e8785799691c8a2e3af5/8ac56/pipeline_man_walking.webp 240w,
/static/8f47d32dc011e8785799691c8a2e3af5/d3be9/pipeline_man_walking.webp 480w,
/static/8f47d32dc011e8785799691c8a2e3af5/e46b2/pipeline_man_walking.webp 960w,
/static/8f47d32dc011e8785799691c8a2e3af5/f992d/pipeline_man_walking.webp 1440w,
/static/8f47d32dc011e8785799691c8a2e3af5/882b9/pipeline_man_walking.webp 1920w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/8f47d32dc011e8785799691c8a2e3af5/09b79/pipeline_man_walking.jpg 240w,
/static/8f47d32dc011e8785799691c8a2e3af5/7cc5e/pipeline_man_walking.jpg 480w,
/static/8f47d32dc011e8785799691c8a2e3af5/6a068/pipeline_man_walking.jpg 960w,
/static/8f47d32dc011e8785799691c8a2e3af5/644c5/pipeline_man_walking.jpg 1440w,
/static/8f47d32dc011e8785799691c8a2e3af5/0f98f/pipeline_man_walking.jpg 1920w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/jpeg&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/8f47d32dc011e8785799691c8a2e3af5/6a068/pipeline_man_walking.jpg&quot;
            alt=&quot;You have broken the CI/CD pipeline&quot;
            title=&quot;You have broken the CI/CD pipeline&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;-you-have-broken-the-cicd-pipeline&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#-you-have-broken-the-cicd-pipeline&quot; aria-label=&quot; you have broken the cicd pipeline permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;😨 You have broken the CI/CD pipeline&lt;/h2&gt;
&lt;p&gt;A couple of weeks ago I spent some time investigating a test that started to
fail in CI/CD pipeline after I have merged a pull request. &lt;strong&gt;When a test starts
failing in CI/CD, the faces of the people with commits that triggered that CI/CD
run go to a public dashboard, visible by the whole R&amp;#x26;D team&lt;/strong&gt;. My face was there
🤦. Not a great feeling. I’ve assigned the failing test to myself. I’ve
put the label  &lt;code class=&quot;language-text&quot;&gt;I&apos;m on it&lt;/code&gt; on the test.&lt;/p&gt;
&lt;h2 id=&quot;-it-works-on-my-machine&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#-it-works-on-my-machine&quot; aria-label=&quot; it works on my machine permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;💻 It works on my machine&lt;/h2&gt;
&lt;p&gt;The test was not new, and it was doing some odd stuff in the arrange part of the
test in order to setup some behavior in the database related with nested
transactions. My pull request was making changes in the database, including a
new version of a stored procedure that is being called in that test. I thought
it could be something on the stored procedure itself. &lt;strong&gt;The curious thing is
that I couldn’t reproduce the error in my machine when I was running the test
inside Visual Studio, or even using the same runner app that CI/CD pipeline was
using.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&quot;️️-investigation&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%EF%B8%8F%EF%B8%8F-investigation&quot; aria-label=&quot;️️ investigation permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;🕵️‍♂️ Investigation&lt;/h2&gt;
&lt;p&gt;After spending some time troubleshooting I got the conclusion that the problem
was not in the database changes. &lt;strong&gt;So what could it be?&lt;/strong&gt; With the help of my
team, I understood that &lt;strong&gt;in CI/CD pipeline the tests run against a release
build. Not only release, but also a build with an obfuscation process in
place&lt;/strong&gt;. So the next step was to run the test in the exact some conditions. And
guess what - the test started to fail in my machine. It should be the
obfuscation process, I thought. Let’s remove obfuscation out of the equation -
the test was still failing with just a release build without obfuscation.&lt;/p&gt;
&lt;p&gt;Next step was to try to &lt;strong&gt;understand the differences between the Build and
Release configuration&lt;/strong&gt;. We also checked what were the differences at the &lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/standard/managed-code#intermediate-language--execution&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;.Net
Intermediate Language
(IL)&lt;/a&gt;.
Nothing relevant from these differences that could explain the behavior of the
test.&lt;/p&gt;
&lt;p&gt;One member of my team then have tried to apply the &lt;code class=&quot;language-text&quot;&gt;NoOptimization&lt;/code&gt; attribute to the test
method. Then the test started to pass again 💥.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;csharp&quot;&gt;&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Fact&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;MethodImpl&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;MethodImplOptions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;NoOptimization&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Test_method_here&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ... test code goes here&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;From the
&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.methodimploptions?view=netframework-4.7.2&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;documentation&lt;/a&gt;
we can see what the &lt;code class=&quot;language-text&quot;&gt;NoOptimization&lt;/code&gt; means&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The method is not optimized by the just-in-time (JIT) compiler or by native
code generation (see Ngen.exe) when debugging possible code generation
problems.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;With this change, my face was not anymore on the public dashboard. But I was not
happy with the fix. This code was just a test, but it’s not hard to imagine that
some production code could have the same issue. &lt;strong&gt;The &lt;code class=&quot;language-text&quot;&gt;NoOptimization&lt;/code&gt; could be
only masquerading the real issue&lt;/strong&gt;. It seems that the JIT compiler is doing
something different for the release build. I plan in my next post to explain what
the test was doing, why it was failing in release, and how I have fixed it
without the need to rely on compiler services options.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[VS 2019 on Windows - Debugging a unit test running in a Linux container]]></title><description><![CDATA[This post shows how to debug in VS 2019 on Windows a unit test running in a Linux container]]></description><link>https://bfcamara.com/posts/vs2019-debugging-unit-test-in-container/</link><guid isPermaLink="false">https://bfcamara.com/posts/vs2019-debugging-unit-test-in-container/</guid><pubDate>Mon, 11 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/4b76264bdf95b42783998d1156e3587a/d073d/vs_debug_unit_tests_in_linux_containers.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 50%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAB2HAAAdhwGP5fFlAAABpUlEQVQoz43P7W6VQBDGce7CVAsL7C5v5wALLO8HTNvEVtsYTTXGb97/TfwNtCZ60qgffpmZZ5PJjnNar7G2p13vaOYb2nbEtsOu7yeGYaLrZ9p2oBtONHak7ReGaaHrR4yxNHbAVJY8r3Cm9QY7Lhxuv6Pf/SA1PWnZkdU9ZT/Rjgt1O1FUHVnRcCg3dncsLZWdaLoZY0eyvMaJoxhTpZijInBdDsecIj8iZUgoQ7RSyDAkDAMC338mdluulURtpCQIAhwpNXGqKKsjQvgUduRQWITKkFLiByE61kilCLflSqHjCKkiLl67vLq43G297/s4ZVHgJZqsiPBcwZtLl6vZ8O3jicf7kcf7gS8PT/Xrw+/zyKfbjs93PY8fBt5fNwjh4aRZhqclURzieR5CCEyqGKqExiRYs9V4r/aP+Slrq4SuTqm2D3kuTpSkCBWTpilaR/uZwg9wPR/vjPvC/IsnAoIgxFnXK5blLVVtKcoaY2qapsX+RfPsPC/LGmeeT6zLSpYdiOMEKdV/UUq/kCmcbUmSpLut387+lyiKyfNiX3r+9hMauC8gK2SCswAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/4b76264bdf95b42783998d1156e3587a/8ac56/vs_debug_unit_tests_in_linux_containers.webp 240w,
/static/4b76264bdf95b42783998d1156e3587a/d3be9/vs_debug_unit_tests_in_linux_containers.webp 480w,
/static/4b76264bdf95b42783998d1156e3587a/e46b2/vs_debug_unit_tests_in_linux_containers.webp 960w,
/static/4b76264bdf95b42783998d1156e3587a/37e8d/vs_debug_unit_tests_in_linux_containers.webp 1297w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/4b76264bdf95b42783998d1156e3587a/8ff5a/vs_debug_unit_tests_in_linux_containers.png 240w,
/static/4b76264bdf95b42783998d1156e3587a/e85cb/vs_debug_unit_tests_in_linux_containers.png 480w,
/static/4b76264bdf95b42783998d1156e3587a/d9199/vs_debug_unit_tests_in_linux_containers.png 960w,
/static/4b76264bdf95b42783998d1156e3587a/d073d/vs_debug_unit_tests_in_linux_containers.png 1297w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/4b76264bdf95b42783998d1156e3587a/d9199/vs_debug_unit_tests_in_linux_containers.png&quot;
            alt=&quot;Debug Unit Tests in Linux
Containers&quot;
            title=&quot;Debug Unit Tests in Linux
Containers&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/visualstudio/containers/overview?view=vs-2019#docker-support-in-visual-studio-1&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Docker Support in Visual Studio
2019&lt;/a&gt;
is great, providing a great experience for &lt;strong&gt;running and debugging ASP.NET and
Console applications in docker containers&lt;/strong&gt;. But when it comes to &lt;strong&gt;Unit Test
projects the experience is not so great&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;My expectation was that the experience of running or debugging unit tests in
containers would be exactly the same as ASP.NET or Console apps. I was even
expecting that I could use the VS Test Explorer: as long as the Docker launch
profile was selected, I thought that the tests would be running/debugging inside
the container. Unfortunately it’s not the case.&lt;/p&gt;
&lt;p&gt;So, imagine that you are working with Visual Studio 2019 on Windows, building a
.NET Core project that would be deployed in Windows, but also in Linux, and &lt;strong&gt;a
specific test is failing in Linux, and you want to debug it&lt;/strong&gt;. How can we do it
in a simple way?&lt;/p&gt;
&lt;p&gt;Let’s create a &lt;a href=&quot;https://xunit.net/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;xUnit&lt;/a&gt; (my test framework of choice) test
project.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 807px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/9b1311b4fa5db4957e9906b8c451b908/d2a60/vs-create-xunit-test-project.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 56.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACFElEQVQozz2OS2sUQRRGO/hW3AhKFnlod1V1d92qrq5nV02/ZsA4MyQKxr3/QAlZZEAlagR/SxAMuM3GEKLgwoUL0Z8jnYCXsz3nu5Eo5XQ2m83nddNOpzNnXRwjYJwxznjBGM9z+A/nAmOCEB7AJFLazOazjY1HACyOE4QwxkRKa4231htTCaHL0lzgXMgymqZ5lmYEZMQ4d1WllBZCSqVEMbS1dsZ4rSutK8bEKHRmaAUhtFLW+9YY71wdUQrWOue81sYYU5YyjpMQQt00VeXPL0ip8pxSCpQyAA7AABghaVQURV03zjmgED9IkgQhhDkvjHEh1N6PlNJKGa2tEPLcHGRKGcYkyil0/cS5KkkQISkhKUKYMi6kUtoqbY11opS8KClwTLIEEYQHMMmGt30I1jqAIUZIGsfJyPu+bUdVZZWqjFFCFEA5UMGYYKzkXDAGeRYBsAtZSkVIiodkugY2DRvQbeX1lPWb0G0W48esf8z6rayZ025rXU/WZR/lOQ0htG3HeYEwIRjfx5Q/30eLo5UPP5bfflt+9/32q7Pri9Ore6c3905u7X0dWJxc2z2OikKMJ5OmabMsR4gMy5jcePHlzpuzePdwZefw3s7nuy8/kcVR+Hi89PrnpYO/V97/vnzwZ2n/1/B207QXyxcmxmQtbMZhnpoOXJ+6cWZ78GNeP1yvn6x2z1ab7dVme615+g+R3I8fIj+iOgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/9b1311b4fa5db4957e9906b8c451b908/8ac56/vs-create-xunit-test-project.webp 240w,
/static/9b1311b4fa5db4957e9906b8c451b908/d3be9/vs-create-xunit-test-project.webp 480w,
/static/9b1311b4fa5db4957e9906b8c451b908/9ec5a/vs-create-xunit-test-project.webp 807w&quot;
              sizes=&quot;(max-width: 807px) 100vw, 807px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/9b1311b4fa5db4957e9906b8c451b908/8ff5a/vs-create-xunit-test-project.png 240w,
/static/9b1311b4fa5db4957e9906b8c451b908/e85cb/vs-create-xunit-test-project.png 480w,
/static/9b1311b4fa5db4957e9906b8c451b908/d2a60/vs-create-xunit-test-project.png 807w&quot;
            sizes=&quot;(max-width: 807px) 100vw, 807px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/9b1311b4fa5db4957e9906b8c451b908/d2a60/vs-create-xunit-test-project.png&quot;
            alt=&quot;xUnit test project&quot;
            title=&quot;xUnit test project&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;For demonstrating purposes, let’s create a simple test that asserts that the
test is running in a Linux container.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;  &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Fact&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Test_is_running_in_linux_container&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

      Assert&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;RuntimeInformation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;IsOSPlatform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;OSPlatform&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Linux&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Unlike ASP.NET projects, &lt;strong&gt;in Unit Test projects we don’t have the option “Enable
Docker Support” while creating the project&lt;/strong&gt;. Though, the option is still
available via Solution Explorer. Let’s try it.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 937px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b43654b31293129de0543d0a7c6442e2/98b29/vs_xunit_add_docker_support.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 80%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACCElEQVQoz3WSyW4UMRCG5yFA017Kdtsuuzfb7V6mMxIKUjKCA+LEHSRuvP8LoB4rJJOE0n+xVV/tB/GeAUCtddcNAIIyzhkz7aDGT/78ZfnxR3/9zR5+8cefB/EfA85DiNY6peo9REXIxw+CkW0aY4NegVNwAAABIJ/sH8xBdn1Ei1pbKRVjnHEQUjVtj64pOnRDZxArSgmlFaUcoNQtLY7zmuLofcM5FAEIaxHRFR2+f77/dn9/2U4Py3LZTo21hZdKTdMcQixp34e3lLaUzmO+S+mcMxoDJbkQKY0pJinV3jNllDLG+A1c0f2zovRIyPGpbCmEQTcvWx5z23bGWKXqXbW2T+QOCyGc9/O8DF0PIBjjxtppmo2xd3fndd2mPCE6a7EIX8IAgEbnMYcQCdnLkFJZi0LIGFOKY+ObfdSME7KXjfiibM65dX5dT8uyXh4vy7IaY0uSvu2l3JdcpqVUXeI+wzkvbdvnPK3rKcWktdlblsrUehqzkOp4rChlhDBrUUpljH2GQxi1tiHE02lDdGWqV28aQpymxaFH3O+sLOwms0NXax1CXJe1vnpcT27XENK6rCmNwxC9b+h+5bewtRhjiiG1bSelIoQqVTvnam3zvM7T7H0DIKqKlLg3MKJz6Nuuj2FvuKyZc9DajNclS1kXOecb376Gy9s5/3KHr/69b946/AVanInETOqvKgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/b43654b31293129de0543d0a7c6442e2/8ac56/vs_xunit_add_docker_support.webp 240w,
/static/b43654b31293129de0543d0a7c6442e2/d3be9/vs_xunit_add_docker_support.webp 480w,
/static/b43654b31293129de0543d0a7c6442e2/ff430/vs_xunit_add_docker_support.webp 937w&quot;
              sizes=&quot;(max-width: 937px) 100vw, 937px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/b43654b31293129de0543d0a7c6442e2/8ff5a/vs_xunit_add_docker_support.png 240w,
/static/b43654b31293129de0543d0a7c6442e2/e85cb/vs_xunit_add_docker_support.png 480w,
/static/b43654b31293129de0543d0a7c6442e2/98b29/vs_xunit_add_docker_support.png 937w&quot;
            sizes=&quot;(max-width: 937px) 100vw, 937px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/b43654b31293129de0543d0a7c6442e2/98b29/vs_xunit_add_docker_support.png&quot;
            alt=&quot;Add docker support&quot;
            title=&quot;Add docker support&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Choose Linux as target. The result: a &lt;code class=&quot;language-text&quot;&gt;Dockerfile&lt;/code&gt; is added to the solution and
a new &lt;code class=&quot;language-text&quot;&gt;Docker&lt;/code&gt; launch profile is added to the list of profiles.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 547px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a8d35ec12271a0b141ea83796ce16bff/977f7/vs_dockerfile_and_docker_profile.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 62.916666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACRElEQVQoz03QW2+bMBQHcL7GkgZwsLlj4hvGYDC3BNJ00tatanfT3rut3/9xIpu6WT8/HMnn/I9stW1fazNNJ6W0MUOlzfl80XVjTH88LYWs+nHhQhkztmbQ2lBavLKGfpKFyjHlUpZVZUpNCJ1NLWRFhTqwUg1vudRMlOM0y0IRwikVGJMsO1j4wDLMMGZ+zpYYPyW5n3NVtWWpdd2Vsi6Vxpj+eZ2lhzQ9YEzznGJMLaHnQp+5mU09PdZDaRZaT6I5CqGkVJ0Zu2ZiTHAutW6rulVmwaTI0nxNhp7nQ4QQihEMfAQR8gBQa64py7rRva67um6U0lq3hayF6nNSHHJGiLAIJTk5UEp5URBK8zxPs3S+7XXVd91xmKau60+nZZyOXTcKIRkT6xQhwzC2XOA6ruO6LgBgvQDYtj2MA2dSlMXt3d3lcjfPy+VykVIGQRgEYRwnYRhBiKz99YAVcBzHtu3NZjPPZ8p4GEaNEvNpmaYTJhT5QRCECPkQIgh9hHyLrX/PGGUYZ0EQAAA228209JRyCCFnbBjGpjVjUehSRRnee/DavLJAHLoBAqG/9zx7t3NsZ7Pbno9VW5mqNk3XPzx8fv/x6RMVjwk+5qwSivO/rH0S7ZMQhD7yob3buY59c7MZp05wGYRRFCdJkiVJGiZZHCUqjKo4jeIkvrJ2N/Z2u0ZuV+6N7b7Z7vphIoQBACBEnge9dVXoQQSu/q3N7n91X37Sd8/i/nn4+jJ9exEfflwevpM89zyIkP8//+q1/A3q5Zl9jOzcuQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/a8d35ec12271a0b141ea83796ce16bff/8ac56/vs_dockerfile_and_docker_profile.webp 240w,
/static/a8d35ec12271a0b141ea83796ce16bff/d3be9/vs_dockerfile_and_docker_profile.webp 480w,
/static/a8d35ec12271a0b141ea83796ce16bff/61e23/vs_dockerfile_and_docker_profile.webp 547w&quot;
              sizes=&quot;(max-width: 547px) 100vw, 547px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/a8d35ec12271a0b141ea83796ce16bff/8ff5a/vs_dockerfile_and_docker_profile.png 240w,
/static/a8d35ec12271a0b141ea83796ce16bff/e85cb/vs_dockerfile_and_docker_profile.png 480w,
/static/a8d35ec12271a0b141ea83796ce16bff/977f7/vs_dockerfile_and_docker_profile.png 547w&quot;
            sizes=&quot;(max-width: 547px) 100vw, 547px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/a8d35ec12271a0b141ea83796ce16bff/977f7/vs_dockerfile_and_docker_profile.png&quot;
            alt=&quot;Dockerfile and Docker profile&quot;
            title=&quot;Dockerfile and Docker profile&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This is exactly the same behavior we get in an ASP.NET or Console project.
However, the running experience is not the same: &lt;strong&gt;the integration between the
test explorer and the docker container does not work&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;That’s what have triggered me to do some investigation. First we need to
&lt;strong&gt;understand what VS is doing when we start debugging in a container with the
the &lt;code class=&quot;language-text&quot;&gt;Docker&lt;/code&gt; profile selected&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;VS optimizes the Debug experience by using the so called &lt;a href=&quot;https://docs.microsoft.com/en-us/visualstudio/containers/container-build?view=vs-2019&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Fast build
mode&lt;/a&gt;&lt;/strong&gt;.
In this mode, the &lt;code class=&quot;language-text&quot;&gt;docker build&lt;/code&gt; command used by VS only uses the &lt;code class=&quot;language-text&quot;&gt;base&lt;/code&gt; stage
of the &lt;code class=&quot;language-text&quot;&gt;Dockerfile&lt;/code&gt;. Furthermore, when selecting the &lt;code class=&quot;language-text&quot;&gt;Docker&lt;/code&gt; profile a
&lt;strong&gt;Project warmup&lt;/strong&gt; is triggered consisting in the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Check Docker Desktop is running and is set to the same operating system as
project&lt;/li&gt;
&lt;li&gt;Pull the image in the first stage (the &lt;code class=&quot;language-text&quot;&gt;base&lt;/code&gt; stage)&lt;/li&gt;
&lt;li&gt;Build the &lt;code class=&quot;language-text&quot;&gt;Dockerfile&lt;/code&gt; and start the container&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When VS starts the container, some volume mappings are created for the remote
debugger, and for Nuget folders. You can check the full &lt;code class=&quot;language-text&quot;&gt;docker run&lt;/code&gt; command in
the Containers Tools output window.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/707eb952144545b6599b1d9053969434/3f8cf/vs_docker_run_command.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 27.916666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAA/ElEQVQY022K60rDQBBG8yY2O7nsZXZ2m3s2oY1UqDEJ/lJ8ANtG/KP4/iBsBRGEw3C+wwSbkDGIQgYMIGQ/bNivhwxuNmH4tzCIGMQBPX1kL1/88T2e12hek/kST2e+vCXLCuMJxlP0cM6eP9n963VeiadLsqzB/m7sD8fG7eqsavJa2kKZXG+rFC1LFXCMOErKgCNw7S/6qCHF4DgMU9eNrjtUVW5ICoFSSs6VFyWEEuI6JRdKSiWlFEL4Euxdf9v1u91QN66q27pumqZVCg1Za7dEhsgaY4ksojbGuzZKodYUuK53Xd+2rijKsqyyvEAkrQlRe+hf/AN9A0vfRdlQPL2FAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/707eb952144545b6599b1d9053969434/8ac56/vs_docker_run_command.webp 240w,
/static/707eb952144545b6599b1d9053969434/d3be9/vs_docker_run_command.webp 480w,
/static/707eb952144545b6599b1d9053969434/e46b2/vs_docker_run_command.webp 960w,
/static/707eb952144545b6599b1d9053969434/dfa64/vs_docker_run_command.webp 1293w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/707eb952144545b6599b1d9053969434/8ff5a/vs_docker_run_command.png 240w,
/static/707eb952144545b6599b1d9053969434/e85cb/vs_docker_run_command.png 480w,
/static/707eb952144545b6599b1d9053969434/d9199/vs_docker_run_command.png 960w,
/static/707eb952144545b6599b1d9053969434/3f8cf/vs_docker_run_command.png 1293w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/707eb952144545b6599b1d9053969434/d9199/vs_docker_run_command.png&quot;
            alt=&quot;VS Docker Run Command&quot;
            title=&quot;VS Docker Run Command&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The container is now running. We can check it in the Containers window.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/eee01f6c773e302b62d0215ac72fdee5/8de58/vs_containers_window.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 32.49999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABLUlEQVQY03XN207CQBAG4L6DsbYYFfaAdZt2Z3fZtNgWr+EVCBLCAyhYK6IpNh5Cr/SRzVI03jj5LmZmd/Jb2fzhar7KZkV/cpdM76PxIhov4kkeTfLL6zyZ/iubFVb1Veevz7eb1WKzuimLdV29fG6X79XyrSo+yqe6XNcbY/urbDxuS0uHEAQSYw+dofZJ2/dYrKNYa4/SzmmbImIfHDqHtms7ru20jtyWs3fsuFa/n2odAZcgemEotI5Gw9FwOIrjOAjCNE0H2SBJEqWU7mkA8P6UhRAmhDYwJoz5PvMp7RJCKT0XQirVk1JxDgCCMX+37zYsjMnPMWnuMcLYbE3f6aA9ZArvXjBuflOLh8C5AC5ASM6FECo0IdJEmVECGLtwYXouOAjKwLvwvwF1vWPuuWnsiQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/eee01f6c773e302b62d0215ac72fdee5/8ac56/vs_containers_window.webp 240w,
/static/eee01f6c773e302b62d0215ac72fdee5/d3be9/vs_containers_window.webp 480w,
/static/eee01f6c773e302b62d0215ac72fdee5/e46b2/vs_containers_window.webp 960w,
/static/eee01f6c773e302b62d0215ac72fdee5/4fba2/vs_containers_window.webp 1219w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/eee01f6c773e302b62d0215ac72fdee5/8ff5a/vs_containers_window.png 240w,
/static/eee01f6c773e302b62d0215ac72fdee5/e85cb/vs_containers_window.png 480w,
/static/eee01f6c773e302b62d0215ac72fdee5/d9199/vs_containers_window.png 960w,
/static/eee01f6c773e302b62d0215ac72fdee5/8de58/vs_containers_window.png 1219w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/eee01f6c773e302b62d0215ac72fdee5/d9199/vs_containers_window.png&quot;
            alt=&quot;VS Containers window&quot;
            title=&quot;VS Containers window&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Now &lt;strong&gt;we want to run our tests inside the container&lt;/strong&gt;. Basically we just need to run
the &lt;code class=&quot;language-text&quot;&gt;dotnet test&lt;/code&gt; command inside the container. We can do it using the &lt;code class=&quot;language-text&quot;&gt;docker
exec&lt;/code&gt; command.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;exec&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-it&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;name_of_the_container&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; dotnet &lt;span class=&quot;token builtin class-name&quot;&gt;test&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s see what happens.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/691200ebe161cbc35081d1605bdb5c53/d0fa6/vs_docker_exe_dotnet_test_error.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 30.41666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAvklEQVQY033L7WrCMBiG4ZzJ1ibvR0w7C01bk6JGVsXOMgV3ALYi6PmfgMz+HCtcP24eeETWXezPIzneqb3S14D7HtsB2wH2/QTd3XR3E/Xue304u91psT3azSFxn7oMuljLzE2I57/EqvbbTWjCqgk+LP3SVa6wNpsbAojeMH7/R4RxJPK8cM55X5dlZUwymxljkjy3RAyA0wQASamUAinVGACYph9KwWjqzKyJNb8Q8QiRiJj/7C+akAEIkJ9cOkNz+EdZOwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/691200ebe161cbc35081d1605bdb5c53/8ac56/vs_docker_exe_dotnet_test_error.webp 240w,
/static/691200ebe161cbc35081d1605bdb5c53/d3be9/vs_docker_exe_dotnet_test_error.webp 480w,
/static/691200ebe161cbc35081d1605bdb5c53/e46b2/vs_docker_exe_dotnet_test_error.webp 960w,
/static/691200ebe161cbc35081d1605bdb5c53/879a2/vs_docker_exe_dotnet_test_error.webp 1263w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/691200ebe161cbc35081d1605bdb5c53/8ff5a/vs_docker_exe_dotnet_test_error.png 240w,
/static/691200ebe161cbc35081d1605bdb5c53/e85cb/vs_docker_exe_dotnet_test_error.png 480w,
/static/691200ebe161cbc35081d1605bdb5c53/d9199/vs_docker_exe_dotnet_test_error.png 960w,
/static/691200ebe161cbc35081d1605bdb5c53/d0fa6/vs_docker_exe_dotnet_test_error.png 1263w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/691200ebe161cbc35081d1605bdb5c53/d9199/vs_docker_exe_dotnet_test_error.png&quot;
            alt=&quot;Docker exec dotnet test&quot;
            title=&quot;Docker exec dotnet test&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We got the following error&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;It was not possible to find any installed .NET Core SDKs&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now we need to look at the &lt;code class=&quot;language-text&quot;&gt;Dockerfile&lt;/code&gt; to understand what image is running.
This the &lt;code class=&quot;language-text&quot;&gt;Dockerfile&lt;/code&gt; originally generated by VS.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;docker&quot;&gt;&lt;pre class=&quot;language-docker&quot;&gt;&lt;code class=&quot;language-docker&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; mcr.microsoft.com/dotnet/core/runtime:3.1-buster-slim &lt;span class=&quot;token keyword&quot;&gt;AS&lt;/span&gt; base&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;WORKDIR&lt;/span&gt; /app&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; mcr.microsoft.com/dotnet/core/sdk:3.1-buster &lt;span class=&quot;token keyword&quot;&gt;AS&lt;/span&gt; build&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;WORKDIR&lt;/span&gt; /src&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; [&lt;span class=&quot;token string&quot;&gt;&quot;XUnitTestContainers/XUnitTestContainers.csproj&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;XUnitTestContainers/&quot;&lt;/span&gt;]&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; dotnet restore &lt;span class=&quot;token string&quot;&gt;&quot;XUnitTestContainers/XUnitTestContainers.csproj&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; . .&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;WORKDIR&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/src/XUnitTestContainers&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; dotnet build &lt;span class=&quot;token string&quot;&gt;&quot;XUnitTestContainers.csproj&quot;&lt;/span&gt; -c Release -o /app/build&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; build &lt;span class=&quot;token keyword&quot;&gt;AS&lt;/span&gt; publish&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; dotnet publish &lt;span class=&quot;token string&quot;&gt;&quot;XUnitTestContainers.csproj&quot;&lt;/span&gt; -c Release -o /app/publish&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; base &lt;span class=&quot;token keyword&quot;&gt;AS&lt;/span&gt; final&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;WORKDIR&lt;/span&gt; /app&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; &lt;span class=&quot;token options&quot;&gt;&lt;span class=&quot;token property&quot;&gt;--from&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;publish&lt;/span&gt;&lt;/span&gt; /app/publish .&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ENTRYPOINT&lt;/span&gt; [&lt;span class=&quot;token string&quot;&gt;&quot;dotnet&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;XUnitTestContainers.dll&quot;&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first thing to notice is the comment at the top of the file. Follow that
link to understand the Fast build mode I mentioned earlier. &lt;strong&gt;In the Fast mode,
only the &lt;code class=&quot;language-text&quot;&gt;base&lt;/code&gt; stage is used&lt;/strong&gt;. In this case &lt;strong&gt;the &lt;code class=&quot;language-text&quot;&gt;base&lt;/code&gt; stage is using a
runtime image which does not include the .NET SDK required to run tests&lt;/strong&gt;. We
need to change our &lt;code class=&quot;language-text&quot;&gt;Dockerfile&lt;/code&gt; to use a .NET SDK image in the &lt;code class=&quot;language-text&quot;&gt;base&lt;/code&gt; stage. We
can also remove all the other stages since they are not being used when
debugging.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;docker&quot;&gt;&lt;pre class=&quot;language-docker&quot;&gt;&lt;code class=&quot;language-docker&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; mcr.microsoft.com/dotnet/core/sdk:3.1-buster &lt;span class=&quot;token keyword&quot;&gt;AS&lt;/span&gt; base&lt;/span&gt;
&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;WORKDIR&lt;/span&gt; /app&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Rebuild the solution. And let’s try again to run the &lt;code class=&quot;language-text&quot;&gt;dotnet test&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/0167b4dd758f1d4662f8ebd947fb37c6/0f246/vs_docker_test_ok.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 36.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABC0lEQVQY033J62rCQBQE4DxJqdmz9z27m82lGu8WYypWKC22rqG/Cn3/NyhR0D9S+BiGmcRNt6qJuO3kOsLiINZH1ZxkE1Vz6m1OetOZttNtn7KJsDzQM1geknzxsvz8nX38FLvvcne0zZdvY9h2vo2ujWr1zudvMNmTyf6SZPx6lYyHo9W0ntfD9WL6PKvHZZiPqroMVjIrGHJQdMAeH24GN4nPgnOZtd754LOgjRVS50Vl0A1SAMqAcsrEXUlWVn4y0sFrbYSQUiopFeeCc8EYv6CU3ZU4l+VPVV4UIeSEQJqSNCWEwD8AgPZoYozT2pyhtR7RWuuNQURnjEV057HvlxfRSm1BOibxD0fVUEXobIIcAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/0167b4dd758f1d4662f8ebd947fb37c6/8ac56/vs_docker_test_ok.webp 240w,
/static/0167b4dd758f1d4662f8ebd947fb37c6/d3be9/vs_docker_test_ok.webp 480w,
/static/0167b4dd758f1d4662f8ebd947fb37c6/e46b2/vs_docker_test_ok.webp 960w,
/static/0167b4dd758f1d4662f8ebd947fb37c6/34186/vs_docker_test_ok.webp 1118w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/0167b4dd758f1d4662f8ebd947fb37c6/8ff5a/vs_docker_test_ok.png 240w,
/static/0167b4dd758f1d4662f8ebd947fb37c6/e85cb/vs_docker_test_ok.png 480w,
/static/0167b4dd758f1d4662f8ebd947fb37c6/d9199/vs_docker_test_ok.png 960w,
/static/0167b4dd758f1d4662f8ebd947fb37c6/0f246/vs_docker_test_ok.png 1118w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/0167b4dd758f1d4662f8ebd947fb37c6/d9199/vs_docker_test_ok.png&quot;
            alt=&quot;Docker test Ok&quot;
            title=&quot;Docker test Ok&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Great, we are now running our tests inside the container. Now we just need to
have a way &lt;strong&gt;to launch the remote debugger and attach to the process responsible
to run the tests&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;When we run a &lt;code class=&quot;language-text&quot;&gt;dotnet test&lt;/code&gt; command, a new process is started to run
&lt;code class=&quot;language-text&quot;&gt;vstest.console&lt;/code&gt; to execute the tests, which in turn runs the &lt;code class=&quot;language-text&quot;&gt;testhost.dll&lt;/code&gt;. We
can &lt;strong&gt;instruct &lt;code class=&quot;language-text&quot;&gt;testhost&lt;/code&gt; to pause execution waiting for a debugger to be
attached, by using an environment variable &lt;code class=&quot;language-text&quot;&gt;VSTEST_HOST_DEBUG=1&lt;/code&gt;&lt;/strong&gt;. Let’s run
the same &lt;code class=&quot;language-text&quot;&gt;docker exec&lt;/code&gt; command passing this environment variable.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;exec&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-it&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;VSTEST_HOST_DEBUG&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;name_of_container&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; dotnet &lt;span class=&quot;token builtin class-name&quot;&gt;test&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/2269e8bc262b5601895d4459c1977f95/99661/vs_donet_test_attach_debugger.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 34.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABCElEQVQY03XL0W6CMBiGYW5F/rYUWmj/om0pDJTp1KgYk2XLLmBHc8k82P0vw4Md6JLn4M2XfJEe3u3bt3m90NOFnb7ocIbDBxzOZBiNQY+fd0X1atcPL93uudkc6/XetGvb79zjvpxvpyNsVtmsBeVuRa33nbOts4vKz70LBh9mU49aJaxgLE9YylhCgEF8Kzr4ats0m1BvQlhav7R2bkwlZRDSy7zLspxQoIzeEz0htoh9Oe208ZkIQlZCuDRzPJ3xtOG8YOzfMyc0mcQshmQCPAbBWEooB8KBpEASIDAihMJfEzqKlDa5wkKhQlMobLtFFWopC43l76iNvlJosLyGKBAEUqF/AEniU3ywjA6DAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/2269e8bc262b5601895d4459c1977f95/8ac56/vs_donet_test_attach_debugger.webp 240w,
/static/2269e8bc262b5601895d4459c1977f95/d3be9/vs_donet_test_attach_debugger.webp 480w,
/static/2269e8bc262b5601895d4459c1977f95/e46b2/vs_donet_test_attach_debugger.webp 960w,
/static/2269e8bc262b5601895d4459c1977f95/4eac3/vs_donet_test_attach_debugger.webp 1098w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/2269e8bc262b5601895d4459c1977f95/8ff5a/vs_donet_test_attach_debugger.png 240w,
/static/2269e8bc262b5601895d4459c1977f95/e85cb/vs_donet_test_attach_debugger.png 480w,
/static/2269e8bc262b5601895d4459c1977f95/d9199/vs_donet_test_attach_debugger.png 960w,
/static/2269e8bc262b5601895d4459c1977f95/99661/vs_donet_test_attach_debugger.png 1098w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/2269e8bc262b5601895d4459c1977f95/d9199/vs_donet_test_attach_debugger.png&quot;
            alt=&quot;Attach debugger to dotnet test&quot;
            title=&quot;Attach debugger to dotnet test&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We got the following info&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;_A total of 1 test files matched the specified pattern. Host debugging is&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;enabled. Please attach debugger to testhost process to continue. Process Id:
643, Name: dotnet_&lt;/p&gt;
&lt;p&gt;Now we just need to &lt;strong&gt;attach the debugger to the &lt;code class=&quot;language-text&quot;&gt;testhost&lt;/code&gt; process&lt;/strong&gt;, which in
this case has its PID=643. Let’s use the Container window to attach the debugger
to this process.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/c318cca4317e54ee917ab01c03ee6c37/8740f/vs_attach_to_container.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 34.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABXUlEQVQY02XNyU7CUBQG4D4FCXRguPe2BdreqVBUqOIQEwXU4LzCoBjaijG1UIcFWy0sfGNTTNiYfP/JycmfHKHjvfc/f/rvSSf87s6WvXh5/PqVipKjKOnOkl6c9OLFfyfxQri+GwSh9/EyHg1uh+PBvTeYTJ+j+Zs3C0dR+Bg+TeKJH/krwYrvTwN/GgTTQHjwXt7mi/bZMGPuZE03Y7hl096qO5ywGmUqRLAE83I+LymKKCuSokiKnJOkrChlRaF5et288eHeldg6l92LrHtpNbYPD/bb7V1CqK7rmxubrZbbbLZsbnOeplyuqJquaboACsWCmEPFvFZKqUXZMgzbrmFMsUUMw7TtWr3uOE6DM24aVqVShRAhpCKkCqqmA4ggUgFcQ3AFIRVCBABcL6USgKs2ABAAKGBMLYukfwillGFMKeWWRQhhf5MSRkh6Z4wzyrQq0QzCKMeY/gKtJWm8OwMo5AAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/c318cca4317e54ee917ab01c03ee6c37/8ac56/vs_attach_to_container.webp 240w,
/static/c318cca4317e54ee917ab01c03ee6c37/d3be9/vs_attach_to_container.webp 480w,
/static/c318cca4317e54ee917ab01c03ee6c37/e46b2/vs_attach_to_container.webp 960w,
/static/c318cca4317e54ee917ab01c03ee6c37/3fe5f/vs_attach_to_container.webp 1106w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/c318cca4317e54ee917ab01c03ee6c37/8ff5a/vs_attach_to_container.png 240w,
/static/c318cca4317e54ee917ab01c03ee6c37/e85cb/vs_attach_to_container.png 480w,
/static/c318cca4317e54ee917ab01c03ee6c37/d9199/vs_attach_to_container.png 960w,
/static/c318cca4317e54ee917ab01c03ee6c37/8740f/vs_attach_to_container.png 1106w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/c318cca4317e54ee917ab01c03ee6c37/d9199/vs_attach_to_container.png&quot;
            alt=&quot;Attach to process in container&quot;
            title=&quot;Attach to process in container&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/f36fdbe44cd81185743fe93ed1b96ead/ad00e/vs_attach_to_process_in_container.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 52.083333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABjElEQVQoz4XNbWvTUBQH8HxlX4uIb3SrY9sXUIYKY0hsR3UvfKWw1ZLO9cGS3DZtHWmbpPcmS3Lz0HvS5B6p62bRgX9+HA738Ocqu6/Ujx1H1aw3X4zji3H1cvZfJ41xvccePdtXTk9r4cJ2rZ+eMw2ZE9/QbdxfZKGfp9E27lOUcHhwoKhq1QvCmb2Yzh2X+g71/sGchbdGN9Oa2UmaPd+pKLUP1UKkIokg5ZBykUQi4ZDG9+5PGQ/yLBZxFN34iPhi96Xy7kRtmbQ1Cfrusj3lhILp5QMKQwYmA9MD3V32XdGz0+/XocHyzjyb0BgRd9bl4/dXE68xpNrY70y5NmINfd4cus2Bow1dbeC2rUhneW+etC1uMOja2bWXbcq1s8+IWJYSUSKiXIEscnwgEmV5uxTFal2u7CkXV11ELEp5q5Qo5d1+9/iXVVFsfq7XP5VlwSO+zDIAEL8DQgAIeDgiCAJErOztK6+P3pqjUbf3QzeIQQZ/GEQ3jG2EkMtu/2uzff6tRQh5/OTpL6g+Ex+UJummAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/f36fdbe44cd81185743fe93ed1b96ead/8ac56/vs_attach_to_process_in_container.webp 240w,
/static/f36fdbe44cd81185743fe93ed1b96ead/d3be9/vs_attach_to_process_in_container.webp 480w,
/static/f36fdbe44cd81185743fe93ed1b96ead/e46b2/vs_attach_to_process_in_container.webp 960w,
/static/f36fdbe44cd81185743fe93ed1b96ead/ec897/vs_attach_to_process_in_container.webp 1366w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/f36fdbe44cd81185743fe93ed1b96ead/8ff5a/vs_attach_to_process_in_container.png 240w,
/static/f36fdbe44cd81185743fe93ed1b96ead/e85cb/vs_attach_to_process_in_container.png 480w,
/static/f36fdbe44cd81185743fe93ed1b96ead/d9199/vs_attach_to_process_in_container.png 960w,
/static/f36fdbe44cd81185743fe93ed1b96ead/ad00e/vs_attach_to_process_in_container.png 1366w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/f36fdbe44cd81185743fe93ed1b96ead/d9199/vs_attach_to_process_in_container.png&quot;
            alt=&quot;Attach to process in container&quot;
            title=&quot;Attach to process in container&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 776px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/2779c7c6cb5e4d4f6635810b1807ff80/167b5/vs_attach_to_process_unix.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 49.16666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABlUlEQVQoz6XPzWsTQRjH8f2PheChBy14UWhPYr301ovgRVpqCypNlIJaRCtSRJJNsi9Nt3bn5ZnZnZedmZ1HktKqB09++RznB88k9CZCaAsUNYvqL6gZan7Lt4zcTBKyqiZUcvr2e7W2X6wfFvdfFvcOyvXDYm2/GOzlg918sJvd3cvuvMgej0pglNClRAgppWSM60Z8nLHNo3JrmD8ZFluj4uko33idPTiYPXyVbxxdbA4vHr1Z7Jz8XL1nnEPStC0idrbzPlhrqjw9OZu+/zb9cDb7Mr2UwNBA1IBWrohglTK2vqq7ziUcIPR9CMH7IBo1npc7x/Ptd/nzU/bsFCrpENGHeEsqLZoWAGKMSV3X3nvgfDKe5OXCGIPLIv6jVhkOghLinEsABCJKISfj9LImSilCWaO0dU4Z22qjtFbGGmuVUlrrRmmljRTLVdL3PSI65wQA4YIDUMoo41KK8yv2abz4/CP/mlbZeZWm6XyeEwbOh87a5fjPk/oYre+7EDvfX7M+Xut89D12ITr/+0cJ/ke/AHxyKTjBKPHLAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/2779c7c6cb5e4d4f6635810b1807ff80/8ac56/vs_attach_to_process_unix.webp 240w,
/static/2779c7c6cb5e4d4f6635810b1807ff80/d3be9/vs_attach_to_process_unix.webp 480w,
/static/2779c7c6cb5e4d4f6635810b1807ff80/bac22/vs_attach_to_process_unix.webp 776w&quot;
              sizes=&quot;(max-width: 776px) 100vw, 776px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/2779c7c6cb5e4d4f6635810b1807ff80/8ff5a/vs_attach_to_process_unix.png 240w,
/static/2779c7c6cb5e4d4f6635810b1807ff80/e85cb/vs_attach_to_process_unix.png 480w,
/static/2779c7c6cb5e4d4f6635810b1807ff80/167b5/vs_attach_to_process_unix.png 776w&quot;
            sizes=&quot;(max-width: 776px) 100vw, 776px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/2779c7c6cb5e4d4f6635810b1807ff80/167b5/vs_attach_to_process_unix.png&quot;
            alt=&quot;Debug Managed (.NET Core for Unix)&quot;
            title=&quot;Debug Managed (.NET Core for Unix)&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Wait a few seconds. You may see a screen informing that symbol loading was
skipped for &lt;code class=&quot;language-text&quot;&gt;testhost.dll&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 795px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b7704363085f1253b96a6d3d6615a904/65c7b/vs_skip_symbol_loading_testhost.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 40%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAA7DAAAOwwHHb6hkAAABOklEQVQY023LS1LcQAyAYR8FcLftbttqtfoh+TlhUoxhoKBYJ5VVWMD9D0CZFBuC9C3+hVTcn07JgSDM4xTTkELOWYTHPRJzlpx5mNZRxnVeRCZJwomHYck8F+bxzZz/mocXfH5NckgyYxAMnGRxxC1EH/M5jxRFhhnC4CkjZYyD57WoT7/rm19q+1MuTxSZ8tRCMECYBgu+NEAGJgtXBlTTa9NrC9rAHqYrVkk3P5brkY/rtG3bYV0Oh+vz3d3P4xH67uLi0itVqX200h+U/uzC+YAUHZJDQqQQk/cUQiSKznmPHtAjemNs3ZgvCqLgkUIIRKHr+k9dvy/0ux7A1XVTVfUXRcq83d4y8zwvIURrW2s7a9u27SpdlaUqS12WSuvqf0VjLIsAgAP0nhzgnh+axvw7qqr62+d3gGVawtp6QgIAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/b7704363085f1253b96a6d3d6615a904/8ac56/vs_skip_symbol_loading_testhost.webp 240w,
/static/b7704363085f1253b96a6d3d6615a904/d3be9/vs_skip_symbol_loading_testhost.webp 480w,
/static/b7704363085f1253b96a6d3d6615a904/399bf/vs_skip_symbol_loading_testhost.webp 795w&quot;
              sizes=&quot;(max-width: 795px) 100vw, 795px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/b7704363085f1253b96a6d3d6615a904/8ff5a/vs_skip_symbol_loading_testhost.png 240w,
/static/b7704363085f1253b96a6d3d6615a904/e85cb/vs_skip_symbol_loading_testhost.png 480w,
/static/b7704363085f1253b96a6d3d6615a904/65c7b/vs_skip_symbol_loading_testhost.png 795w&quot;
            sizes=&quot;(max-width: 795px) 100vw, 795px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/b7704363085f1253b96a6d3d6615a904/65c7b/vs_skip_symbol_loading_testhost.png&quot;
            alt=&quot;Skip symbol loading for testhost.dll&quot;
            title=&quot;Skip symbol loading for testhost.dll&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Just click &lt;code class=&quot;language-text&quot;&gt;Continue&lt;/code&gt; and your breakpoint is hit.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/e2f8c18f61356cc19e10b21686bdf337/561da/vs_breakpoint_debug_container.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 40.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAA7DAAAOwwHHb6hkAAABMklEQVQY043LSU/CQAAF4P4LCGWWTjvT2dpCqVCx7RRQYowaotalFD2oiXpR///FgMuBxOjLd3iH9yylVBdCjzIqe1QEQRBIIbXSSinPdSEE8PdYmzNijLqUyyDWOnK5TxR3fYq2xwBj9GN9FkJ2EZIhRxByFUb9IXQYQg4ACCEHYwwhgnCzx6TTAa2W3W7Z7bYNALRG/dDXPN2LCPGQSzOT3N7Nr5f5TZ0vV6ZuTN0Uy1VRN0XdmPNqfF6Nq6vx2UWqtG+NIsk424k5I45HcDrwT+ZxmYkylyZbK3M5KVSZyTKT00JNCz0zelIoyRwrql571Vt4+U5Pn93jF+foqTO7t9cevm31L/jw0RoeLCaLerC/wLH5RJKSJKXzFxwbK5Qi303TZBCHOhC+oB4lmP3PB3pbWSMZgpHUAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/e2f8c18f61356cc19e10b21686bdf337/8ac56/vs_breakpoint_debug_container.webp 240w,
/static/e2f8c18f61356cc19e10b21686bdf337/d3be9/vs_breakpoint_debug_container.webp 480w,
/static/e2f8c18f61356cc19e10b21686bdf337/e46b2/vs_breakpoint_debug_container.webp 960w,
/static/e2f8c18f61356cc19e10b21686bdf337/bd9c6/vs_breakpoint_debug_container.webp 969w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/e2f8c18f61356cc19e10b21686bdf337/8ff5a/vs_breakpoint_debug_container.png 240w,
/static/e2f8c18f61356cc19e10b21686bdf337/e85cb/vs_breakpoint_debug_container.png 480w,
/static/e2f8c18f61356cc19e10b21686bdf337/d9199/vs_breakpoint_debug_container.png 960w,
/static/e2f8c18f61356cc19e10b21686bdf337/561da/vs_breakpoint_debug_container.png 969w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/e2f8c18f61356cc19e10b21686bdf337/d9199/vs_breakpoint_debug_container.png&quot;
            alt=&quot;Breakpoint in container&quot;
            title=&quot;Breakpoint in container&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You can now debug your test inside the Linux container. The whole debugging unit
tests experience is not ideal and I truly hope VS integrates Test Explorer with
Containers Tools very soon.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Preparing Interviews for a Software Engineer position]]></title><description><![CDATA[I've just finished two job recuitment processes. Here are some tips and how I prepared them to succeed.]]></description><link>https://bfcamara.com/posts/preparing-interviews-for-software-engineer-position/</link><guid isPermaLink="false">https://bfcamara.com/posts/preparing-interviews-for-software-engineer-position/</guid><pubDate>Mon, 21 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/af6c13be5855124aa1e36e60c6164c3c/93719/preparing-interviews-for-software-engineer-position.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAMFBP/EABUBAQEAAAAAAAAAAAAAAAAAAAEC/9oADAMBAAIQAxAAAAGXWblEEkP/xAAaEAEBAAIDAAAAAAAAAAAAAAACAQADBBES/9oACAEBAAEFAvFzinrTtRKxWxUFZ//EABcRAAMBAAAAAAAAAAAAAAAAAAABERL/2gAIAQMBAT8BjMs//8QAFxEBAAMAAAAAAAAAAAAAAAAAAAEhMf/aAAgBAgEBPwGcU//EABwQAAIBBQEAAAAAAAAAAAAAAAABMQIREiEiQf/aAAgBAQAGPwLSZ0vSESNZF3Wz/8QAHBAAAgIDAQEAAAAAAAAAAAAAAAERITFBcVGB/9oACAEBAAE/IXNY+CGK2eUQXV4W9+C6QTvA5tOH/9oADAMBAAIAAwAAABAw/wD/xAAWEQEBAQAAAAAAAAAAAAAAAAABEBH/2gAIAQMBAT8QEcIf/8QAFhEBAQEAAAAAAAAAAAAAAAAAEQEQ/9oACAECAQE/EBVn/8QAHRABAAICAgMAAAAAAAAAAAAAAQARITFBUXGB0f/aAAgBAQABPxBgbDpMCZWwzGDuUHztJeQo2+kWUwQFbo5fE0EdN/BP/9k=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/af6c13be5855124aa1e36e60c6164c3c/8ac56/preparing-interviews-for-software-engineer-position.webp 240w,
/static/af6c13be5855124aa1e36e60c6164c3c/d3be9/preparing-interviews-for-software-engineer-position.webp 480w,
/static/af6c13be5855124aa1e36e60c6164c3c/e46b2/preparing-interviews-for-software-engineer-position.webp 960w,
/static/af6c13be5855124aa1e36e60c6164c3c/f992d/preparing-interviews-for-software-engineer-position.webp 1440w,
/static/af6c13be5855124aa1e36e60c6164c3c/882b9/preparing-interviews-for-software-engineer-position.webp 1920w,
/static/af6c13be5855124aa1e36e60c6164c3c/c67aa/preparing-interviews-for-software-engineer-position.webp 4000w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/af6c13be5855124aa1e36e60c6164c3c/09b79/preparing-interviews-for-software-engineer-position.jpg 240w,
/static/af6c13be5855124aa1e36e60c6164c3c/7cc5e/preparing-interviews-for-software-engineer-position.jpg 480w,
/static/af6c13be5855124aa1e36e60c6164c3c/6a068/preparing-interviews-for-software-engineer-position.jpg 960w,
/static/af6c13be5855124aa1e36e60c6164c3c/644c5/preparing-interviews-for-software-engineer-position.jpg 1440w,
/static/af6c13be5855124aa1e36e60c6164c3c/0f98f/preparing-interviews-for-software-engineer-position.jpg 1920w,
/static/af6c13be5855124aa1e36e60c6164c3c/93719/preparing-interviews-for-software-engineer-position.jpg 4000w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/jpeg&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/af6c13be5855124aa1e36e60c6164c3c/6a068/preparing-interviews-for-software-engineer-position.jpg&quot;
            alt=&quot;Interview Preparation&quot;
            title=&quot;Interview Preparation&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Last week I’ve just &lt;strong&gt;finished two recruitment processes for a Senior Software
Engineer position&lt;/strong&gt; that I have applied. Both companies have a very well organized
recruitment process, consisting in several interviews, including technical ones
with code challenges.&lt;/p&gt;
&lt;p&gt;I got an offer in both cases. Unfortunately I had to decline one of them, and I
can tell you that it was a really hard decision, because both were presenting me
exciting and interesting challenges (engineeringly speaking). I wish I could
multiply myself to accept both offers (I would have loved to live both
experiences). But that’s life. &lt;strong&gt;And Yes, I am about to start a new journey. New
Year, New Life&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;In this post I want to &lt;strong&gt;describe how I have prepared for the interviews and give
some tips&lt;/strong&gt; to someone thinking to apply to a similar position. &lt;strong&gt;IMHO,
preparation is the key to succeed&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;be-ready-to-write-code-in-an-interview&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#be-ready-to-write-code-in-an-interview&quot; aria-label=&quot;be ready to write code in an interview permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Be ready to write code in an interview&lt;/h2&gt;
&lt;p&gt;The obvious - if we are applying for a software engineer position, &lt;strong&gt;we need to
be ready to be asked to write code during interviews&lt;/strong&gt;. I know that some
companies do not ask to write code in interviews, they assign you a homework
task instead. It’s arguable which one is better.&lt;/p&gt;
&lt;p&gt;In my case, in both processes I had to write code (C# and SQL). Furthermore, one
of the companies was  using a hiring platform,
&lt;a href=&quot;https://www.codility.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Codility&lt;/a&gt;, in which you need to write real working
code (compiled, tested against test data, etc.), not just pseudo-code on paper.&lt;/p&gt;
&lt;p&gt;The thing is, if you write code on a daily basis, writing code is not an
issue, right? &lt;strong&gt;The problem here is the type of problems that they are throwing
you in the exercises, particularly those that you don’t deal with for some
time&lt;/strong&gt;. They tend to like exercises about:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Arrays challenges&lt;/li&gt;
&lt;li&gt;Algorithms and data structures&lt;/li&gt;
&lt;li&gt;SQL&lt;/li&gt;
&lt;li&gt;Object oriented principles and design patterns&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let’s see what kind of preparation we can think of to improve our ability to
solve these problems.&lt;/p&gt;
&lt;h2 id=&quot;practicing-codesql-challenges&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#practicing-codesql-challenges&quot; aria-label=&quot;practicing codesql challenges permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Practicing Code/SQL challenges&lt;/h2&gt;
&lt;p&gt;There are some  &lt;strong&gt;platforms out there where we can practice code/sql
challenges&lt;/strong&gt;. Here are some examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://codility.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Codility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.hackerrank.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;HackerRank&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://leetcode.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;LeetCode&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of them have great exercises. Regarding difficulty level, &lt;strong&gt;I would suggest
to focus on the Easy and Medium level&lt;/strong&gt;. You can choose the language of your
choice to solve the exercise.&lt;/p&gt;
&lt;p&gt;Codility and HackerRank are hiring platforms, but they have a lot of training
content for developers. In Codility, the platform that I used most, I would
suggest the 10 first lessons in the section Codility for Programmers. HackerRank
is very thorough, and you can choose the skills you want to practice.&lt;/p&gt;
&lt;p&gt;And if we struggle in a given exercise, we can have some help from the community
using those platforms. It happened sometimes, where I wasn’t tackling the
problem in the right direction.&lt;/p&gt;
&lt;h2 id=&quot;big-o-algorithms-and-data-structures&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#big-o-algorithms-and-data-structures&quot; aria-label=&quot;big o algorithms and data structures permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Big-O, Algorithms and Data Structures&lt;/h2&gt;
&lt;p&gt;This is another topic that engineering interviewers like to discuss or see it in
action.&lt;/p&gt;
&lt;p&gt;Today, when we need to sort some data, we typically rely on an implementation
provided by a base class library. So, if someone asks us out of the blue, what
is the difference between a bubble sort and merge sort, unless we have a great
memory or deal with this on a daily basis, probably we won’t answer immediately.&lt;/p&gt;
&lt;p&gt;But there are some theory that we should know for sure. One of them is the
&lt;a href=&quot;https://en.wikipedia.org/wiki/Big_O_notation&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Big O notation&lt;/strong&gt;&lt;/a&gt; (asymptotic
analysis). And here, more important than to know what it is, it is &lt;strong&gt;to
recognize quickly the approx. time complexity of a given algorithm&lt;/strong&gt;: constant,
logarithmic, linear, quadratic, etc.&lt;/p&gt;
&lt;p&gt;So, even if we don’t remember the bubble sort algorithm, as soon as we see its
implementation we should recognize a quadratic time complexity. Besides sorting,
searching algorithms is also important to be aware of, since they are somehow
related (we can adopt different searching approaches if the data is already
sorted).&lt;/p&gt;
&lt;p&gt;A long time ago, I’ve read somewhere a saying: &lt;strong&gt;&lt;em&gt;“Make it run, make it right,
make it fast”&lt;/em&gt;&lt;/strong&gt;. I can’t remember the source, but I can say that I really like
this approach. So, when the interviewer asks you to solve an exercise, &lt;strong&gt;focus
first on the simplest solution&lt;/strong&gt;, and do not worry about performance. As soon as
you finish your first solution, try to identify its time complexity, and &lt;strong&gt;if
you have time you can start to identify possible improvements&lt;/strong&gt; (unnecessary
work, common cases. etc.). In the coding platforms that I mentioned earlier, we
got a score based on the tests results. Sometimes the solution is
correct, but we don’t get 100% score because we are not fast enough, and some
tests timeout.&lt;/p&gt;
&lt;p&gt;For data structures, I think the important is to know &lt;strong&gt;what data structure should
be used for a given scenario/exercise&lt;/strong&gt;. When facing an exercise we should try
to identify which data structure, or combination of data structures, best suits
the given problem:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Array&lt;/li&gt;
&lt;li&gt;Linked List&lt;/li&gt;
&lt;li&gt;Queue (FIFO - First in First Out)&lt;/li&gt;
&lt;li&gt;Stack (LIFO - Last in First Out)&lt;/li&gt;
&lt;li&gt;Hash table&lt;/li&gt;
&lt;li&gt;Binary Search Tree&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To know what is the best &lt;strong&gt;data structure to use, we need to know the time
complexity of each of its operation&lt;/strong&gt;, such as adding/removing elements, search
by position, search by key, etc.&lt;/p&gt;
&lt;p&gt;In my case, I reviewed all these concepts by taking a &lt;a href=&quot;https://www.pluralsight.com/courses/algorithms-data-structures-part-one&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;course on
Pluralsight&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;object-oriented-and-design-patterns&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#object-oriented-and-design-patterns&quot; aria-label=&quot;object oriented and design patterns permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Object Oriented and Design Patterns&lt;/h2&gt;
&lt;p&gt;Another topic that interviewers like to ask is about &lt;strong&gt;Object Oriented
Principles and Design Patterns&lt;/strong&gt;. And here we can expect several type of
interviewers: some of them asks you to explain the &lt;a href=&quot;https://en.wikipedia.org/wiki/SOLID&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;SOLID
principles&lt;/a&gt;; others that ask you to
write, for example a singleton pattern; and others that will present you a real
problem to see if you use principles and patterns in a natural way. I think this
later approach is the one that makes more sense, and in my case it happened
exactly that. I was asked to design a system where these topics started to popup
naturally. (interfaces, polymorphism, composite pattern, strategy pattern, etc.)&lt;/p&gt;
&lt;p&gt;Again, if you use these principles on a daily basis, this should not be a
problem. Even some design patterns are so embedded in our daily work that we don’t
even notice that we are using them. Nevertheless I decided to review these
topics, just in case someone could ask me about them in more detail.&lt;/p&gt;
&lt;p&gt;Instead of reading the gang of four book, &lt;a href=&quot;https://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional-ebook/dp/B000SEIBB8&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Design Patterns: Elements of Reusable
Object-Oriented
Software&lt;/a&gt;,
I decided to review just the most used patterns by reading the new edition of
&lt;a href=&quot;https://www.amazon.com/Head-First-Design-Patterns-Object-Oriented/dp/149207800X&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Head First Design
Patterns&lt;/a&gt;,
which I really enjoyed. The Head First series books provides a great way of learning.&lt;/p&gt;
&lt;h2 id=&quot;be-ready-to-brainstorm-about-real-problems&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#be-ready-to-brainstorm-about-real-problems&quot; aria-label=&quot;be ready to brainstorm about real problems permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Be ready to brainstorm about real problems&lt;/h2&gt;
&lt;p&gt;These are the questions that I like most, and in fact I was expecting more of
these. Basically &lt;strong&gt;the interviewers present you a real problem&lt;/strong&gt;. Typically you
don’t need to write any code. They are just ask you to present a high level
solution, discussing alternatives, pros and cons, etc. &lt;strong&gt;They want to know how
you think&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For example, &lt;em&gt;“the product owner wants a new feature of auto-completing a
search, providing multiple matches to the user, based on user past behavior.
Let’s start thinking about the problem”&lt;/em&gt;. That’s the type of questions you
should expect.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IMHO, this is the most interesting type of questions&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;be-ready-to-be-asked-about-past-projects&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#be-ready-to-be-asked-about-past-projects&quot; aria-label=&quot;be ready to be asked about past projects permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Be ready to be asked about past projects&lt;/h2&gt;
&lt;p&gt;Another common set of questions is &lt;strong&gt;questions about past projects that are
mentioned in your CV&lt;/strong&gt;. My suggestion is to revisit your CV and try to remember
some options you have chosen, the design and architecture adopted, etc. If some
detail is missing in your head, go read some documentation that you still have
about the project.&lt;/p&gt;
&lt;p&gt;Typically, &lt;strong&gt;the projects that are discussed in interviews are chosen by you&lt;/strong&gt;,
not by the interviewer. So, be wise when choosing your projects to be discussed.&lt;/p&gt;
&lt;p&gt;There are a lot of topics that can arise during these questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DevOps general questions&lt;/strong&gt;: how you build? how you deploy? What flow you
use? CI/CD?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Testing approaches&lt;/strong&gt; (unit tests, integration tests, e2e test, load tests)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Observability&lt;/strong&gt;: how do you know what’s happening in production? Telemetry,
traces, logs, etc.?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Distributed systems&lt;/strong&gt;: pub/sub systems? queuing systems? retries? circuit
breakers and other patterns, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The variety of questions here is endless, and basically is based on your
experience.&lt;/p&gt;
&lt;h2 id=&quot;know-about-the-interviewer-as-much-as-possible&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#know-about-the-interviewer-as-much-as-possible&quot; aria-label=&quot;know about the interviewer as much as possible permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Know about the interviewer as much as possible&lt;/h2&gt;
&lt;p&gt;As I said earlier, &lt;strong&gt;preparation is the key to success&lt;/strong&gt;. In an interview
process, part of the preparation is to know the interviewer. Most of the
companies announce who will be your interviewer. Take advantage of that
information and try to know as much as possible about that person via LinkedIn,
blog, presentations, etc.&lt;/p&gt;
&lt;p&gt;If we think carefully, &lt;strong&gt;interviewing is like dating&lt;/strong&gt;. Basically both parties
are trying to understand how compatible they are, right? If you know who is
interviewing you, you can pick common topics that you and your interviewer
relates to.&lt;/p&gt;
&lt;p&gt;This &lt;em&gt;“investigation”&lt;/em&gt; can be very time consuming. Let me give you an example. For
the preparation of one of my interviews, I found a presentation made by the
interviewer. During that presentation he mentioned that he practices martial
arts. Great, I thought, I also practice martial arts (Taekwondo and Hapkido). So
we have something in common. At some point in the interview I asked
him what martial art did he practice, and we have spent a few minutes on this
topic. It’s all about &lt;strong&gt;Rapport - connecting through shared interests and empathy&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For another interview, I’ve skimmed the master thesis of the interviewer about
Aspects Oriented Programming. I also read his blog. Again, some blog posts were
mentioned during the interview. We can create connections easier if we know
better who is talking to us.&lt;/p&gt;
&lt;h2 id=&quot;soft-skills&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#soft-skills&quot; aria-label=&quot;soft skills permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Soft skills&lt;/h2&gt;
&lt;p&gt;I am sure that there are a lot of other suggestions to excel in an interview. My
focus on this post was mainly in the Software Engineering field. I didn’t want
to focus too much in the soft skills. I think the only suggestion that I have
regarding soft skills is: &lt;strong&gt;be yourself and respect your identity&lt;/strong&gt;. Don’t
pretend to be someone who you aren’t.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;As a conclusion, I just want to mention that  a recruitment process is time
consuming for a candidate. &lt;strong&gt;I spent many hours preparing my interviews&lt;/strong&gt;, and I
don’t have any problem assuming that. Probably there are some people that don’t
need any kind of preparation. Not me.&lt;/p&gt;
&lt;p&gt;In this post I just wanted to describe how I prepared myself for the interviews.
It worked for me. It doesn’t mean it will work for you.&lt;/p&gt;
&lt;p&gt;Finally I want to finish this post by mentioning two resources:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;the book &lt;a href=&quot;https://www.crackingthecodinginterview.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Cracking the Coding
Interview&lt;/strong&gt;&lt;/a&gt;. I didn’t read the
book so I can’t recommend it. The reviews are great. I only heard about the
book after my technical interviews. What I can say is that, if I knew it
before, I would have read it before applying to those positions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;the site &lt;a href=&quot;https://www.glassdoor.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&lt;strong&gt;Glassdoor&lt;/strong&gt;&lt;/a&gt;. Before applying to a
position, search for interviews reviews on this site to have an idea what you
should expect, how long does it take, how many interviews, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</content:encoded></item><item><title><![CDATA[DDD is fancy - Are we doing it right? Should we use it?]]></title><description><![CDATA[This post is a reflection about Domain Driven Design (DDD).]]></description><link>https://bfcamara.com/posts/ddd-is-fancy-are-we-doing-it-right/</link><guid isPermaLink="false">https://bfcamara.com/posts/ddd-is-fancy-are-we-doing-it-right/</guid><pubDate>Fri, 23 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/065c172ace2ad4616ba1fd519dc0023a/93719/DDD_Praise_from_Eric_Evans_Book.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAgMA/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAH/2gAMAwEAAhADEAAAAbuTiGWP/8QAGRAAAwADAAAAAAAAAAAAAAAAAAECERIx/9oACAEBAAEFAo5hFQm1RsOz/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFhAAAwAAAAAAAAAAAAAAAAAAACAx/9oACAEBAAY/AiL/AP/EABkQAQEBAAMAAAAAAAAAAAAAAAEAEUFRcf/aAAgBAQABPyEATOJSbnLovUG3/9oADAMBAAIAAwAAABAvL//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EAB0QAQABAwUAAAAAAAAAAAAAAAEAESFBMVGBkaH/2gAIAQEAAT8QSzaDaZB0SvBbQgBYlpfxCaq8T//Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/065c172ace2ad4616ba1fd519dc0023a/8ac56/DDD_Praise_from_Eric_Evans_Book.webp 240w,
/static/065c172ace2ad4616ba1fd519dc0023a/d3be9/DDD_Praise_from_Eric_Evans_Book.webp 480w,
/static/065c172ace2ad4616ba1fd519dc0023a/e46b2/DDD_Praise_from_Eric_Evans_Book.webp 960w,
/static/065c172ace2ad4616ba1fd519dc0023a/f992d/DDD_Praise_from_Eric_Evans_Book.webp 1440w,
/static/065c172ace2ad4616ba1fd519dc0023a/882b9/DDD_Praise_from_Eric_Evans_Book.webp 1920w,
/static/065c172ace2ad4616ba1fd519dc0023a/c67aa/DDD_Praise_from_Eric_Evans_Book.webp 4000w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/065c172ace2ad4616ba1fd519dc0023a/09b79/DDD_Praise_from_Eric_Evans_Book.jpg 240w,
/static/065c172ace2ad4616ba1fd519dc0023a/7cc5e/DDD_Praise_from_Eric_Evans_Book.jpg 480w,
/static/065c172ace2ad4616ba1fd519dc0023a/6a068/DDD_Praise_from_Eric_Evans_Book.jpg 960w,
/static/065c172ace2ad4616ba1fd519dc0023a/644c5/DDD_Praise_from_Eric_Evans_Book.jpg 1440w,
/static/065c172ace2ad4616ba1fd519dc0023a/0f98f/DDD_Praise_from_Eric_Evans_Book.jpg 1920w,
/static/065c172ace2ad4616ba1fd519dc0023a/93719/DDD_Praise_from_Eric_Evans_Book.jpg 4000w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/jpeg&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/065c172ace2ad4616ba1fd519dc0023a/6a068/DDD_Praise_from_Eric_Evans_Book.jpg&quot;
            alt=&quot;Domain Driven Design&quot;
            title=&quot;Domain Driven Design&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; - This post is just a reflection about DDD based on my experience,
and my goal is to reflect about some questions: &lt;strong&gt;are we doing DDD right? is it
worth?&lt;/strong&gt; I am far from being an expert in Domain Driven Design (DDD). So, you
should skip the entire post if you expect some words from a DDD expert
practitioner.&lt;/p&gt;
&lt;h2 id=&quot;how-are-we-doing-ddd&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#how-are-we-doing-ddd&quot; aria-label=&quot;how are we doing ddd permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;How are we doing DDD&lt;/h2&gt;
&lt;p&gt;If someone says “My team uses DDD”, that person gets my full attention.
Basically I enter in a mode where I can do only two things: to breathe and to get
more info from the person in front of me to know more about how they are doing
DDD.&lt;/p&gt;
&lt;p&gt;Basically, I will get a lot of curiosity to know more about the project, and
particularly to know &lt;strong&gt;how complex the project is, and what is the layered
architecture being adopted&lt;/strong&gt;. In my opinion, I think it’s dam hard to do DDD
right (whatever that means). Furthermore, I will always ask if I can take a look
at the code to see &lt;strong&gt;what DDD concepts are being used&lt;/strong&gt; (entities, value
objects, aggregate roots, repositories, unit of work, etc.), and &lt;strong&gt;what software
architecture/patterns are in place&lt;/strong&gt; (Hexagonal Architecture, Onion
Architecture, CQRS, Event Sourcing, etc.). My hope is always to get something
new that I can learn from it, or something new that I can say &lt;em&gt;“this makes a lot
of sense and I’ve never though about it. I need to try for myself”&lt;/em&gt;. &lt;strong&gt;Keep
learning is always the goal&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;keep-studying-ddd&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#keep-studying-ddd&quot; aria-label=&quot;keep studying ddd permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Keep studying DDD&lt;/h2&gt;
&lt;p&gt;I think it was around 2005 when I read the Eric Evan’s &lt;strong&gt;book &lt;a href=&quot;https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;“Domain Driven Design: Tackling
Complexity in the Heart of
Software”&lt;/a&gt;,
and I can say that it was very hard to digest it&lt;/strong&gt;. By that time, my
feeling was that there were missing good samples to serve as base reference
implementation. It started to appear then some samples in the community, but I never
got 100% happy with a single one, where I could say &lt;em&gt;“That is the one”&lt;/em&gt;. Even
today, from time to time, I &lt;strong&gt;still search for new DDD samples to see how they
are tackling software complexity&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Fortunately, we have more samples today that we can learn from, at least the
tactical aspects of a DDD implementation. I say tactical, because regarding the
domain knowledge we don’t have access to the decisions that were made that have
conducted to the given model. And that’s where &lt;strong&gt;I think we (as developers) are
missing one of the most important points of Domain Driven Design: the Ubiquitous
Language&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;the-ubiquitous-language&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#the-ubiquitous-language&quot; aria-label=&quot;the ubiquitous language permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;The Ubiquitous Language&lt;/h2&gt;
&lt;p&gt;I don’t know why, but &lt;strong&gt;we (as developers), tend to think that we know more of a
given domain than the domain expert itself&lt;/strong&gt;. It doesn’t make any sense - but we
still do it a lot. That’s why there is a &lt;strong&gt;gap in the communication between the domain
experts and the technical team members&lt;/strong&gt;. We tend to build something that
follows our mental model based on our own technical language, and not based on the domain
expert language. &lt;strong&gt;We should build based on the Ubiquitous Language&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Unless we are building software that targets developers itself, &lt;strong&gt;we are not the
domain experts&lt;/strong&gt;. So we should listen them first, ask them questions to make
them think deeper about the subject, and then &lt;strong&gt;agree with them on a common
vocabulary and model&lt;/strong&gt; that is understood by all team members in the project.
That’s the model that we should build in software. That’s why I think that &lt;strong&gt;it
makes a lot of sense to have a domain expert as a member of the team. If not,
are we really doing DDD? And if we don’t need a domain expert on the team, are
we really tackling a complex domain that justifies a DDD investment?&lt;/strong&gt; Probably
not.&lt;/p&gt;
&lt;h2 id=&quot;technical-complexity&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#technical-complexity&quot; aria-label=&quot;technical complexity permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Technical complexity&lt;/h2&gt;
&lt;p&gt;If we are not tackling a complex domain, I think we should focus in not adding
technical complexity - &lt;strong&gt;instead we should chase for simplicity, technically
speaking&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For example, we are asked to &lt;strong&gt;build a simple CRUD application&lt;/strong&gt; - a small
backofice web app to manage some reference data. Why should we add technical
complexity to this simple app? &lt;strong&gt;Probably we can get most of the job done by using
a scaffolding tool&lt;/strong&gt;, combined with a validation, authorization, and auditing
mechanism and we are good to go, right? &lt;strong&gt;Is there anything wrong with this
approach?&lt;/strong&gt; I don’t think so.&lt;/p&gt;
&lt;p&gt;Now, imagine that we are developing &lt;strong&gt;a core domain backend service to be
consumed by a frontend&lt;/strong&gt; (a &lt;a href=&quot;https://samnewman.io/patterns/architectural/bff/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;BFF&lt;/a&gt;-Backend for
Frontend). This &lt;strong&gt;core domain
is the one that generates money for the company and it’s relatively complex, and
it’s evolving quickly&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;We &lt;strong&gt;decide to use &lt;a href=&quot;https://graphql.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;GraphQL&lt;/a&gt; to expose our API&lt;/strong&gt; to be
consumed by the frontend, which is mostly a &lt;strong&gt;Task based UI&lt;/strong&gt;. Since we are
using GraphQL, we can think that it makes sense to use internally different
approaches for queries and mutations, and so &lt;strong&gt;we decide to implement a
&lt;a href=&quot;https://www.martinfowler.com/bliki/CQRS.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;CQRS&lt;/a&gt; pattern&lt;/strong&gt; (Command Query
Responsibility Segregation). &lt;strong&gt;For the Commands, the rules are complex, and so
we decide to adopt a Domain Model approach&lt;/strong&gt;, with persistence ignorance,
repositories, triggering domain events (potentially to be consumed by other
services), etc. But for the &lt;strong&gt;Queries we decide to use a simpler approach by
using a Micro-ORM with an Anemic Read Model&lt;/strong&gt; (or DTOs if you prefer).
Initially, we can even decide that both Queries and Commands are using the same
physical database, but we can change that in the future if we need it, by
physically isolating the read and write persistence model. &lt;strong&gt;Is there anything
wrong by mixing these approaches?&lt;/strong&gt; I don’t think so. Are we really using DDD?
Probably &lt;strong&gt;we are only using some DDD tactical patterns in parts of our
system&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;dont-need-to-be-ddd-all-in&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#dont-need-to-be-ddd-all-in&quot; aria-label=&quot;dont need to be ddd all in permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Don’t need to be “DDD All-In”&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;I think DDD is not an All or Nothing approach&lt;/strong&gt;. We can use a &lt;strong&gt;DDD-Lite&lt;/strong&gt; (term
coined by Vaughn Vernon in his book &lt;a href=&quot;https://www.amazon.com/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/0321834577&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Implementing Domain-Driven
Design&lt;/a&gt;)
by &lt;strong&gt;choosing just some DDD tactical patterns for parts of our system&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I think also that DDD is not for all projects&lt;/strong&gt;. We all like to put in
practice what we learn, and we all want to become better developers writing
better software today than we wrote yesterday. &lt;strong&gt;DDD is something that I think
every developer should learn in the course of his career. But more important is
to get the capability to decide when it’s worth or not to use DDD in a
project&lt;/strong&gt;. If we decide to adopt DDD blindly, regardless of the complexity of
the domain, just because we are proud of our brilliant code with lots of
patterns, I think it’s a wrong approach. &lt;strong&gt;At the end of the day we are hired to build
software that is supposed to add value to the business&lt;/strong&gt;. And with this blind
approach, we are just throwing technical complexity to the solution, which
becomes a cost.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;To conclude, I think &lt;strong&gt;we should keep learning DDD, to be able to apply it when it
worths, and no less important also, to be able to know when it doesn’t worth&lt;/strong&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[The Fear of Public Speaking]]></title><description><![CDATA[This post is a reflection about the Fear of Public Speaking. 😨]]></description><link>https://bfcamara.com/posts/fear-of-public-speaking/</link><guid isPermaLink="false">https://bfcamara.com/posts/fear-of-public-speaking/</guid><pubDate>Tue, 06 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/159b1f36204cafa9a8120cc306ed46d2/93719/talk_like_ted.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAQFAv/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAFWrL0LDBH/xAAbEAEAAgIDAAAAAAAAAAAAAAABAAIDERIUMf/aAAgBAQABBQJrp40j7bMtezWGdD//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAZEAACAwEAAAAAAAAAAAAAAAAAARARITL/2gAIAQEABj8CWnMaXQkf/8QAGhAAAwEBAQEAAAAAAAAAAAAAAAERITFBcf/aAAgBAQABPyFeQ98HOQRW+mMLRs6X6KouI//aAAwDAQACAAMAAAAQtx//xAAXEQADAQAAAAAAAAAAAAAAAAAAARFh/9oACAEDAQE/EGoTT//EABcRAAMBAAAAAAAAAAAAAAAAAAABEWH/2gAIAQIBAT8QTpcP/8QAHRABAAICAgMAAAAAAAAAAAAAAQARITFB4VFhcf/aAAgBAQABPxCmzIEWZwtqqmlFWq2Vsrk0az1PBNx6fIbBAN9T/9k=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/159b1f36204cafa9a8120cc306ed46d2/8ac56/talk_like_ted.webp 240w,
/static/159b1f36204cafa9a8120cc306ed46d2/d3be9/talk_like_ted.webp 480w,
/static/159b1f36204cafa9a8120cc306ed46d2/e46b2/talk_like_ted.webp 960w,
/static/159b1f36204cafa9a8120cc306ed46d2/f992d/talk_like_ted.webp 1440w,
/static/159b1f36204cafa9a8120cc306ed46d2/882b9/talk_like_ted.webp 1920w,
/static/159b1f36204cafa9a8120cc306ed46d2/c67aa/talk_like_ted.webp 4000w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/159b1f36204cafa9a8120cc306ed46d2/09b79/talk_like_ted.jpg 240w,
/static/159b1f36204cafa9a8120cc306ed46d2/7cc5e/talk_like_ted.jpg 480w,
/static/159b1f36204cafa9a8120cc306ed46d2/6a068/talk_like_ted.jpg 960w,
/static/159b1f36204cafa9a8120cc306ed46d2/644c5/talk_like_ted.jpg 1440w,
/static/159b1f36204cafa9a8120cc306ed46d2/0f98f/talk_like_ted.jpg 1920w,
/static/159b1f36204cafa9a8120cc306ed46d2/93719/talk_like_ted.jpg 4000w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/jpeg&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/159b1f36204cafa9a8120cc306ed46d2/6a068/talk_like_ted.jpg&quot;
            alt=&quot;Talk like TED&quot;
            title=&quot;Talk like TED&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Public Speaking&lt;/strong&gt; - it’s one of my fears. But I think I am not alone, and
according to some studies, &lt;strong&gt;it’s a very common fear&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I don’t know exactly the reasons that cause us &lt;strong&gt;to be terrified 😨 when we need
to speak in public&lt;/strong&gt; or to an audience - probably there are &lt;strong&gt;social or
psychological reasons, or even physiological&lt;/strong&gt;, I don’t know. But I do know how
I feel when facing an audience: &lt;strong&gt;anxious, nervous, my heart starts beating
faster, I start sweating&lt;/strong&gt;, etc. Typically these feelings have its peak few minutes
before the presentation. But then, a few minutes after the presentation starts,
everything returns to a normal state, unless there are some issues with the
presentation itself, like a laptop crash, or the projector is broken, or
anything else that doesn’t follow the plan, and in that case a lot of stress arises.
The root causes for these feelings might be: &lt;strong&gt;fear to fail publicly, fear to
be negativelly commented, fear to be vulnerable, fear to be judged, fear to not
know the answer&lt;/strong&gt;, etc. Today, &lt;strong&gt;if someone is on a stage, that person deserves my
empathy and my respect - that person is facing these fears fighting them in
the Arena&lt;/strong&gt; (I really like the term &lt;em&gt;Arena&lt;/em&gt;, which I heard in the book &lt;a href=&quot;https://www.amazon.com/gp/product/B00APRW2WC/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Daring
Greatly&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In 2005&lt;/strong&gt; I was invited to be a speaker in TechDays Portugal, an event
sponsored by Microsoft, &lt;strong&gt;to present a session about the &lt;a href=&quot;https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Fallacies of
Distributed
Computing&lt;/a&gt;&lt;/strong&gt;.
I presented the session with a friend and colleague (fortunately I was not alone
on the stage) and we decided to present it in a different way: &lt;strong&gt;we presented as
a parody between two characters&lt;/strong&gt;. One of the characters was the Teacher, the
&lt;strong&gt;“Software Architect”&lt;/strong&gt;, the reasonable, the prudent, and the experienced
professional; and the other character was the Student, the &lt;strong&gt;“Cowboy Coder”&lt;/strong&gt;,
the developer who thinks is the best in the world and solves everything with a
few lines of code. Sounds familiar 🤠? The whole session was presented as a
conflict between these 2 characters, with a lot of drama. &lt;strong&gt;Guess what character
I played:…The fu#$#%&amp;#x26;&amp;#x26; Cowboy&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Since this session in 2005 got some positive feedback, we were invited again
&lt;strong&gt;in 2007&lt;/strong&gt; to the same event. This time we did &lt;strong&gt;two sessions&lt;/strong&gt;: one about
&lt;strong&gt;Visual Studio Team Systems and Agile Methodologies&lt;/strong&gt; (XP, Scrum, etc.), which
can be partially watched &lt;a href=&quot;https://youtu.be/9a45oS1AEBk&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;here&lt;/a&gt;; and the other was
the continuation of the session of 2005 with the title &lt;strong&gt;“The anxieties of an
architect”&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For this session we decided to use the same recipe, &lt;strong&gt;but now the “Cowboy Coder”
became the “Architect Wannabe”, and the Professor was now the Doctor or the
Psychologist&lt;/strong&gt;. Basically the goal of the session was to discuss some questions
of that time, such as “XML vs JSON”, or “REST vs WS-*”, “ORM or not ORM”, etc.,
that were the anxieties of the Architect Wannabe. &lt;strong&gt;This time, I played the role
of the “Architect wannabe”&lt;/strong&gt;, and the whole session was designed to be pretended
as a psychoanalysis session - &lt;strong&gt;I was the whole session laid down in a chaise
long, so vulnerable&lt;/strong&gt; 🛏️. OMG, what have I done? Recently, I found the
recording of this session, but I refuse to embed it here in the blog post itself
😄, but you can still watch it &lt;a href=&quot;https://youtu.be/OugyYA8lYHI&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;here&lt;/a&gt;. As far as I
remember, the feedback was better in 2005 than in 2007.&lt;/p&gt;
&lt;p&gt;My feeling in general is, every time I watch a video of me speaking to an
audience, I typically &lt;strong&gt;only see the negative points: I think my voice is not
good, I think I have the wrong posture, typically my jokes don’t work, etc.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Since then I stayed away of &lt;em&gt;“the stage spotlights”&lt;/em&gt;. &lt;strong&gt;This year 2020, last
February&lt;/strong&gt;, I was invited to &lt;strong&gt;teach a class of Database Management Systems&lt;/strong&gt; in
the School of Business Administration at the Polytechnic Institute of Setúbal,
Portugal. This class belongs to the study plan of the 1st cycle college course
of IT Systems Management. &lt;strong&gt;My role was limited to help students solving problems
at the labs, by putting in practice what they were being taught in theory&lt;/strong&gt;.
Basically we are talking about SQL problems, writing a lot of queries, something
that I am completely comfortable with.&lt;/p&gt;
&lt;p&gt;But then it came the pandemic, and we were all confined to our homes, and &lt;strong&gt;most
of the sessions were presented online via Microsoft Teams&lt;/strong&gt;, which is not the same
thing as being physically in the classroom. &lt;strong&gt;I felt that the level of stress when
doing online sessions is much lower&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;But since I am going to continue to teach at the same institute, I decided to
invest sometime to know and understand &lt;strong&gt;how to be a better communicator, and
how to improve the connection with your audience&lt;/strong&gt;. I started &lt;strong&gt;watching great
speakers and revisiting great presentations. We can find them on
&lt;a href=&quot;https://ted.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;TED&lt;/a&gt;&lt;/strong&gt; - go to the list of &lt;a href=&quot;https://www.ted.com/talks&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;TED
talks&lt;/a&gt; and sort presentations by most viewed and we
are all presented with excellent speakers and inspiring talks. I confess that I envy
them, because they are really great and every talk is absolutely inspiring. &lt;strong&gt;I
am aware that giving a TED talk is entirely different than teaching a class, but
I thought that I could gather something from these TED speakers&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I’ve &lt;strong&gt;read the book &lt;a href=&quot;https://www.amazon.com/Talk-Like-TED-Public-Speaking-Secrets/dp/1250041120&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Talk like
TED&lt;/a&gt;&lt;/strong&gt;.
The author, &lt;a href=&quot;https://www.amazon.com/Carmine-Gallo/e/B001IGUTPG&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Carmine Gallo&lt;/a&gt;,
studied hundreds of TED Talks and compiled what they have in common
in order to be a great presenter. The author presents the &lt;strong&gt;9 public-speaking
secrets&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Passion&lt;/strong&gt; - be passionate about your topic&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;StoryTelling&lt;/strong&gt; - tell stories. We tend to pay attention to stories.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Have a conversation&lt;/strong&gt; - deliver your talk as a conversation with a close
friend. Be natural.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Teach something new&lt;/strong&gt; - present something new to your audience. It can be new
information, or just presented in a different and novel way.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Have Jaw-Dropping Moments&lt;/strong&gt; - deliver shocking, impressive or surprising
moments.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Lighten Up&lt;/strong&gt; - deliver some humor, and don’t take too seriously&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;18-Minute Rule&lt;/strong&gt; - keep your presentation length approx. 18 minutes&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Multisensory experiences&lt;/strong&gt; - incorporate several senses in your
presentation (sight, sound, touch, smell, and taste)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Be authentic&lt;/strong&gt; - most people can spot a phony.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I enjoyed reading the book and I strongly recommend it to everyone that wants
improve their communication skills. I’ve also annotated each TED talk
referenced in the book and I am watching them to observe the
subtleties of the speaker.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I would say that is hard do design a presentation with all the secrets in the
list, but I will definitely consider them on my next class or talk.&lt;/strong&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Excluding jobs from Succeeded Jobs in Hangfire Dashboard]]></title><description><![CDATA[This post shows how to exclude some jobs from the Succeeded in Hangfire Dashboard, even if they succeed.]]></description><link>https://bfcamara.com/posts/hide-succeeded-jobs-in-hangfire-dashboard/</link><guid isPermaLink="false">https://bfcamara.com/posts/hide-succeeded-jobs-in-hangfire-dashboard/</guid><pubDate>Wed, 30 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/51f44a123400cdefa97335da3dc4d875/93719/vs_hangfire_photo.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAQFA//EABYBAQEBAAAAAAAAAAAAAAAAAAABAv/aAAwDAQACEAMQAAABl0kNxwWMX//EABoQAAIDAQEAAAAAAAAAAAAAAAADAQIRBBL/2gAIAQEAAQUCOSIta66+tEthZLtP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAGhAAAgIDAAAAAAAAAAAAAAAAABEBAhAyUf/aAAgBAQAGPwIs+GsYsxo//8QAGhAAAwADAQAAAAAAAAAAAAAAAAERITFhcf/aAAgBAQABPyHRFKfQmwaFFhUMeMfT/9oADAMBAAIAAwAAABCTP//EABYRAQEBAAAAAAAAAAAAAAAAAAABEf/aAAgBAwEBPxCMf//EABYRAAMAAAAAAAAAAAAAAAAAAAABIf/aAAgBAgEBPxBqFP/EABoQAQEBAQEBAQAAAAAAAAAAAAERACGBMUH/2gAIAQEAAT8QL+nTJTkF7TBkfMjhB8zCmIIW91i1fFBv/9k=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/51f44a123400cdefa97335da3dc4d875/8ac56/vs_hangfire_photo.webp 240w,
/static/51f44a123400cdefa97335da3dc4d875/d3be9/vs_hangfire_photo.webp 480w,
/static/51f44a123400cdefa97335da3dc4d875/e46b2/vs_hangfire_photo.webp 960w,
/static/51f44a123400cdefa97335da3dc4d875/f992d/vs_hangfire_photo.webp 1440w,
/static/51f44a123400cdefa97335da3dc4d875/882b9/vs_hangfire_photo.webp 1920w,
/static/51f44a123400cdefa97335da3dc4d875/c67aa/vs_hangfire_photo.webp 4000w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/51f44a123400cdefa97335da3dc4d875/09b79/vs_hangfire_photo.jpg 240w,
/static/51f44a123400cdefa97335da3dc4d875/7cc5e/vs_hangfire_photo.jpg 480w,
/static/51f44a123400cdefa97335da3dc4d875/6a068/vs_hangfire_photo.jpg 960w,
/static/51f44a123400cdefa97335da3dc4d875/644c5/vs_hangfire_photo.jpg 1440w,
/static/51f44a123400cdefa97335da3dc4d875/0f98f/vs_hangfire_photo.jpg 1920w,
/static/51f44a123400cdefa97335da3dc4d875/93719/vs_hangfire_photo.jpg 4000w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/jpeg&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/51f44a123400cdefa97335da3dc4d875/6a068/vs_hangfire_photo.jpg&quot;
            alt=&quot;Hangfire&quot;
            title=&quot;Hangfire&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; - If you want to to hide some succeeded jobs from the Hangfire
Dashboard, you can do it by forcing them to be deleted as soon as they succeed,
and you can use a job filter for that purpose.&lt;/p&gt;
&lt;p&gt;Many applications need some &lt;strong&gt;background processing&lt;/strong&gt;, for example,  sending
thousands of campaign emails. One common scenario is to trigger these background
processing tasks in a schedule, for example, &lt;em&gt;“send campaign emails every night
at 1 am”&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;In the .Net world we have several tools and libraries at our disposal to perform
this kind of scheduled background processing. For example, we have
&lt;a href=&quot;https://www.quartz-scheduler.net/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Quartz.Net&lt;/a&gt;,
&lt;a href=&quot;https://docs.coravel.net/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Coravel&lt;/a&gt;, &lt;a href=&quot;https://www.hangfire.io/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Hangfire&lt;/a&gt;, etc.&lt;/p&gt;
&lt;p&gt;Recently, I was involved in a project where I needed to build a data connector,
a piece of software to perform data synchronization between a 3rd party provider
and the customer system, in a multi-tenant fashion environment. Basically, for
each tenant the connector needs to run a task to perform the sync operation for
the given tenant.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I used Hangfire as the processing background server hosted in a windows
service with &lt;a href=&quot;https://github.com/Topshelf/Topshelf&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Topshelf&lt;/a&gt;&lt;/strong&gt;. I won’t go in
too much details about the architecture of this connector, but one of the
requirements was that it must be reliable and resilient, so as soon as the job
was created it should complete the task whenever possible, even if there are
some transient errors. &lt;strong&gt;Hangfire provides a retry mechanism out of the box&lt;/strong&gt;,
so if an unhandled exception occurs during the job, Hangfire supports to
configure a retry strategy to take care of it. I also used some other retries
mechanisms before letting the exception to propagate to Hangfire, &lt;strong&gt;for example
using &lt;a href=&quot;https://github.com/App-vNext/Polly&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Polly&lt;/a&gt; for HTTP retries&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Another great thing that &lt;strong&gt;Hangfire provides is a Dashboard where you can
monitor the whole activity in the Hangfire Server&lt;/strong&gt;, such as, Enqueued Jobs,
Processing Jobs, Retries, etc.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/ee3c850e1378953ea7984663361daafc/e24fe/Hangfire_dashboard.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 59.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAA7BAAAOwQG4kWvtAAABr0lEQVQoz31STU/bQBD1j8FFQHtAlaze4UIqtf3PRSpphO1g4kPUS0MogsSO1971x67XD80ah+UjHWk0Y++bN29G45ycnOJsNMK37z8wGn2F533B4dFHHBwcYc/9ANfdh7uNtg//XBx+OsbxZw+e58EJggC+72M8HuPXxQUmkwl8P8DP83P4QYirKEIUXSMMp5hOrxCGocnjOMZsNsMsjs375aWPKIrg4Mm6rhtSaK3R1BUqkYPnGQpeIM9zaAuzyxwqbtsWi8UCNzdLrFYr3N3f4/YhRTBfYv73H5JkjfV6jbquTWOtW5NXVQUhBBqpoFpt3BnUpWmKJEnAuUCRM9wmHL//rDBfJtCtgpTS4LonfN00hrQoCkOYsRyirJ4JGWP9Y9OYqJVCK2tkaWLGHVxwYZR11ppIMU1GdVvCLMvARQ+mQlLAywaM9UQEpik2m435Vkr1irvOrIwElWX5UiHn3CikKJVCLRVyxiClMo2oacaY2Vu/S72bcIhDTjsTZbndHRVRTj6osy+EBBDGsclsGwh2W/dCwPZsbGW2293/568xzpu+74Dem2DXYT8ClFhztC17inEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/ee3c850e1378953ea7984663361daafc/8ac56/Hangfire_dashboard.webp 240w,
/static/ee3c850e1378953ea7984663361daafc/d3be9/Hangfire_dashboard.webp 480w,
/static/ee3c850e1378953ea7984663361daafc/e46b2/Hangfire_dashboard.webp 960w,
/static/ee3c850e1378953ea7984663361daafc/e9b9c/Hangfire_dashboard.webp 1073w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/ee3c850e1378953ea7984663361daafc/8ff5a/Hangfire_dashboard.png 240w,
/static/ee3c850e1378953ea7984663361daafc/e85cb/Hangfire_dashboard.png 480w,
/static/ee3c850e1378953ea7984663361daafc/d9199/Hangfire_dashboard.png 960w,
/static/ee3c850e1378953ea7984663361daafc/e24fe/Hangfire_dashboard.png 1073w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/ee3c850e1378953ea7984663361daafc/d9199/Hangfire_dashboard.png&quot;
            alt=&quot;Hangfire Dashboard&quot;
            title=&quot;Hangfire Dashboard&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Even though the Dashboard feature is great, I also needed to integrate de
connector with Azure App Insights, which was the main telemetry system of my
customer. &lt;strong&gt;One of the things that I was worried about was if the windows
service, for some unexpected reason, would stop working&lt;/strong&gt;. I configured Windows
Service to be retried in case of failures, but we never know what could happen,
and I was afraid that the stop would become unnoticed.&lt;/p&gt;
&lt;p&gt;So, &lt;strong&gt;to be 100% sure that I would be notified if the system stopped completely,
I decided to run a Heartbeat job every 5 minutes, which basically sends a custom
event to App Insights&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/cac502002dc398d86690164c48138757/914c7/hangfire_recurring_heartbeat.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 87.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAIAAABSJhvpAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAChUlEQVQ4y01Ty3LbOBDkPyfryiFyJJed9Wk3P5RccszJtQ/FcfSgKFqyJZEigHkAMwB3QW686eoDOERX9wyA4v2vt9fXN9N30+nsaja7mkwuJ5fv3k4uLy7evHr9y8XFm1yZXE6ns4HTq6vr2fXtb79/uLm5Kbz3IQQZ0Pd9yogpRQAwXYcAY6X/CTFG731KqXja1Yfd43ZTrVbrqqpiVma8bB0/44BxNf7N4j/K5vN8vz92nklV0w/8rEwpiQh7ttYCUJDIQTTGYn+m6oQYdIz9AmMMM7+4I6J1DgAAUVSRSFQLXi7ceulWq/b+G20q3m5HHr/eP8/n3WLRLRZQlqf7+/2ffz3P53efPtZ3d8/zv81yWdDDdzZG2nMyNlnbI45st7VvW9+23DRqTA+gppNzZ+o9HY4KwFn8+HguS1fXWNVYbWG9gfUGq21XlmZT2SrT1TU97aF+bLarh+WX5+rBbXOliDGe2paIk6qKahD1IYk2bWOsRWI/HGTq+yCRhJ/w4ATyvFIqoioCaAh5gkgCJEjRByJi4kxmEYlRxQfnXWnWZ2o9+6haqGrbtsGHpBpDiD4zaWyaxlorIWM8QhVh4QMeIIAEiTHm2IgYvNcQhLKtIOnonEFEFEKIMQYfrLfrbtUOzqqaxV3XqejgLJF9ZJ97bhoAUNX/nVVZ/ZGOGCDvT6kIIVhrmViIApFG1RhVdbhM4KxzziGiiBBSC+335uFoD+BARAoi6rouh0RixCEqe+/3u70xWQ/gEICZEbBDs4PdGc//iSUEYwwiesgUn0OqqvsBa+3grIONKZdlcxo6kmHadV0jQK8xirw8iaZpjDFEPPacX6Iqez41p7GLf3v+B3OdtUZN4jWLAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/cac502002dc398d86690164c48138757/8ac56/hangfire_recurring_heartbeat.webp 240w,
/static/cac502002dc398d86690164c48138757/d3be9/hangfire_recurring_heartbeat.webp 480w,
/static/cac502002dc398d86690164c48138757/e46b2/hangfire_recurring_heartbeat.webp 960w,
/static/cac502002dc398d86690164c48138757/0e613/hangfire_recurring_heartbeat.webp 978w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/cac502002dc398d86690164c48138757/8ff5a/hangfire_recurring_heartbeat.png 240w,
/static/cac502002dc398d86690164c48138757/e85cb/hangfire_recurring_heartbeat.png 480w,
/static/cac502002dc398d86690164c48138757/d9199/hangfire_recurring_heartbeat.png 960w,
/static/cac502002dc398d86690164c48138757/914c7/hangfire_recurring_heartbeat.png 978w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/cac502002dc398d86690164c48138757/d9199/hangfire_recurring_heartbeat.png&quot;
            alt=&quot;Hangfire Recurring Jobs&quot;
            title=&quot;Hangfire Recurring Jobs&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;And here is the simple code of the job.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;Task&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Heartbeat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    _logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;LogInformation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;(.)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    _telemetryClient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;TrackEvent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;HEARTBEAT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Task&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CompletedTask&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With this event being registered in the App Insights, it’s very easy to take
advantage of Azure Monitor to create an alert to be triggered if we don’t have a
heartbeat event in the last 15 minutes, which means that the service is not
running.&lt;/p&gt;
&lt;p&gt;So, everything was in place to address my main fear, right? Yes, but I got a
collateral effect. &lt;strong&gt;Suddenly I got a lot of noise in the Dashboard - every
“Heartbeat” jobs was being registered in the “Succeeded” page&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/50e9d030e3e9c01447c2e7a373b19454/5b587/hangfire_dashboard_heartbeat_noise.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 69.16666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABiklEQVQoz3WSy47bMAxF/f9/1l1XBYouChSZ8cSOHiRF6km6sNIO0iA9KwEEeXQpLYjkvXfOA8C2bdfrxsx5klISEZrUBwAgxlhKWWqtibn3nnMupQZ/i25f39+2bXtfV0Q8jsPMjsnn4c4izCGEUkpKiUW+/bp9+f7+todaTnNrbYzRWhORWqua9aFDbQw1swWR1nUlIgAgoh8f+PWnc1ROzxxfSmHmOToDErHkUgGTqi3e+8vl4py7Xq/e+8O0ZiGMSCQsNvl7Z40hAAAifKyrqi4ifL/eXA/XPpKUOKGU7jk/R6hqKVmYiZKpLikl732tlZnP5tYpZe+d9x6R7IHjOHrvRIiEIYTTrKpjDJ2YautDcokQAWKa5kfGGPf8iHg2P5VLbcTiJoD4wowIAH/MT821dc4VJ8xs/3I388z80twx8b7v++0WI5gdT2ZEjCE45180t95zbYjne4jIU1XHEOaS8+vMtQ9ATJI5l0Sp1vZYNbP7XscY5w97nm1Wcj7XPxMO1eP//AYkYS5HbRaHgAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/50e9d030e3e9c01447c2e7a373b19454/8ac56/hangfire_dashboard_heartbeat_noise.webp 240w,
/static/50e9d030e3e9c01447c2e7a373b19454/d3be9/hangfire_dashboard_heartbeat_noise.webp 480w,
/static/50e9d030e3e9c01447c2e7a373b19454/e46b2/hangfire_dashboard_heartbeat_noise.webp 960w,
/static/50e9d030e3e9c01447c2e7a373b19454/93852/hangfire_dashboard_heartbeat_noise.webp 1010w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/50e9d030e3e9c01447c2e7a373b19454/8ff5a/hangfire_dashboard_heartbeat_noise.png 240w,
/static/50e9d030e3e9c01447c2e7a373b19454/e85cb/hangfire_dashboard_heartbeat_noise.png 480w,
/static/50e9d030e3e9c01447c2e7a373b19454/d9199/hangfire_dashboard_heartbeat_noise.png 960w,
/static/50e9d030e3e9c01447c2e7a373b19454/5b587/hangfire_dashboard_heartbeat_noise.png 1010w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/50e9d030e3e9c01447c2e7a373b19454/d9199/hangfire_dashboard_heartbeat_noise.png&quot;
            alt=&quot;Hangfire Heartbeat Noise&quot;
            title=&quot;Hangfire Heartbeat Noise&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;But I didn’t want to pollute the “Succeeded” page with these Heartbeat job
entries, and I only care of those jobs related with the data sync. So, I needed
to remove them from there. I started to do some research and I eventually &lt;a href=&quot;https://discuss.hangfire.io/t/hide-certain-jobs-in-dashboard-log/2678/2&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;found
some
solutions&lt;/a&gt;
but they consisted in changing the Dashboard itself, which is something that I
wanted to avoid.&lt;/p&gt;
&lt;p&gt;So I though, there must be an alternative solution. &lt;strong&gt;Hangfire supports some
extensibility via &lt;a href=&quot;https://docs.hangfire.io/en/latest/extensibility/using-job-filters.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Job
Filters&lt;/a&gt;&lt;/strong&gt;,
which are similar  to Filters in ASP.NET. In fact, for this same project, I
wrote some filters to manage how the jobs were being enqueued and to manage jobs
in queue. So I knew what I could do inside filters.&lt;/p&gt;
&lt;p&gt;One thing that occurred to me is that &lt;strong&gt;I could change a job to a “Delete” state
as soon as it succeeds, and in this case the job would be shown immediately on
the “Deleted” page&lt;/strong&gt;. Here is the simple filter that I eventually wrote.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DeleteOnSuccessFilter&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token type-list&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;JobFilterAttribute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IElectStateFilter&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;OnStateElection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ElectStateContext&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CandidateState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Name &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; SucceededState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;StateName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CandidateState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;DeletedState&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                Reason &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Deleted automatically when succeeded.&quot;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Basically it changes the candidate “Succeeded” state to a “Deleted” state
specifying a reason why it was deleted. Next you just need to apply this filter
attribute to the job method.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;DeleteOnSuccessFilter&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;Task&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Heartbeat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    _logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;LogInformation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;(.)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    _telemetryClient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;TrackEvent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;HEARTBEAT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Task&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CompletedTask&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And here is the result - &lt;strong&gt;Succeeded jobs with only the jobs that I am
interested in&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/31e1210bf75db7075f57ac03a7077b38/47aef/hangfire_succeeded_job_clean.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 67.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABeklEQVQoz6WSS5LbMAxEff+rZZEDZFKV2VhjWyJIfEgA/CglWUkpU55Vest67AbQF8QEACGEhDh9fASAnLOpCrPsSglV1Xa5OzOnlEopZnZR1Zxzay3nXEqe79My397ff82Px3WaWmvr17ogYghBzYQpkXz7cfv+806Sa3Uzb62pWs6ZWVof5s1rq6333jc4hDBNU0Jcljkiv13j2zXUPp5/997NVFWZZZ5nIjGv87y41w1eluV2u6WU7vdHzjJGL4VjjADALOeQZsZMRAgAte4wETFzrZWZVbVYReIIEOMBj13rurbWWISQUowHLCLM7O4iYmbqGwzhDzwOeIzxNEBE+Aufg40x1JxFUty0O48zLMJE26lew1kNiSAEACDic2wzQ8SUMAAcC/sEF6vEEmNMKYnk8+s2876xL52lGCKFZbMmonX9Z+YnGUJ47azmkjPT1s1SdIzR+1GJMYaZlVKejfwMr+uq5kTktbm5eTPfaquqr+u5/od+A2LzLxBluIDQAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/31e1210bf75db7075f57ac03a7077b38/8ac56/hangfire_succeeded_job_clean.webp 240w,
/static/31e1210bf75db7075f57ac03a7077b38/d3be9/hangfire_succeeded_job_clean.webp 480w,
/static/31e1210bf75db7075f57ac03a7077b38/e46b2/hangfire_succeeded_job_clean.webp 960w,
/static/31e1210bf75db7075f57ac03a7077b38/0ca5b/hangfire_succeeded_job_clean.webp 1063w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/31e1210bf75db7075f57ac03a7077b38/8ff5a/hangfire_succeeded_job_clean.png 240w,
/static/31e1210bf75db7075f57ac03a7077b38/e85cb/hangfire_succeeded_job_clean.png 480w,
/static/31e1210bf75db7075f57ac03a7077b38/d9199/hangfire_succeeded_job_clean.png 960w,
/static/31e1210bf75db7075f57ac03a7077b38/47aef/hangfire_succeeded_job_clean.png 1063w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/31e1210bf75db7075f57ac03a7077b38/d9199/hangfire_succeeded_job_clean.png&quot;
            alt=&quot;Hangfire Succeeded Jobs&quot;
            title=&quot;Hangfire Succeeded Jobs&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;And the Deleted jobs with the noise of Heartbeats jobs.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/2cf4252c8460e57940a73a44c63509ef/ee9b6/Hangfire_Dashboar_Delete_Heartbeat_Jobs.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 67.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABaElEQVQoz32S27LUIBBF5/9/TX/A0irPwzFRhzR9oaEJDbGSuThOnXG/UWSxoLNPALAsCyHCEr5OvzipqpZSmIlZRISZ7SFMhIg5ZzM7qWr3BrnOWgXCz+l9CWGaJhHZtm2Msb3OKYRQcqakwOlthk9ffrz/jlmT1bptm7t7dzOrdfU+WtvXfYzLoTusqjlnFfl+Tp+/nWfQu9PMNKmI5GK1eV29eY/E3vsOE5GZlVKS6hjdLCfhlJJqHjfDuMXdNaUQzv0CT9NERCEEAFibcyqwAAAg0fg327ata40xItIYBzzPMyICQARozVM2PCIiH8ErMdNx7g67+2V0Y+zzEC3Lof6POUK8wo+jv5kjIvLxq57SWqMjH8BraykbRIgRiPilOcZ+h+9NWFsTLfu1MBI/w5dpCzMiXs3HU9tfc6mIMWLkW8Oe5Kr64s3eiUVzKVZTupbsKf3ItZ6PG2MMM7s08PGjV93+A4HuL/dGy7yqAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/2cf4252c8460e57940a73a44c63509ef/8ac56/Hangfire_Dashboar_Delete_Heartbeat_Jobs.webp 240w,
/static/2cf4252c8460e57940a73a44c63509ef/d3be9/Hangfire_Dashboar_Delete_Heartbeat_Jobs.webp 480w,
/static/2cf4252c8460e57940a73a44c63509ef/e46b2/Hangfire_Dashboar_Delete_Heartbeat_Jobs.webp 960w,
/static/2cf4252c8460e57940a73a44c63509ef/e0a35/Hangfire_Dashboar_Delete_Heartbeat_Jobs.webp 1041w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/2cf4252c8460e57940a73a44c63509ef/8ff5a/Hangfire_Dashboar_Delete_Heartbeat_Jobs.png 240w,
/static/2cf4252c8460e57940a73a44c63509ef/e85cb/Hangfire_Dashboar_Delete_Heartbeat_Jobs.png 480w,
/static/2cf4252c8460e57940a73a44c63509ef/d9199/Hangfire_Dashboar_Delete_Heartbeat_Jobs.png 960w,
/static/2cf4252c8460e57940a73a44c63509ef/ee9b6/Hangfire_Dashboar_Delete_Heartbeat_Jobs.png 1041w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/2cf4252c8460e57940a73a44c63509ef/d9199/Hangfire_Dashboar_Delete_Heartbeat_Jobs.png&quot;
            alt=&quot;Hangfire Deleted Jobs&quot;
            title=&quot;Hangfire Deleted Jobs&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;And here is the detail with the reason why it was deleted.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/f49544a6fa33a44f1f80a8c94b32bbf1/d69c4/Hangfire_deleted_heartbeat_detail.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 73.33333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAA7CAAAOwgEVKEqAAAACB0lEQVQ4y31UiXLjIBTL//9VPqPdbpPY9X0BBgM+oh09x5nptcxoMBiE9IR9UkrhgNYaRVFIP00TvA9wzsE6Bx8CnMx5xBgRQpSea4wxGK1FCAGncRzlYVkWIXHO4iNNUGQfKPIMZZGjKkuUeYb0doVRCnu746d26vseJOXJRmvYyePWDLjVvSBtBmSdRtoqJM2AUlmosHzC4BfosOB+v+PUtq3YpUo7Gmgf8dI6vDYWf7oJf3sv/WtrBS/1iMvgcVUBVx2kfx88UhOxkZAK7cM/axFDgNIGdV/DaIXJWXhnscSAOQbE4BH8jlFrjMbI/BzjrpDqaFcsGyNFLgqFJE2RZRnyPEdRVei1waCUlIcCiN2dRmBIByEnmeSukOlGVKVGxlCKUkjLuhZCZYwk7ayVPV3XCSnDjAch013XFdu2CTjm4j1xt8NaTLQ4DFB1LdeICpumQde1IoYcQvg19uP6sJZcyFrFdYUfR3Rvb5hY53kWRYczlovkFHQi6wG2yTmUVSUv5YB1RVQK5nLBQlvA0w33cH2SJDifzyLmqfAgnOcZTF5sU8E8Q6UponNC9lN5QgzPuW+E67IIIdPnZh4wryvWbZPxVxzEtP2phgchX/JbHoZBrgzJOeYG1vYnuEdIvxIyRd43/ih4z7h4/yGEbzjmf1VIy1RHVdvDJg/5H0hKpST8B0d3iN/Nn3qeAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/f49544a6fa33a44f1f80a8c94b32bbf1/8ac56/Hangfire_deleted_heartbeat_detail.webp 240w,
/static/f49544a6fa33a44f1f80a8c94b32bbf1/d3be9/Hangfire_deleted_heartbeat_detail.webp 480w,
/static/f49544a6fa33a44f1f80a8c94b32bbf1/e46b2/Hangfire_deleted_heartbeat_detail.webp 960w,
/static/f49544a6fa33a44f1f80a8c94b32bbf1/0a92e/Hangfire_deleted_heartbeat_detail.webp 1002w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/f49544a6fa33a44f1f80a8c94b32bbf1/8ff5a/Hangfire_deleted_heartbeat_detail.png 240w,
/static/f49544a6fa33a44f1f80a8c94b32bbf1/e85cb/Hangfire_deleted_heartbeat_detail.png 480w,
/static/f49544a6fa33a44f1f80a8c94b32bbf1/d9199/Hangfire_deleted_heartbeat_detail.png 960w,
/static/f49544a6fa33a44f1f80a8c94b32bbf1/d69c4/Hangfire_deleted_heartbeat_detail.png 1002w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/f49544a6fa33a44f1f80a8c94b32bbf1/d9199/Hangfire_deleted_heartbeat_detail.png&quot;
            alt=&quot;Hangfire Deleted Heartbeat Detail&quot;
            title=&quot;Hangfire Deleted Heartbeat Detail&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I hope it helps if you have an identical scenario in Hangfire.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Most Popular Programming Languages 1965-2019]]></title><description><![CDATA[Timeline of the most popular programming languages from 1965 to 2019]]></description><link>https://bfcamara.com/posts/most-popular-programming-langs-1965-2019</link><guid isPermaLink="false">https://bfcamara.com/posts/most-popular-programming-langs-1965-2019</guid><pubDate>Tue, 05 Nov 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It’s always interesting to know which programming languages are more popular.
Here is a very interesting video showing a timeline of the most popular
programming languages from 1965 to 2019.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;youtube:https://www.youtube.com/embed/Og847HVwRSI&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In summary:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;From &lt;strong&gt;1965 to 1980&lt;/strong&gt;, &lt;strong&gt;Fortran&lt;/strong&gt; kept the 1st place&lt;/li&gt;
&lt;li&gt;In &lt;strong&gt;1980&lt;/strong&gt;, &lt;strong&gt;Pascal&lt;/strong&gt; got first and kept on top for five years.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;C programming language&lt;/strong&gt; got its main popularity from 1985 until 2001.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Java&lt;/strong&gt; has been on top in the &lt;strong&gt;21st century&lt;/strong&gt;. &lt;strong&gt;JavaScript&lt;/strong&gt; comes next most of the time, with an increase over the years.&lt;/li&gt;
&lt;li&gt;Until &lt;strong&gt;2019&lt;/strong&gt;, where &lt;strong&gt;JavaScript&lt;/strong&gt; and &lt;strong&gt;Python&lt;/strong&gt; got the top of popularity.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Interesting facts!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[From Tumblr to Gatsby]]></title><description><![CDATA[Howto migrate from Tumblr to Gatsby ]]></description><link>https://bfcamara.com/posts/howto-migrate-from-tumblr-to-gatsby</link><guid isPermaLink="false">https://bfcamara.com/posts/howto-migrate-from-tumblr-to-gatsby</guid><pubDate>Fri, 27 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; &quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/fa38ab30a9b8abb4a1ff8c0b7fb86cef/e8950/Gatsby_Logo.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 27.916666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsTAAALEwEAmpwYAAABPklEQVQY05WRS0uCYRSEH2/QKgqCCKRNOykou1nQjcRCRCNKIiIXKWFBV/u0kmxRubESIjRETQkEIVykEZW0bCdFf0aMeKP4XFSrBoaBA2dmYFgbuVw9deefg47cjUsfNSz1xVg3JpT8hUpmFWpZFfJd8c24vyhO3HkRle7F4dx1xVIfbLPWhapPM8AW0PDLqGpsBlp+xF54H8RkU6jiNsTKHlNauLoi4W6tFZVSMw34gHFgCDACE8AO4Ad6gU0gCAwDrYCOYuZNBB25d48pXb5LvQjJnDob1U+hVmkWASdgA16BKHAEZAEvEAMSQEDWcyBJIV4St/GSSAaeRHi58GFvPu4Ya5TQ1upq5IYHQCfgADbkgB7ADbjktv3ANjDLymBC2rVlSvv27KOzPTLks1wxP7CnVCpU/BMLX6N8AuLrXFP+qFeUAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/fa38ab30a9b8abb4a1ff8c0b7fb86cef/8ac56/Gatsby_Logo.webp 240w,
/static/fa38ab30a9b8abb4a1ff8c0b7fb86cef/d3be9/Gatsby_Logo.webp 480w,
/static/fa38ab30a9b8abb4a1ff8c0b7fb86cef/e46b2/Gatsby_Logo.webp 960w,
/static/fa38ab30a9b8abb4a1ff8c0b7fb86cef/f992d/Gatsby_Logo.webp 1440w,
/static/fa38ab30a9b8abb4a1ff8c0b7fb86cef/882b9/Gatsby_Logo.webp 1920w,
/static/fa38ab30a9b8abb4a1ff8c0b7fb86cef/b84eb/Gatsby_Logo.webp 2000w&quot;
              sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/fa38ab30a9b8abb4a1ff8c0b7fb86cef/8ff5a/Gatsby_Logo.png 240w,
/static/fa38ab30a9b8abb4a1ff8c0b7fb86cef/e85cb/Gatsby_Logo.png 480w,
/static/fa38ab30a9b8abb4a1ff8c0b7fb86cef/d9199/Gatsby_Logo.png 960w,
/static/fa38ab30a9b8abb4a1ff8c0b7fb86cef/07a9c/Gatsby_Logo.png 1440w,
/static/fa38ab30a9b8abb4a1ff8c0b7fb86cef/29114/Gatsby_Logo.png 1920w,
/static/fa38ab30a9b8abb4a1ff8c0b7fb86cef/e8950/Gatsby_Logo.png 2000w&quot;
            sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/fa38ab30a9b8abb4a1ff8c0b7fb86cef/d9199/Gatsby_Logo.png&quot;
            alt=&quot;Gatsby&quot;
            title=&quot;Gatsby&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I’ve recently migrated this blog from &lt;a href=&quot;https://tumblr.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Tumblr&lt;/a&gt; to
&lt;a href=&quot;https://www.gatsbyjs.org&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Gatsby&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I’ve used Tumblr for many years to host this blog. Tumblr can be used for that
purpose, but it also provides some other social features like &lt;em&gt;follow&lt;/em&gt;, &lt;em&gt;like&lt;/em&gt;,
&lt;em&gt;reblog&lt;/em&gt;, links and video sharing, etc. Moving my blog to a static site
generator was in my backlog for a long time, and the main reason is to not have
my content dependent of any 3rd party service like Tumblr, Medium,
Wordpress, etc. Nobody knows what these services will do in the future with our
content. Look for example at Medium, it’s very annoying every time I need to
read an article on Medium to be asked to upgrade to a paid plan to continue
reading, and forces me to navigate incognito to workaround that. Anyway…&lt;/p&gt;
&lt;p&gt;There are many &lt;a href=&quot;https://www.staticgen.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;static site generators&lt;/a&gt;, and some of
them that are very popular (&lt;a href=&quot;https://jekyllrb.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Jekyll&lt;/a&gt;,
&lt;a href=&quot;https://gohugo.io/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Hugo&lt;/a&gt;, etc.). So, the question is, &lt;em&gt;“which one should you
use?”&lt;/em&gt;. Well, there is no right or wrong answer. I’ve chosen
&lt;a href=&quot;https://www.gatsbyjs.org&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Gatsby&lt;/a&gt;, and here are the reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it uses &lt;a href=&quot;https://reactjs.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;React&lt;/a&gt; as templates&lt;/li&gt;
&lt;li&gt;it uses &lt;a href=&quot;https://graphql.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;GraphQL&lt;/a&gt; to query data sources to generate the site&lt;/li&gt;
&lt;li&gt;it is written in JavaScript&lt;/li&gt;
&lt;li&gt;it has gained a lot of attention recently&lt;/li&gt;
&lt;li&gt;it’s easy to learn if you know node and React&lt;/li&gt;
&lt;li&gt;it has a &lt;a href=&quot;https://www.gatsbyjs.org/plugins/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;lot of plugins&lt;/a&gt; to integrate with&lt;/li&gt;
&lt;li&gt;it has a &lt;a href=&quot;https://www.gatsbyjs.org/starters/?v=2&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;lot of starters&lt;/a&gt; that you can
use as a starting point for your blog, portfolio, company, or e-commerce site.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In summary, I’ve chosen Gatsby because I want to deep my knowledge in the
components that uses (React, GraphQL, JavaScript, etc.), and due to its recent
popularity in the community.&lt;/p&gt;
&lt;h2 id=&quot;blog-migration-requirements&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#blog-migration-requirements&quot; aria-label=&quot;blog migration requirements permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Blog Migration Requirements&lt;/h2&gt;
&lt;p&gt;Here is the requirements list for my blog migration:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The content of old posts should be migrated to Markdown files (to be hosted
locally in my git repo)&lt;/li&gt;
&lt;li&gt;The design should be very simple and clean, allowing me to have an “About” page&lt;/li&gt;
&lt;li&gt;It must be able to integrate with &lt;a href=&quot;https://disqus.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Disqus&lt;/a&gt;, to allow
readers to comment my posts.&lt;/li&gt;
&lt;li&gt;Old URLs must be kept (no broken links), including the RSS URL to keep
the subscription of my blog in feed readers.&lt;/li&gt;
&lt;li&gt;All the typical requirements of a blog about software development: tags,
categories, code snippets displayed friendly, google analytics, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;migration-of-tumblr-content-to-markdown&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#migration-of-tumblr-content-to-markdown&quot; aria-label=&quot;migration of tumblr content to markdown permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Migration of Tumblr content to Markdown&lt;/h2&gt;
&lt;p&gt;The first step was to get the content of my blog posts as markdown files,
including images used in posts. &lt;a href=&quot;https://www.tumblr.com/docs/en/api/v2&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Tumblr provides a REST
API&lt;/a&gt; that I can use to grab my content. I
used a python script,
&lt;a href=&quot;https://github.com/jaanus/tumblr2markdown/blob/master/tumblr2markdown.py&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;tumblr2markdown.py&lt;/a&gt;
from someone that had the same need. It worked great, generating a markdown file
for each post, and downloading all the images embedded in posts. Each markdown
generated contains a YAML front matter with metadata that will be processed by
Gatsby. I just needed to do some small changes in the python script to include
more metadata, in particular the &lt;code class=&quot;language-text&quot;&gt;slug&lt;/code&gt; field to be set as the same URL used in
Tumblr. (more on that later)&lt;/p&gt;
&lt;p&gt;Here is an example with my first post, written in 2012.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;md&quot;&gt;&lt;pre class=&quot;language-md&quot;&gt;&lt;code class=&quot;language-md&quot;&gt;&lt;span class=&quot;token front-matter-block&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token front-matter yaml language-yaml&quot;&gt;layout: post
template: post
date: 2012-01-28
title: &quot;Welcome to my blog&quot;
slug: /post/16629534467/welcome
description: &quot;Welcome to my blog&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token entity&quot; title=&quot;&amp;#13;&quot;&gt;&amp;amp;#13;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;One of my resolutions for 2012 was back to blog . I decided to kill &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.agilior.pt/blogs/bruno.camara/&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;_blank&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;my old blog&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; (in fact, it was already dead),  which is hosted in the &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.agilior.pt/blogs/&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;_blank&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Agilior&apos;s corporate blog&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;, the company where I work and I was a co-founder (right now, I already  haven&apos;t  any part of the company&apos;s capital) and create a new blog with a personal touch,associated with the bfcamara.com domain.&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token entity&quot; title=&quot;&amp;#13;&quot;&gt;&amp;amp;#13;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;The most of the content that I will publish is certainly related to my work, software development.&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token entity&quot; title=&quot;&amp;#13;&quot;&gt;&amp;amp;#13;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;As one of the founders of Agilior, I hope also to share some of the stories that were part of my life as founder, and some of the mistakes I made along this route. There will be space also to personal subjects, however with lower frequency.&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token entity&quot; title=&quot;&amp;#13;&quot;&gt;&amp;amp;#13;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;In &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.agilior.pt/blogs/bruno.camara/archive/2007/12/02/3300.aspx&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;one of my posts&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; at the old blog, I explain that my life has been done of cycles. My perception is that a new cycle is about to come. I do not expect an easy time, and certainly I will have to leave the comfort zone. But &quot;freedom&quot; is one of the things that I value most, and to be honest,  I like to be the leader and the captain of the ship&quot;, deciding where to go and when.&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token entity&quot; title=&quot;&amp;#13;&quot;&gt;&amp;amp;#13;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;span&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;I hope I can maintain some activity in this blog.&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;span&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token entity&quot; title=&quot;&amp;#13;&quot;&gt;&amp;amp;#13;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, the content hosted in Tumblr is not very clean, probably because
I was using a rich text editor in Tumblr to write my posts, but in the end, what
is important is that posts are being displayed correctly in the new blog.&lt;/p&gt;
&lt;h2 id=&quot;choose-the-design-by-using-a-gatsby-starter&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#choose-the-design-by-using-a-gatsby-starter&quot; aria-label=&quot;choose the design by using a gatsby starter permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Choose the design by using a Gatsby starter&lt;/h2&gt;
&lt;p&gt;The next step was to choose the design for my new blog. I wanted a simple and
clean design. I started to look to the &lt;a href=&quot;https://www.gatsbyjs.org/starters/?v=2&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Gatsby starters
library&lt;/a&gt;, and I’ve tried some of them.&lt;/p&gt;
&lt;p&gt;I ended by choosing the &lt;a href=&quot;https://www.gatsbyjs.org/starters/GatsbyCentral/gatsby-v2-starter-lumen/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;gatsby-v2-start-lumen
starter&lt;/a&gt;
starter. The design is simple, clean, and it’s already prepared to integrate
with Disqus. However, in terms of code, I did some changes and I removed some
features that I didn’t want to use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Removed integration with &lt;a href=&quot;https://flow.org&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Flow&lt;/a&gt;, a static type checker for
JavaScript. I thought of using &lt;a href=&quot;https://www.typescriptlang.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;TypeScript&lt;/a&gt;
instead (also brings optional static type-checking to JavaScript), but in the
end I’ve changed the code to be just plain JavaScript (ES2018).&lt;/li&gt;
&lt;li&gt;Removed docker files&lt;/li&gt;
&lt;li&gt;Changed the &lt;a href=&quot;https://prismjs.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Prismjs&lt;/a&gt; theme to Okaidia. Prismjs is a
syntax highlihter that this Gatsby starter uses to make code snippets
embedded in my posts to look great.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, I just needed to set some settings: Avatar, Google Analytics
key, Twitter handler, etc, and I had my blog up and running.&lt;/p&gt;
&lt;h2 id=&quot;choose-the-platform-to-host-the-blog&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#choose-the-platform-to-host-the-blog&quot; aria-label=&quot;choose the platform to host the blog permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Choose the platform to host the blog&lt;/h2&gt;
&lt;p&gt;Next I needed to choose which platform to use to serve my blog. I had simple
requirements: free, support custom domains, and support automatic deployments.
By automatic deployments I mean having a new deployment triggered whenever I do
a &lt;code class=&quot;language-text&quot;&gt;git push&lt;/code&gt; in my master branch.&lt;/p&gt;
&lt;p&gt;There are many platforms that support &lt;a href=&quot;https://jamstack.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;JAMstack&lt;/a&gt; sites.
A JAMstack site (JAM = JavaScript, APIs and Markup) doesn’t need a web/app
server. Since I am using Gatsby, which is a static site generator, my blog follows the
JAMstack. Here is a list with some platforms that I could have used:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.netlify.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Netlify&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pages.github.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;GitHub pages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://surge.sh/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Surge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zeit.co/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Zeit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are many others. I started with Netlify due its popularity, and I must say
that the experience was awesome. So, I decided to go with Netlify. But from what
I’ve seen from documentation of other platforms, I would risk to say that I
wouldn’t have any issue if I had chosen one of them.&lt;/p&gt;
&lt;p&gt;In the end, I’ve created my site in Netlify, configured with my custom
domain (bfcamara.com), and configured  with automatic deployments from &lt;a href=&quot;https://github.com/bfcamara/bfcamara.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;my git
repo&lt;/a&gt; hosted in GitHub.&lt;/p&gt;
&lt;h3 id=&quot;keep-old-urls-no-broken-links&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#keep-old-urls-no-broken-links&quot; aria-label=&quot;keep old urls no broken links permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Keep old URLs (no broken links)&lt;/h3&gt;
&lt;p&gt;One of my main requirements was to keep the old URLs. Basically I didn’t want
to loose all the links out there pointing to my old blog, including the RSS link
that people were using to subscribe to my blog.&lt;/p&gt;
&lt;p&gt;Part of the problem was solved during content migration. Each markdown created
during migration was generated with a front matter key, the &lt;code class=&quot;language-text&quot;&gt;slug&lt;/code&gt; key, with its value
set to the URL used in Tumblr. Gatsby uses this key to determine the URL of a
post. For example, for my welcome post I have&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;slug&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /post/16629534467/welcome&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The issue is that Tumblr has configured automatically some redirect rules:
&lt;code class=&quot;language-text&quot;&gt;/post/16629534467&lt;/code&gt; is configured to be redirected to &lt;code class=&quot;language-text&quot;&gt;/post/16629534467/welcome&lt;/code&gt;.
And Tumblr does this for all posts, so the post ID is enough for a post to be visited.
I needed to the same in my new blog by using redirects.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.netlify.com/docs/redirects/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Netlify supports redirects&lt;/a&gt;, and I just
needed to add a new file &lt;code class=&quot;language-text&quot;&gt;_redirects&lt;/code&gt; to my repo with some rules. For
the welcome example above, it’s just as simple as&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/post/16629534467 /post/16629534467/welcome&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can check
&lt;a href=&quot;https://github.com/bfcamara/bfcamara.com/blob/master/static/_redirects&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;here&lt;/a&gt;
the file with all the rules.&lt;/p&gt;
&lt;p&gt;Finally, I also wanted to keep the RSS subscription URL. In the old
blog I was using &lt;code class=&quot;language-text&quot;&gt;/rss&lt;/code&gt; and the new blog is using &lt;code class=&quot;language-text&quot;&gt;/rss.xml&lt;/code&gt;. I just needed to
add a final redirection rule&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/rss /rss.xml&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With this rule, RSS readers doesn’t need to change my blog subscription URL.&lt;/p&gt;
&lt;h3 id=&quot;conclusion&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;In conclusion, I am happy with the final result, mainly because now I have full
control and I own the content of my blog. I also took advantage of this process
to learn Gatsby. I hope it helps anyone that needs to migrate a blog to a static
site generator. You can check the &lt;a href=&quot;https://github.com/bfcamara/bfcamara.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;git repo in GitHub&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Adopting Gatsby]]></title><description><![CDATA[Moving my blog from Tumblr to Gatsby]]></description><link>https://bfcamara.com/posts/moving-from-tumblr-to-gatsbyjs/</link><guid isPermaLink="false">https://bfcamara.com/posts/moving-from-tumblr-to-gatsbyjs/</guid><pubDate>Fri, 13 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I finally had some time to move this blog from &lt;a href=&quot;https://tumblr.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Tumblr&lt;/a&gt; to &lt;a href=&quot;https://www.gatsbyjs.org&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Gatsby&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I will write a next post describing the whole process of this migration. Stay tuned.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Software Complexity Is Killing Us - Simple Thread]]></description><link>https://bfcamara.com/post/170336995588/software-complexity-is-killing-us-simple-thread</link><guid isPermaLink="false">https://bfcamara.com/post/170336995588/software-complexity-is-killing-us-simple-thread</guid><pubDate>Wed, 31 Jan 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.simplethread.com/software-complexity-killing-us/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://www.simplethread.com/software-complexity-killing-us/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Very good blog post about software complexity nowadays.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Tar and Curl Come to Windows!]]></description><link>https://bfcamara.com/post/168765532553/tar-and-curl-come-to-windows</link><guid isPermaLink="false">https://bfcamara.com/post/168765532553/tar-and-curl-come-to-windows</guid><pubDate>Wed, 20 Dec 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://blogs.technet.microsoft.com/virtualization/2017/12/19/tar-and-curl-come-to-windows/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://blogs.technet.microsoft.com/virtualization/2017/12/19/tar-and-curl-come-to-windows/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It’s about time!&amp;nbsp; Two command-line tools added to the Windows toolchain: curl and bsdtar.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Netflix: What Happens When You Press Play? - High Scalability -]]></description><link>https://bfcamara.com/post/168460029863/netflix-what-happens-when-you-press-play-high</link><guid isPermaLink="false">https://bfcamara.com/post/168460029863/netflix-what-happens-when-you-press-play-high</guid><pubDate>Tue, 12 Dec 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://highscalability.com/blog/2017/12/11/netflix-what-happens-when-you-press-play.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://highscalability.com/blog/2017/12/11/netflix-what-happens-when-you-press-play.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Interesting article explaining how Netflix has evolved its infrasctructure, and how it is today highly distributed all over the world.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[The 6-Step "Happy Path" to HTTPS]]></description><link>https://bfcamara.com/post/166563975903/the-6-step-happy-path-to-https</link><guid isPermaLink="false">https://bfcamara.com/post/166563975903/the-6-step-happy-path-to-https</guid><pubDate>Thu, 19 Oct 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.troyhunt.com/the-6-step-happy-path-to-https/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://www.troyhunt.com/the-6-step-happy-path-to-https/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Excellent blog post explaining how to upgrade a web site to HTTPS safely. Includes also a lot of links to good resources on web apps security.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[How to undo (almost) anything with Git]]></description><link>https://bfcamara.com/post/122858660318/how-to-undo-almost-anything-with-git</link><guid isPermaLink="false">https://bfcamara.com/post/122858660318/how-to-undo-almost-anything-with-git</guid><pubDate>Tue, 30 Jun 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://github.com/blog/2019-how-to-undo-almost-anything-with-git&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://github.com/blog/2019-how-to-undo-almost-anything-with-git&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For future reference, for those git situations we need some help to undo some mistakes.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[TFS New Build System: vNext agents  Alkampfer's Place |]]></description><link>https://bfcamara.com/post/121054954603/tfs-new-build-system-vnext-agents-alkampfers</link><guid isPermaLink="false">https://bfcamara.com/post/121054954603/tfs-new-build-system-vnext-agents-alkampfers</guid><pubDate>Mon, 08 Jun 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://www.codewrecks.com/blog/index.php/2015/06/03/tfs-new-build-system-vnext-agents&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://www.codewrecks.com/blog/index.php/2015/06/03/tfs-new-build-system-vnext-agents&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Great post explaining the new TFS/VSO Build system (vNext), particularly the improvements regarding build infrastructure management, when compared with the older approach.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Introducing Aurelia]]></description><link>https://bfcamara.com/post/109312007668/introducing-aurelia</link><guid isPermaLink="false">https://bfcamara.com/post/109312007668/introducing-aurelia</guid><pubDate>Tue, 27 Jan 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://eisenbergeffect.bluespire.com/introducing-aurelia/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://eisenbergeffect.bluespire.com/introducing-aurelia/&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;I&apos;m totally stoked!!! Why? Because I finally get to share Aurelia with the JavaScript world. What is it you might ask? It&apos;s a next generation JavaScript client framework unlike anything else available today. Cut to The Chase Several months ago...&lt;/blockquote&gt;
&lt;p&gt;I think we were all expecting this announcement from Rob Eisenberg after he had announced in November last year that &lt;a href=&quot;http://eisenbergeffect.bluespire.com/leaving-angular/&quot; target=&quot;_blank&quot;&gt;he was leaving Angular 2.0&lt;/a&gt;. &lt;a href=&quot;http://aurelia.io/&quot; target=&quot;_blank&quot;&gt;Aurelia&lt;/a&gt; is the new JavaScript client framework. I watched the &lt;a href=&quot;http://vimeo.com/117778145&quot; target=&quot;_blank&quot;&gt;video&lt;/a&gt;, and it looks really good. The comparisons to Angular are inevitable, at least for me, because Angular is my framework of choice to develop rich web applications.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I&apos;m very curious to check how the community will embrace Aurelia&lt;/strong&gt;. I believe that Aurelia is arriving at the right moment after all the controversy about Angular 2.0. It seems obvious that those developers not very happy with the future of Angular 2.0, will embrace Aurelia (or at lest they will try it for sure). Let&apos;s start to check Aurelia in Google Search Trends.&amp;nbsp;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[The importance of setting goals: half-marathon finished]]></title><description><![CDATA[The importance of setting goals: half-marathon finished]]></description><link>https://bfcamara.com/post/106522617023/the-importance-of-setting-goals-half-marathon</link><guid isPermaLink="false">https://bfcamara.com/post/106522617023/the-importance-of-setting-goals-half-marathon</guid><pubDate>Mon, 29 Dec 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;375&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./069577bf55363d145b8d46c7a8f80e06963f6432e4f5c10d70660ee807586f5b.jpg&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIEAQX/xAAWAQEBAQAAAAAAAAAAAAAAAAAAAQL/2gAMAwEAAhADEAAAAUS/TllhNf/EABoQAAICAwAAAAAAAAAAAAAAAAECAAMREjL/2gAIAQEAAQUCFahSsNeCF3DUrG6//8QAFhEBAQEAAAAAAAAAAAAAAAAAABEh/9oACAEDAQE/AdV//8QAFhEAAwAAAAAAAAAAAAAAAAAAARAR/9oACAECAQE/ARF//8QAGhABAAEFAAAAAAAAAAAAAAAAADEBECJhof/aAAgBAQAGPwLaWVo6q//EABwQAAICAwEBAAAAAAAAAAAAAAERACExQVFhkf/aAAgBAQABPyEPdEKzyBCoyt9hkZfYALdcKiQR6kbCM+z/2gAMAwEAAgADAAAAENcP/8QAFhEBAQEAAAAAAAAAAAAAAAAAAQBR/9oACAEDAQE/EF1E/8QAFhEBAQEAAAAAAAAAAAAAAAAAAAFR/9oACAECAQE/EIwr/8QAHBABAQACAwEBAAAAAAAAAAAAAREAQSExUYHB/9oACAEBAAE/EE+VuQqlawW+sJPTjWJtl6ThcGYtz1EdY1ipp4+YzIqqFfmf/9k=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/6066a2b1c83ced2f262c49336c0c9454/8ac56/2d884828e1360c744638f9995ef5936b4b7aa9e6eeaa3c6634ce7b6a5f9d4253.webp 240w,
/static/6066a2b1c83ced2f262c49336c0c9454/d3be9/2d884828e1360c744638f9995ef5936b4b7aa9e6eeaa3c6634ce7b6a5f9d4253.webp 480w,
/static/6066a2b1c83ced2f262c49336c0c9454/b0a15/2d884828e1360c744638f9995ef5936b4b7aa9e6eeaa3c6634ce7b6a5f9d4253.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/6066a2b1c83ced2f262c49336c0c9454/09b79/2d884828e1360c744638f9995ef5936b4b7aa9e6eeaa3c6634ce7b6a5f9d4253.jpg 240w,
/static/6066a2b1c83ced2f262c49336c0c9454/7cc5e/2d884828e1360c744638f9995ef5936b4b7aa9e6eeaa3c6634ce7b6a5f9d4253.jpg 480w,
/static/6066a2b1c83ced2f262c49336c0c9454/41099/2d884828e1360c744638f9995ef5936b4b7aa9e6eeaa3c6634ce7b6a5f9d4253.jpg 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/jpeg&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/6066a2b1c83ced2f262c49336c0c9454/41099/2d884828e1360c744638f9995ef5936b4b7aa9e6eeaa3c6634ce7b6a5f9d4253.jpg&quot; alt=&quot;2d884828e1360c744638f9995ef5936b4b7aa9e6eeaa3c6634ce7b6a5f9d4253&quot; title=&quot;2d884828e1360c744638f9995ef5936b4b7aa9e6eeaa3c6634ce7b6a5f9d4253&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;We are at that time of the year when people typically do a retrospective on how good/bad was the year that is ending. Well, I&apos;m not writing this post to do that kind of reflection, instead I want to show &lt;strong&gt;how important is to set goals in our lives&lt;/strong&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Last Dec. 7, &lt;strong&gt;I finished my first half-marathon, 21 Km (13.1 miles), in 2 hours and 7 minutes.&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;257&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./5107f5f6a8b9205965e4fba498eaa025289665f211aba6da7af96fc9064941d6.jpg&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 51.25000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAKABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAIDBP/EABYBAQEBAAAAAAAAAAAAAAAAAAABAv/aAAwDAQACEAMQAAABvTNYYQmv/8QAGxAAAQQDAAAAAAAAAAAAAAAAAQADETECEkH/2gAIAQEAAQUCyhN6ogTxuzf/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAYEAADAQEAAAAAAAAAAAAAAAAAARExEP/aAAgBAQAGPwLCQxC7/8QAHRAAAgIBBQAAAAAAAAAAAAAAAAEhMRFBUXGRsf/aAAgBAQABPyFIw6JHs6pGS8BBbwWH/9oADAMBAAIAAwAAABBjD//EABYRAQEBAAAAAAAAAAAAAAAAABEAAf/aAAgBAwEBPxAdjL//xAAXEQADAQAAAAAAAAAAAAAAAAAAAREh/9oACAECAQE/EE8Kf//EAB4QAQACAgEFAAAAAAAAAAAAAAEAQRExIVFhkaHB/9oACAEBAAE/EEDVz2MDALUvBOQbOiJczXyewidlz//Z&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/426c0684c2264534130c283d1f2e9f4f/8ac56/c05d8f3fae9cb523e9b4cdbcade28ea0c014e5180d84ce93a618ee83ce66b132.webp 240w,
/static/426c0684c2264534130c283d1f2e9f4f/d3be9/c05d8f3fae9cb523e9b4cdbcade28ea0c014e5180d84ce93a618ee83ce66b132.webp 480w,
/static/426c0684c2264534130c283d1f2e9f4f/b0a15/c05d8f3fae9cb523e9b4cdbcade28ea0c014e5180d84ce93a618ee83ce66b132.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/426c0684c2264534130c283d1f2e9f4f/09b79/c05d8f3fae9cb523e9b4cdbcade28ea0c014e5180d84ce93a618ee83ce66b132.jpg 240w,
/static/426c0684c2264534130c283d1f2e9f4f/7cc5e/c05d8f3fae9cb523e9b4cdbcade28ea0c014e5180d84ce93a618ee83ce66b132.jpg 480w,
/static/426c0684c2264534130c283d1f2e9f4f/41099/c05d8f3fae9cb523e9b4cdbcade28ea0c014e5180d84ce93a618ee83ce66b132.jpg 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/jpeg&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/426c0684c2264534130c283d1f2e9f4f/41099/c05d8f3fae9cb523e9b4cdbcade28ea0c014e5180d84ce93a618ee83ce66b132.jpg&quot; alt=&quot;c05d8f3fae9cb523e9b4cdbcade28ea0c014e5180d84ce93a618ee83ce66b132&quot; title=&quot;c05d8f3fae9cb523e9b4cdbcade28ea0c014e5180d84ce93a618ee83ce66b132&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I would like to write this post telling you how strong I&apos;ve cut the finish line, but the truth is that it was very hard, particularly the final 3 kilometers. I confess that I spent many minutes thinking to quit, and how absurd I was being in craving for this goal, especially when I don&apos;t take any pleasure in running. Let me explain why I did it.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.bfcamara.com/post/33154883793/im-back-with-a-fixed-heart&quot; target=&quot;_blank&quot;&gt;In June of 2012 I did a surgery to my heart&lt;/a&gt;. Before the surgery I had strong limitations which didn&apos;t allow me to practice sports. With the aorta aneurysm already removed and an aortic prosthesis placed in my heart, a few months later, my surgeon told me that I was ready to do what I want freely except weight lifting. To be honest, I didn&apos;t believe him 100%. I decided to make some tests. So, &lt;strong&gt;In 2013 I set the following goals for me:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;&lt;span&gt;By the end of 2013 I&apos;ll run &lt;strong&gt;10 Km&lt;/strong&gt;. Nice to have: complete it less than an hour&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;/span&gt;By the end of 2014 I&apos;ll run a &amp;nbsp;&lt;strong&gt;half-marathon&lt;/strong&gt; (21 Km). Nice to have: complete it less than 2 hours&lt;/li&gt;
&lt;li&gt;By the end of 2015 I&apos;ll run a &lt;strong&gt;marathon&lt;/strong&gt; (42 Km). Nice to have: complete it less than 4 hours.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;So, I started running in 2013. I was very excited, I bought some shoes, I started to train during the morning, etc. After 2 weeks, I had to stop because my knees couldn&apos;t support all this kind of effort (I weighed &amp;nbsp;to much by that time). I stopped for 2 weeks, and then I started gradually. And &lt;strong&gt;here are the results:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;&lt;span&gt;I achieved the first goal very well: &lt;strong&gt;by the end of 2013 I run 10Km in 52 minutes.&lt;/strong&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;/span&gt;The 2nd goal was achieved as well, &lt;strong&gt;I run a half-marathon by the end of 2014, however I took 2 hours and 7 minutes to complete it&lt;/strong&gt; . So, I&apos;d say that I completed the goal.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;But when I was cutting the finish line, &lt;strong&gt;my first thought was: &quot;hey Bruno, do you think you could handle to run more 21 Kms?&quot;. My answer was a big &quot;NO&quot;&lt;/strong&gt;. I have now many doubts if I should go with the 3rd goal at all. It is a lot of pain. &lt;strong&gt;It&apos;s not just the pain on the day you run a marathon. It&apos;s all the pain of the training sessions. Currently. I&apos;m not prepared to run a marathon&lt;/strong&gt;. In fact I&apos;m wondering if I should drop the goal at all.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The moral of this all story is that if I hadn&apos;t set any goal I wouldn&apos;t even run 10 KMs. I&apos;m sure about that. This last 3 months, every Sunday, I woke up to run to be prepared to the half-marathon. And the only thought that I had in my mind was &quot;I have to achieve my goal&quot;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;On the other hand, it&apos;s the goals theirselves that allows us to understand if a goal is realistic or not. And that&apos;s why I&apos;m really evaluating if I&apos;ll run a marathon or not.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Happy new year 2015.&lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Video post]]></title><description><![CDATA[Evolving JavaScript with TypeScript: great talk from Anders Hejlsberg where he presents an overview of Typescript.]]></description><link>https://bfcamara.com/post/104152868603/evolving-javascript-with-typescript-great-talk</link><guid isPermaLink="false">https://bfcamara.com/post/104152868603/evolving-javascript-with-typescript-great-talk</guid><pubDate>Tue, 02 Dec 2014 00:00:00 GMT</pubDate><content:encoded>&lt;div class=&quot;gatsby-resp-iframe-wrapper&quot; style=&quot;padding-bottom: 56.2%; position: relative; height: 0; overflow: hidden; margin-bottom: 1.0725rem&quot; &gt; &lt;iframe id=&quot;youtube_iframe&quot; src=&quot;https://www.youtube.com/embed/Ut694dsIa8w?feature=oembed&amp;amp;enablejsapi=1&amp;amp;origin=https://safe.txmblr.com&amp;amp;wmode=opaque&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot; style=&quot; position: absolute; top: 0; left: 0; width: 100%; height: 100%; &quot;&gt;&lt;/iframe&gt; &lt;/div&gt;
&lt;p&gt;&lt;span&gt;Evolving JavaScript with TypeScript: great talk from&amp;nbsp;&lt;/span&gt;Anders Hejlsberg where he presents an overview of Typescript.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[The recent Microsoft .Net announcements: now what?  What's the next complain?]]></title><description><![CDATA[The recent Microsoft .Net announcements: now what?  What's the next complain?]]></description><link>https://bfcamara.com/post/102604612468/the-recent-microsoft-net-announcements-now-what</link><guid isPermaLink="false">https://bfcamara.com/post/102604612468/the-recent-microsoft-net-announcements-now-what</guid><pubDate>Fri, 14 Nov 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span&gt;From time to time I discuss with some colleagues, whom I met in university and we graduated together, about the &lt;strong&gt;career path in software development&lt;/strong&gt; that each of us have chosen. &lt;strong&gt;I think most of us have chosen the path in an organic way, mostly influenced by the technologies that our first employers had adopted by that time&lt;/strong&gt;. At least, in my case, it was what happened, and what influenced me the most to have chosen to be a Microsoft .Net developer. However, the majority of my friends have chosen non Microsoft development stacks. Every time we discuss this topic I always have to listen some critics:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;span&gt;&quot;.Net is not open source!&quot;&lt;/span&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;/span&gt;&lt;em&gt;.Net is limited to Windows!&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&quot;Developers can&apos;t influence the future of .Net&quot;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;Even when I try to explain the Mono project, or how Microsoft encourages developers to participate and vote in UserVoice, the response from them is always the same:&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;span&gt;&quot;Mono is a small initiative just to entertain some guys&quot;&lt;/span&gt;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;/span&gt;&quot;Voting features is not the same as contributing to sources as it happens in OSS projects&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think most of this behavior of being anti Microsoft have historical reasons. We graduated all in the end of the 90s, and the majority of our projects were developed using the C language targeting Unix systems, with Emacs or vi as the preferred editor. By that time, it was not very fashion to be a Microsoft developer, programming &amp;nbsp;in Basic or C++, COM, MFCs, etc. Therefore, for these guys whom didn&apos;t follow the .Net life, it&apos;s natural that they still have some issues with Microsoft.&lt;/p&gt;
&lt;p&gt;Well, these last two days were made many &lt;a href=&quot;http://news.microsoft.com/2014/11/12/microsoft-takes-net-open-source-and-cross-platform-adds-new-development-capabilities-with-visual-studio-2015-net-2015-and-visual-studio-online/&quot; target=&quot;_blank&quot;&gt;announcements&lt;/a&gt; in the &lt;a href=&quot;http://www.visualstudio.com/connect-event-live-vs&quot; target=&quot;_blank&quot;&gt;Connect event&lt;/a&gt;. To all my those colleagues:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;span&gt;Microsoft open sources .Net&lt;/span&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;/span&gt;&lt;strong&gt;Microsoft .Net will have official distributions for Linux and Mac OS.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So guys, what is your next complain now? I&apos;m looking forward to meet up with all of you to check what are your reactions.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;strong&gt;Personal advice to someone starting a software development career&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;My personal advice to someone that is starting his career in software development is to &lt;strong&gt;choose mainly one development stack&lt;/strong&gt;: Microsoft, Java, Ruby/Rails, PHP, Node, etc. When choosing the stack, don&apos;t forget to &lt;strong&gt;look at what market is demanding in terms of skills to be sure that what you offer is something that the market needs&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Don&apos;t loose sight of what&apos;s happening on those different stacks: you&apos;ll conclude that &lt;strong&gt;typically the trendy practices will be available sooner or later in all development stacks&lt;/strong&gt; and that the fundamental concepts won&apos;t differ too much.&lt;/p&gt;
&lt;p&gt;Finally, and especially if you&apos;re doing web development where JavaScript is omnipresent, if node is not your main development stack, I suggest to look at it and try to have some knowledge and practice with node (and the frameworks available like expressjs).&lt;/p&gt;
&lt;p&gt;It&apos;s very hard to follow close what happens in a given development stack, so imagine what needs to be done to excel in various development stacks. But nobody said that it was easy. Everyday there is something new out and it&apos;s very hard to know in detail everything. However, be aware that we need to stay close of what is new, otherwise you&apos;ll be obsolete soon.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Infographic: Understanding AngularJS Isolated Scope – One Hungry Mind]]></description><link>https://bfcamara.com/post/102020873648/infographic-understanding-angularjs-isolated</link><guid isPermaLink="false">https://bfcamara.com/post/102020873648/infographic-understanding-angularjs-isolated</guid><pubDate>Fri, 07 Nov 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://onehungrymind.com/infographic-understanding-angularjs-isolated-scope/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://onehungrymind.com/infographic-understanding-angularjs-isolated-scope/&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;Working with isolated scope in directives can be a bit confusing so I wanted to take this opportunity to try to explain how to interact with isolated scope&lt;/blockquote&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Angular 2 Core - Google Slides]]></description><link>https://bfcamara.com/post/101090192458/angular-2-core-google-slides</link><guid isPermaLink="false">https://bfcamara.com/post/101090192458/angular-2-core-google-slides</guid><pubDate>Mon, 27 Oct 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://docs.google.com/presentation/d/1XQP0_NTzCUcFweauLlkZpbbhNVYbYy156oD--KLmXsk&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://docs.google.com/presentation/d/1XQP0_NTzCUcFweauLlkZpbbhNVYbYy156oD—KLmXsk&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Check what&apos;s coming with Angular 2.&lt;/p&gt;
&lt;p&gt;RIP:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Controllers&lt;/li&gt;
&lt;li&gt;Directives object definition&lt;/li&gt;
&lt;li&gt;$scope&lt;/li&gt;
&lt;li&gt;angular.module (no more discussions on how to structure your app in terms of modules)&lt;/li&gt;
&lt;li&gt;jqLite&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Consuming VS Online REST API using a Service Account ]]></title><description><![CDATA[Consuming VS Online REST API using a Service Account]]></description><link>https://bfcamara.com/post/99409744598/consuming-vs-online-rest-api-using-a-service</link><guid isPermaLink="false">https://bfcamara.com/post/99409744598/consuming-vs-online-rest-api-using-a-service</guid><pubDate>Tue, 07 Oct 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;One of the great things about the &lt;a href=&quot;http://www.visualstudio.com/en-us/integrate/reference/reference-vso-overview-vsi.aspx&quot;&gt;VS Online REST API&lt;/a&gt; is that you no longer need to have installed Visual Studio or Team Explorer, or just the &lt;a href=&quot;http://visualstudiogallery.msdn.microsoft.com/3278bfa7-64a7-4a75-b0da-ec4ccb8d21b6&quot;&gt;TFS Object Model&lt;/a&gt; to integrate with TFS. It&apos;s just a normal REST API we can consume by making HTTP calls.&lt;/p&gt;
&lt;p&gt;Following the &lt;a href=&quot;http://www.visualstudio.com/integrate/get-started/get-started-rest-basics-vsi&quot;&gt;documentation on VS Online site&lt;/a&gt;, it seems that &lt;strong&gt;we are limited to consume the REST API using alternate credentials (basic&amp;nbsp;&lt;/strong&gt;&lt;strong&gt;authentication with username and password) or using OAuth (bearer access tokens).&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;This is not perfect if we&apos;re developing some integration work in VS Online and we want to use a Service Account to perform some tasks such as&amp;nbsp;&lt;/span&gt;queue a build, create work items, etc.&lt;/p&gt;
&lt;p&gt;Well, if it&apos;s possible to use service accounts when using TFS Object Model, there should be a way to use them as well with VSO REST API . In fact &lt;strong&gt;there is a way to use a service account in the REST API&lt;/strong&gt;, and this post aims to show you how to do it.&lt;/p&gt;
&lt;p&gt;First and foremost, we need to get a Service Account in VS Online. For that we can use the tool &lt;a href=&quot;http://nakedalm.com/tfs-service-credential-viewer/&quot;&gt;TFS Service Credential Viewer&lt;/a&gt;&amp;nbsp;provided&amp;nbsp;by&amp;nbsp;&lt;a href=&quot;http://nakedalm.com/&quot;&gt;Martin Hinshelwood from naked ALM&lt;/a&gt;.&amp;nbsp;You can even &lt;a href=&quot;http://youtu.be/Fkn6V0_zz28&quot;&gt;watch a video&lt;/a&gt; explaining how to do it.&lt;/p&gt;
&lt;p&gt;Next, in order to use these credentials with REST API, we need to understand what TFS Object Model does and try to replicate the same behavior in REST API and check if we succeed. Basically TFS OM uses &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/azure/hh674475.aspx&quot;&gt;OAuth WRAP Protocol to get an access token from Azure Access Control Service &amp;nbsp;(ACS)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;With the help of &lt;a href=&quot;www.telerik.com/fiddler&quot;&gt;Fiddler&lt;/a&gt;, here are the interactions we got when using TFS OM:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;&lt;span&gt;Hit VS Online unauthenticated to get a redirect 302 response where there are &lt;strong&gt;some headers that contain federation data&lt;/strong&gt;, namely,&amp;nbsp;&lt;/span&gt;realm and issuer&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Request a token from ACS&lt;/strong&gt; via the OAuth WRAP Protocol passing the Service Account username and password&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use the returned token in the Authorization header with a WRAP scheme&lt;/strong&gt; when invoking TFS services.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s try to code this in C# and see what we got.&amp;nbsp;If you want a full gist we can grab it from &lt;a href=&quot;https://gist.github.com/bfcamara/6aab0858ebda2db435a9&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let&apos;s start with Step 1 to get federation data.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;265&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./a8b7ab62b2e09e94ba0ad35cb9f16cdf202f7f01e634eac428e5b4285aa6e27c.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 52.916666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB4klEQVQoz4WT2Y6cMBBFoVkMxngBm6VZGuieUZRMHjP//2cnaiZSlCjLw5H9YB1V1S1Hr6Pl7e2Nb+/vPO4H2+z4/GVjP274ztAGg3/SGbrR0gaNtYahH7mtG8EHiqJASnkSzSZnXRb2/WDb91N6Px403jCsimGpT/pZMW2aMCq0KzBO4lqFqguiKPpJXZVoXWONxhqFsxpjaqqqQoiMPIspRIoQCSJPyLKEXGQUZY4osvMeRxFJHJEkFyKtNdoYTJXSO0nvFMFV+BDwTYORGU2dEXTG4AoaLXHWcr1OXMcrXddjtDrflWVJ9Fg8yzyxjR3LOrFsV5ZtIoSGdZm43+8ctytfP+0MXp9yUwmstTjnTrz35EJ8tLwOlq4f6PuBrg+MY4drLLXKGH1F30qufcMwTtS1/nVef8I1Lbdt5zh25nniftzPVGsnCJOiHSVNV1EUHxXE/xXWgskrfNvSth5jFVJlKJ1Tm5yqfp4CqXKkEsTx5d9CmV/QUpCm6Q8SkvSZZnqmdrnEJElMkj65kCTJyV+FoUqZ5/kc8jwtvLy8si4rj8cr67qe1TVdSfdsv5e0wTLPy7lqfxSOTUnwnhACrtXYtqQ2BaYpca08l/jZtnbiHIVzlqZp6bru42f8JvwOlZn/HmqoQ6sAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/19a02bc4159928be171ec5b311531335/8ac56/9fe7e420702dcbc3b2d6457a633aec92ee701d634fdac3d765dcebc25d613ed9.webp 240w,
/static/19a02bc4159928be171ec5b311531335/d3be9/9fe7e420702dcbc3b2d6457a633aec92ee701d634fdac3d765dcebc25d613ed9.webp 480w,
/static/19a02bc4159928be171ec5b311531335/b0a15/9fe7e420702dcbc3b2d6457a633aec92ee701d634fdac3d765dcebc25d613ed9.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/19a02bc4159928be171ec5b311531335/8ff5a/9fe7e420702dcbc3b2d6457a633aec92ee701d634fdac3d765dcebc25d613ed9.png 240w,
/static/19a02bc4159928be171ec5b311531335/e85cb/9fe7e420702dcbc3b2d6457a633aec92ee701d634fdac3d765dcebc25d613ed9.png 480w,
/static/19a02bc4159928be171ec5b311531335/0b533/9fe7e420702dcbc3b2d6457a633aec92ee701d634fdac3d765dcebc25d613ed9.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/19a02bc4159928be171ec5b311531335/0b533/9fe7e420702dcbc3b2d6457a633aec92ee701d634fdac3d765dcebc25d613ed9.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Having the federation Realm and Issuer, we can now request an access token&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;225&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./eb84095afeaa1fbd6cdcb9480489a3d20fd9959dadb81388f64772934b5bb1a8.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 44.99999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsTAAALEwEAmpwYAAABpklEQVQoz32Qy5KbMBQFBRIvISwexgZsIfATz8Tx/39dpwZXJZlFsuhSXS3OPbdFWxrcvuF8veGcww8tsz8y+ZF58ozjSN1UVLVd34015EaTaU2xsWidk6YpWZatiHqT43eWk9tzOU0r59PMoWu5jD3LfeFwHNjuSmyhGHpNt0vp24Kr72mbDUKIP4RSYdIIVyd8TDVXVzF3FtcYDnXO+binqgtspdFaUZclbV2RRJI0VsSR+h4YBAGBEOyKmLuzLKNl3BmOZcLWxPha0w0lvTe0fUE/dJxOZ5wb8X5inme224YwDN+BcZwgpVxDIxmsm6UMkYFY/0IhCAJBKAVB+G6hlFq9JUny299XsTXQFgbnjkzTzNGNdO0WN3SM3mNMsco3xpDnb7Q2BCL4fubfVJnkMo08n0+WZWFyB358LNzvN+Zpx/Xuudw8nz+v3O4XmrYkLxKSVJFqRZZHpJkizWKUVIgiU9zmgcfjwev14nyZOF09TbvBFIqqMZR1ji1zbJVTlAlRHBLFkjh58zXHSbSqE181bVnR9z1d161e3l7Vv8/6D78AuHLSrc/JRjUAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/c8d432b042ffa2c6c281607a6f8ee5ff/8ac56/950b70b80760feef63ad958cfb36e588aad66ba164ba99f5257eb1c4fc1fef22.webp 240w,
/static/c8d432b042ffa2c6c281607a6f8ee5ff/d3be9/950b70b80760feef63ad958cfb36e588aad66ba164ba99f5257eb1c4fc1fef22.webp 480w,
/static/c8d432b042ffa2c6c281607a6f8ee5ff/b0a15/950b70b80760feef63ad958cfb36e588aad66ba164ba99f5257eb1c4fc1fef22.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/c8d432b042ffa2c6c281607a6f8ee5ff/8ff5a/950b70b80760feef63ad958cfb36e588aad66ba164ba99f5257eb1c4fc1fef22.png 240w,
/static/c8d432b042ffa2c6c281607a6f8ee5ff/e85cb/950b70b80760feef63ad958cfb36e588aad66ba164ba99f5257eb1c4fc1fef22.png 480w,
/static/c8d432b042ffa2c6c281607a6f8ee5ff/0b533/950b70b80760feef63ad958cfb36e588aad66ba164ba99f5257eb1c4fc1fef22.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/c8d432b042ffa2c6c281607a6f8ee5ff/0b533/950b70b80760feef63ad958cfb36e588aad66ba164ba99f5257eb1c4fc1fef22.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;And finally we can use the access token to consumer our REST API, to get the list of team projects for example.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;273&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./e8175553fd9e52285b01981255f5cd0fd8d1c359c3f777676d44c7160c221bd6.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 54.58333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAABn0lEQVQoz52SyW7bMBgGZW0UqYW7VttUbCC5BH3/t5tCSgsUaVAEPQw+gofhvzAL1jBNM3GcsEazjJ77OrLNkds6sk6eGALWWIw2Zx50bYdsJFIqpJS/zpJMFBnvb4kfbzf21bPOFm9rghU4I4heIZqSvLxQVPmZJ8WFssqp6g9qUVCWBZlSLeM4crtueO8xTuPigPUD3dDQtiXeNcQgzwz+N5JBNwhZItsK1VUIUZNprUl7ZF0j1jqcsxx31hqkFHRNgRsEphPYXhJtR9AK3dZUR0VZ9pkMWWb0qkYbQyNryjqjEhl1k5/kZUYjFfqYo3W0Xf+V6IO+HxBC0NU5rWowx9CtJcaIPpZgLX3/D8FnpmlinuK51WWeWZaFbVtJKeGcOx+rqur7wltU7NeRtD9IaWfdNtYwMAfL/vLC8/kkpRvP13SybpHn3bBEjWrbv4UpKl73mf1+57qtPB430mNlWjxh1IRocKFnsAI/SYyXdL3icrl8XWErSrQs6GWF7jvM0BNCoGma77f5J0VRMqgSO0iGQZ9f5iDP8/8S/gRiGfej5tGH7AAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/08b46004b0f21513608205e731d098bd/8ac56/6178531cbfe1a93155a66506aa452ff8f1d66b83e3c663a96ff79d226a1ac841.webp 240w,
/static/08b46004b0f21513608205e731d098bd/d3be9/6178531cbfe1a93155a66506aa452ff8f1d66b83e3c663a96ff79d226a1ac841.webp 480w,
/static/08b46004b0f21513608205e731d098bd/b0a15/6178531cbfe1a93155a66506aa452ff8f1d66b83e3c663a96ff79d226a1ac841.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/08b46004b0f21513608205e731d098bd/8ff5a/6178531cbfe1a93155a66506aa452ff8f1d66b83e3c663a96ff79d226a1ac841.png 240w,
/static/08b46004b0f21513608205e731d098bd/e85cb/6178531cbfe1a93155a66506aa452ff8f1d66b83e3c663a96ff79d226a1ac841.png 480w,
/static/08b46004b0f21513608205e731d098bd/0b533/6178531cbfe1a93155a66506aa452ff8f1d66b83e3c663a96ff79d226a1ac841.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/08b46004b0f21513608205e731d098bd/0b533/6178531cbfe1a93155a66506aa452ff8f1d66b83e3c663a96ff79d226a1ac841.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Here is the result for my account&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;634&quot; data-orig-width=&quot;419&quot; data-orig-src=&quot;./78dcaa0a885aa1fce893b588be36a31eee137d185ea43dcf37feddfc1bbd457a.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 419px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 151.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC7klEQVRIx62V21IaQRCGF1AUgd2FAhRURBTkpHJGUMrb+BRJ3oNbitMq+sSd+tqMVUlhkOhF18zOTP/993Gt7z9+ymg0Em8xl/lsIt5iJp43l+WTJ0+Pr/K8fJSXl6U8L59kPB6rTCYTmU6nMptNZT6fy2KxEM/zxHp4+CaVSlkKhYIMBn25uLiQaCQi8XhcHMcRx7HFtqPiuq64riMxXV1xHUfXWOxVdO+6YjUaTTk/P5fDw0NJp9NyeXkpjuNKNBqVq6srOTk50Xu+LctaL/V6XRUrlYqyPD4+1pXvXC4nzWZTyuWy5PN5ZX92dqaMTk9PlQDGOEulUmrc6vV6UiqVFKRYLIpt22opEAisZMC53+/XdXt7W8LhsMre3p6KhYtYgxmsAE0mk1KtVtUQLDudjoaCM5js7+8rM+5hj4ewRyw+cOf6+lra7bYQAvYoY4B7vhHuGo2GhgEj6EEG73iPcavf72tCeNTtdt+Y1Go13cOAGBnG7PGClW9IEDuAObNubm6EOMKEh1jFIvRhCFCr1VJGKMAQthgygh6kIGBhAXbmobHMJZLJZDS+KBwdHWlmiXE2m1WBGW8gwhtlaLLMagAAQ2FnZ0ezSQbJbCgU0n0kElldh3d3d6q4u7urygcHB6oQi8VUiQ6AEQbpHpMIdAAHxOfzqSjgcDjUB5Hf7QYQtQiQYYKhD3UJMhgM3kqBzJIEygP3SQp3ptgNiz8YrXIZJVYyS8ZMQZMkXPswO4TaI3OwIuMwhimlBOjW1tZmgLhIVmklYkbs6E3cpGc3AkOIE+xgRTY3Bvhb6AIYEjua/tOAxAqWiUTi82AmhnQFMYSl6YB3y2Kd3N7eamFTvHTLe4P1w0IyYAcoqxlF7DcuGYSiBgDXzSiioHVy/G8M6QxWwAD/lNuML2YgLlKPsMRtpgox3Rjw/v5eBycCU+JGhxgh28xDc74W0AxX6pCVvsZ1Vv5w5j8Na84B/ue0CQaDX1PQRszU/Sr5BXCn7zNBhq5AAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/2f195ff7c929987bf1e418c3964ac926/8ac56/1af137c20a21e75c0f466c9bf57e6cca96646ea186618e1ee12542d75ed98c47.webp 240w,
/static/2f195ff7c929987bf1e418c3964ac926/bde39/1af137c20a21e75c0f466c9bf57e6cca96646ea186618e1ee12542d75ed98c47.webp 419w&quot; sizes=&quot;(max-width: 419px) 100vw, 419px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/2f195ff7c929987bf1e418c3964ac926/8ff5a/1af137c20a21e75c0f466c9bf57e6cca96646ea186618e1ee12542d75ed98c47.png 240w,
/static/2f195ff7c929987bf1e418c3964ac926/d587d/1af137c20a21e75c0f466c9bf57e6cca96646ea186618e1ee12542d75ed98c47.png 419w&quot; sizes=&quot;(max-width: 419px) 100vw, 419px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/2f195ff7c929987bf1e418c3964ac926/d587d/1af137c20a21e75c0f466c9bf57e6cca96646ea186618e1ee12542d75ed98c47.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;It works!&lt;/p&gt;
&lt;p&gt;As a side note,&lt;strong&gt; this method of consuming the REST API is not documented in VS Online site which means that we have no guarantees that&amp;nbsp;it will still working in the future&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;I hope it helps.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[The philosophy of great customer service | Derek Sivers]]></description><link>https://bfcamara.com/post/90336185118/the-philosophy-of-great-customer-service-derek</link><guid isPermaLink="false">https://bfcamara.com/post/90336185118/the-philosophy-of-great-customer-service-derek</guid><pubDate>Mon, 30 Jun 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://sivers.org/cs&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://sivers.org/cs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Worth reading. There is no doubt how important customer service is and the impact it has when trying to thrive a company. The same is true for freelancers.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[ Hubot security considerations]]></title><description><![CDATA[Hubot security considerations]]></description><link>https://bfcamara.com/post/89658506788/hubot-security-considerations</link><guid isPermaLink="false">https://bfcamara.com/post/89658506788/hubot-security-considerations</guid><pubDate>Mon, 23 Jun 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;nbsp;I&apos;m currently working in a project that integrates &lt;a href=&quot;https://hubot.github.com/&quot; target=&quot;_blank&quot;&gt;Hubot&lt;/a&gt; with an external system. If you don&apos;t know anything about Hubot you can read more &lt;a href=&quot;https://github.com/github/hubot/tree/master/docs&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. It&apos;s definitely a very endearing project commissioned by Github.&lt;/p&gt;
&lt;p&gt;In this small post, I would like to make some security considerations that I thought being useful for someone who needs to install Hubot in production&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DIE command&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The default Hubot installation (the one that is created by hubot --create mybot) exposes a &lt;strong&gt;DIE command&lt;/strong&gt;, included in the ping.coffee file in the scripts folder. Any user in the room can invoke it as &apos;&lt;strong&gt;hubot DIE&lt;/strong&gt;&apos;. This command just simply terminates the current hubot instance. A possible mitigation for this risk could be just remove the ping.coffee file from the scripts folder or modify it commenting the command. You could also add an if clause to check if the user running the command has a given role.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Show Storage command&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Another command available by default is the &apos;s&lt;strong&gt;how storage&lt;/strong&gt;&apos; command, included in the storage.coffee file. This command shows all the data stored in brain (well, not all data since it&apos;s just showing the brain JSON object at a maximum of a depth 4). This command is available for everyone, s&lt;strong&gt;o be aware of what kind of information you&apos;re storing in brain&lt;/strong&gt;. If you are going to install custom scripts that store sensitive information in brain, you should consider &amp;nbsp;remove this command or add some restrictions on running it. You could also encrypt the data before saving in brain.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Auth vs Roles scripts&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The default Hubot installtions loads two scripts to manage roles in hubot&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;&lt;strong&gt;auth.coffee&lt;/strong&gt; - Only users registered in &lt;strong&gt;HUBOT_AUTH_ADMIN&lt;/strong&gt; env variable can manage roles (kind of secure mode). In this mode only the instance admins can do &lt;strong&gt;&apos;hubot user1 has god role&apos;&lt;/strong&gt;.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;/span&gt;&lt;strong&gt;roles.coffee&lt;/strong&gt; - Everyone in the room can manage roles (kind of a free mode). In this mode everyone can do &lt;strong&gt;&apos;hubot user1 is god&apos;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;These modes are mutually exclusive&lt;/strong&gt;. If env variable HUBOT_AUTH_ADMIN is defined and has values (comma separated list of admin user IDs) then hubot uses the auth script, otherwise hubot uses the roles script. &lt;strong&gt;Make sure you define the variable HUBOT_AUTH_ADMIN with the list of user IDs that will be the hubot admins&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTTP Endpoint secured&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You can expose HTTP endpoints inside Hubot which will run hubot commands. Hubot uses internally the &lt;a href=&quot;http://expressjs.com/&quot; target=&quot;_blank&quot;&gt;Express&lt;/a&gt; framework. By default, Hubot exposes these endpoints without any kind of security enabled. &lt;strong&gt;We can enable basic authentication by setting the enviroment variables EXPRESS_USER and EXPRESS_PASSWORD. It&apos;s strongly&amp;nbsp;recommended&amp;nbsp;to user strong passwords.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Finally I would like to recommend the book &lt;a href=&quot;https://leanpub.com/automation-and-monitoring-with-hubot&quot; target=&quot;_blank&quot;&gt;Automation and Monitoring with Hubot&lt;/a&gt; from &lt;a href=&quot;http://varaneckas.com/&quot; target=&quot;_blank&quot;&gt;Tomas Varaneckas&lt;/a&gt;. I bought the book when I started to work with Hubot and I have to say that it helped me a lot to enter quickly inside the world of Hubot.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How much RESTful is your API]]></title><description><![CDATA[How much RESTful is your API]]></description><link>https://bfcamara.com/post/87193730398/how-much-restful-is-your-api</link><guid isPermaLink="false">https://bfcamara.com/post/87193730398/how-much-restful-is-your-api</guid><pubDate>Thu, 29 May 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;We all have a tendency to say and assume that our API is RESTful as soon as we expose our services using HTTP with JSON/XML and applying some conventions around the HTTP verbs (GET, POST, PUT, DELETE, etc.). However, this assumption is not correct. I don&apos;t want to dig in the &lt;a href=&quot;http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm&quot; target=&quot;_blank&quot;&gt;REST architectural style&lt;/a&gt; to show why this assumption is &amp;nbsp;incorrect; instead I want to share something that I learned recently while I&apos;m preparing for my &lt;a href=&quot;http://www.microsoft.com/learning/en-us/mcsd-web-apps-certification.aspx&quot; target=&quot;_blank&quot;&gt;MCSD certification in Web Apps&lt;/a&gt;, in particular while studying for &lt;a href=&quot;http://www.microsoft.com/learning/en-us/exam-70-487.aspx&quot; target=&quot;_blank&quot;&gt;exam 70-487&lt;/a&gt;: &lt;a href=&quot;http://www.crummy.com/writing/speaking/2008-QCon/act3.html&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;The Richardson Maturity Model&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Richardson Maturity Model describes four levels of maturity for services&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;&lt;strong&gt;Level 0&lt;/strong&gt;. Use &lt;strong&gt;HTTP as a transport protocol&lt;/strong&gt; by ignoring the capabilities of HTTP as an&amp;nbsp;&lt;/span&gt;application layer protocol. Level 0 services use a single address, also known as endpoint and asingle HTTP method, which is usually POST. SOAP services and other RPC-based protocols are&amp;nbsp;examples of level zero services.&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;strong&gt;Level 1&lt;/strong&gt;. Identify &lt;strong&gt;resources by using URIs&lt;/strong&gt;. Each resource in the system has its own URI by&amp;nbsp;&lt;span&gt;which the resource can be accessed.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;/span&gt;&lt;strong&gt;Level 2&lt;/strong&gt;. Uses the different&lt;strong&gt; HTTP verbs&lt;/strong&gt; to allow the user to manipulate the resources and&amp;nbsp;create a full API based on resources.&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;strong&gt;Level 3&lt;/strong&gt;. Although the first two services only emphasize the suitable use of HTTP&amp;nbsp;&lt;/span&gt;semantics, level 3 introduce &lt;strong&gt;Hypermedia&lt;/strong&gt;, an extension of the term Hypertext as a means&amp;nbsp;for a resource to describe their own state in addition to their relation to other resources.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;Martin Fowler has a &lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;a href=&quot;http://martinfowler.com/articles/richardsonMaturityModel.html&quot; target=&quot;_blank&quot;&gt;great post &lt;/a&gt;&lt;span&gt;in his blog describing in detail these four levels.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I would risk to say that most of us, when using the Web API project template provided in Visual Studio and following the typical recipes, or using the&amp;nbsp;&lt;/span&gt;scaffolding generated code, &lt;strong&gt;most of the time we are building services at level 2&lt;/strong&gt;. If we want our services at level 3, we need to introduce Hypermedia elements in our payloads. Maybe we should look to&lt;strong&gt;&lt;a href=&quot;http://stateless.co/hal_specification.html&quot; target=&quot;_blank&quot;&gt; HAL - Hypertext Application Language&lt;/a&gt;, which is a simple format that gives a consistent and easy way to hyperlink between resources in our API&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Roy Fielding, the author of the doctoral dissertation that describes REST, considers that &lt;a href=&quot;http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;level 3 is required in a REST architectural style&lt;/strong&gt;&lt;/a&gt;. However, I think I&apos;ll continue to say that &quot;our API is a RESTful API&quot;, even though my services are at level 2.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Shaping up with Angular.js]]></description><link>https://bfcamara.com/post/86491134088/shaping-up-with-angularjs</link><guid isPermaLink="false">https://bfcamara.com/post/86491134088/shaping-up-with-angularjs</guid><pubDate>Thu, 22 May 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://campus.codeschool.com/courses/shaping-up-with-angular-js/intro&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://campus.codeschool.com/courses/shaping-up-with-angular-js/intro&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;From the video introductions I&apos;d say that it seems an enjoyable way to learn Angularjs.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Using the Zendesk for Visual Studio Online integration]]></title><description><![CDATA[Using the Zendesk for Visual Studio Online integration]]></description><link>https://bfcamara.com/post/85562983333/vso-zendesk-integration</link><guid isPermaLink="false">https://bfcamara.com/post/85562983333/vso-zendesk-integration</guid><pubDate>Mon, 12 May 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://northamerica.msteched.com/&quot; target=&quot;_blank&quot;&gt;TechEd NA&lt;/a&gt;’s recent announcements about &lt;a href=&quot;http://www.visualstudio.com/&quot; target=&quot;_blank&quot;&gt;Visual Studio Online&lt;/a&gt; (VSO) &lt;a href=&quot;http://www.visualstudio.com/integrate/get-started/get-started-rest-basics-vsi&quot; target=&quot;_blank&quot;&gt;Service Hooks and REST APIs&lt;/a&gt;, will make us believe the sky is the limit regarding integrations between VSO and external services and applications.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;http://www.visualstudio.com/integrate/reference/reference-vso-overview-vsi&quot; target=&quot;_blank&quot;&gt;REST AP&lt;/a&gt;I&amp;nbsp;not only allows to get and manipulate data on VSO from a multi-platform perspective but the &lt;a href=&quot;http://www.visualstudio.com/integrate/reference/reference-vso-hooks-overview-vsi&quot; target=&quot;_blank&quot;&gt;Service Hooks&lt;/a&gt; will enable applications to get notifications about changes on VSO in real time.&lt;/p&gt;
&lt;p&gt;But I’m digressing; this isn’t about the APIs nor the service hooks capabilities, but of a particular scenario that has been implemented using these new capabilities.&lt;/p&gt;
&lt;p&gt;One of the available service hooks that is available is Zendesk. Using service hooks, paired with a Zendesk app we are now able to reduce the gap between the support team using Zendesk to doing customer care and the development team workflow that is using VSO.&lt;/p&gt;
&lt;p&gt;This integration is enabled by using a Zendesk app that allows the support team to better collaborate by escalating tickets to the dev team directly from Zendesk without the need for &lt;a href=&quot;http://www.webopedia.com/TERM/S/swivel_chair_interface.html&quot; target=&quot;_blank&quot;&gt;swivel chair integration&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The app is available as open source in Codeplex’s project the &lt;a href=&quot;https://vsozendesk.codeplex.com/&quot; target=&quot;_blank&quot;&gt;Visual Studio Online App for Zendesk&lt;/a&gt; and can be installed on your Zendesk account.&lt;/p&gt;
&lt;p&gt;For example, when a customer reports a bug, the agent can create a work item in VSO directly from Zendesk. After fixing the bug, a developer can add a comment to the ticket directly from Visual Studio Online. An agent can also notify developers by adding comments to the work items without leaving Zendesk.&lt;/p&gt;
&lt;p&gt;The main purpose of this post is to show how to setup and use the Zendesk for Visual Studio Online integration.&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Setup integration&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;The setup process consists of:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Installing the Zendesk application in Zendesk&lt;/li&gt;
&lt;li&gt;Creating a Zendesk service hook subscription in Visual Studio Online&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Install application in Zendesk&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;To install the application you must first download the latest version of the application zip package from &lt;/span&gt;&lt;a href=&quot;https://vsozendesk.codeplex.com/&quot;&gt;CodePlex&lt;/a&gt;&lt;span&gt;. You can install the app in Zendesk by navigating to &lt;/span&gt;&lt;strong&gt;APPS &lt;/strong&gt;&lt;strong&gt;à&lt;/strong&gt;&lt;strong&gt; Manage&lt;/strong&gt;&lt;span&gt; and clicking in the &lt;/span&gt;&lt;strong&gt;Upload App&lt;/strong&gt;&lt;span&gt; button.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;280&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./9b247ec0a87e269f1f4989f4a9b2a1b7da587097e9d07abb1e44d57039d27597.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 55.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAABd0lEQVQoz5WS307bMBhH85aANK652wNxiTZUrtjuhxAS2rQnQOuQkoaSNv3n1HacNIl9kE2JSqV1m6UjJ/KX49/nOLq4OeL65xmfbo+4vDvp+Xx33D8P7j9w9RcG96cMvn0kmmZLtG6ojcW20HkaqCuLljVKbvifEY3HT0itMJWh2kHKgqIQSCURTynz4S9mv4fMH4eIJGY1GrGME0SastnUWNvhnCXKsoyVKFBaY4wJlGWJMSVN04Rdy9QLvShBxDEqSVCjEes4oYxjnHOhzs/RbJazFCJItVKoLV5srQ2Fm66jmOTohweqNA1purbt2/SiN2k0nU4RogiCuq4DVVWF93b7UdO2yMWCYjxG5Xm/UZFliOfnd9KQcLHWrKQOojdh13V94f5wW+GPL1/5fn4OkwmubznPg0xq80fhPvj5dRGaBjuf47bnHRIKWWJ62eGEbkcWUu2tRZMsY7nWgd0zPNjyzl99l9wn9NfGt6tL88/CQxf7BXVWQMB1DojvAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/896fa65756ef4a29741afea349252f2f/8ac56/7ce9309ba740e84bd7a4b0e20cd93ef3496e7deffb7022ffe247ad06495e076f.webp 240w,
/static/896fa65756ef4a29741afea349252f2f/d3be9/7ce9309ba740e84bd7a4b0e20cd93ef3496e7deffb7022ffe247ad06495e076f.webp 480w,
/static/896fa65756ef4a29741afea349252f2f/b0a15/7ce9309ba740e84bd7a4b0e20cd93ef3496e7deffb7022ffe247ad06495e076f.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/896fa65756ef4a29741afea349252f2f/8ff5a/7ce9309ba740e84bd7a4b0e20cd93ef3496e7deffb7022ffe247ad06495e076f.png 240w,
/static/896fa65756ef4a29741afea349252f2f/e85cb/7ce9309ba740e84bd7a4b0e20cd93ef3496e7deffb7022ffe247ad06495e076f.png 480w,
/static/896fa65756ef4a29741afea349252f2f/0b533/7ce9309ba740e84bd7a4b0e20cd93ef3496e7deffb7022ffe247ad06495e076f.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/896fa65756ef4a29741afea349252f2f/0b533/7ce9309ba740e84bd7a4b0e20cd93ef3496e7deffb7022ffe247ad06495e076f.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Before starting the installation process, Zendesk requires you accept the license. After the upload is done we will be redirected to the settings page to configure the app:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;VSO account name à VSO account name, like in https://&lt;strong&gt;&amp;lt;account_name&amp;gt;&lt;/strong&gt;.visualstudio.com.&lt;/li&gt;
&lt;li&gt;VSO work item tag à the tag that will be applied in VSO to linked work items. This tag will be used in Visual Studio Online when a work item is created directly from Zendesk.&lt;/li&gt;
&lt;li&gt;Enable role restrictions? àselect which roles (administrator, agent) have access to the app&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;The tag is optional, but by defining a tag you can easily find which work items have been escalated from Zendesk with the use of a query. Furthermore, it also allows you to quickly see on the backlog which work items have been originated from Zendesk (by showing the tags columns)&lt;/p&gt;
&lt;p&gt;Fill the settings and click &lt;strong&gt;Install&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;545&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./62c69848f23e7f2e3b3b79d65dbb6b9907f0f066d20bc5ef0a90c78638eb8719.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 109.16666666666669%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAWCAIAAABPIytRAAAACXBIWXMAAAsTAAALEwEAmpwYAAADJElEQVQ4y4WUy44bRRSG/RhcFGXBilfgkdjxBAgpEJQNCIndCLJjNIRRFIQCC5RNhBIhxRO7NZ6x3Z5uj+2+V1eduldXdaF22zOegMSvX6XafH3qrzqnBw9O3jt68cm3v3385ZP3v3ry4Y0f/PzBo2f3v/njo0fP7j/85d7D03tfn3Zrv+k9mC3GWbFMs6usjGua1pD0RnRzdXn5168v4+mMq5KwbO8c07T3YHW9AeA1kVIYo11vLa33/sXjV0efnrx5fh7Fq3AezS7DaBGH82i9SqqyTpNiEMcxADAulNZqLymk9c2rp29+/Oxk9OeFapzWjdHGe9+2/kaD1WqFEGIUzAGstWaMGa0FFc2Wca1tW+da29k11jVt6wZJkmAC6xzVBDjbiXMOAMpwZRhjREpmnW6ssk7vbJW1apCmKca4KCsAeiPGGABRmlUVKstKSrk98MGJvW+s7GCEEMZYSqn3MsYABaU5ECI454wBIVKI7gPOtc45a3u4O3ZFWJ9YbqWkpJLTaJ6dnW2C8Xo0SoNgMxrh+ZzHMVsu6WSicdHBBGhWsxq4kPsLU4pKAfOLYjgsJuf5eJwHQTYaFUGQj4NiMsFnQ1WlfWWaE0aYuKG11pSCVKzMizxNs2STJ2mepul6nSVJsl5TAOvUFgZaATO3L9XBQIkyHANUGKMuF6kwoUJQIQjnUmvb6g6uO5grdQemjApS1ldX1WJRhosyDIv5HJbXZHkt06wpCw3VLnOCaInpLdxnnp5v3r5NwxBFMYqiOopFmjZVZcpSZxm9CLYwZSUIxqU8hAVnqygfB+V0iheLOpyj2RzNZsXlZTGdsjimy8Ug6ZqkBoyF4AcNqqQSjZUYk7KqKoQqhLgQSilnGu+c9141YluZACEgxJ3YSsmuHxvbmKZbtWm9VyV6+dPx8+Pj16enDlCfmdVUHJbtZaxsvd25bYz3dBE+/eLzx99/9/sPR47j/VORd8p2F952A2R2ttp5r/5+7WbTrs+dbb3r5hkDLTC77a897P+l1trW+97dPG/W65rQgjBg4n/h7ldwMFuD4XBIt3P/Tub/hu/qHwqWurlpl33pAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/90697deacd652d7fcd737b41fa9c45cb/8ac56/f881dcd74abc78c23b8e5fb40f80b673760a28c1c44494bc7ac879c5c1291332.webp 240w,
/static/90697deacd652d7fcd737b41fa9c45cb/d3be9/f881dcd74abc78c23b8e5fb40f80b673760a28c1c44494bc7ac879c5c1291332.webp 480w,
/static/90697deacd652d7fcd737b41fa9c45cb/b0a15/f881dcd74abc78c23b8e5fb40f80b673760a28c1c44494bc7ac879c5c1291332.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/90697deacd652d7fcd737b41fa9c45cb/8ff5a/f881dcd74abc78c23b8e5fb40f80b673760a28c1c44494bc7ac879c5c1291332.png 240w,
/static/90697deacd652d7fcd737b41fa9c45cb/e85cb/f881dcd74abc78c23b8e5fb40f80b673760a28c1c44494bc7ac879c5c1291332.png 480w,
/static/90697deacd652d7fcd737b41fa9c45cb/0b533/f881dcd74abc78c23b8e5fb40f80b673760a28c1c44494bc7ac879c5c1291332.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/90697deacd652d7fcd737b41fa9c45cb/0b533/f881dcd74abc78c23b8e5fb40f80b673760a28c1c44494bc7ac879c5c1291332.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The app is now installed.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;132&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./ebcd1e418445cdf9d8b25abadb3114d1139e43c6528c8a2cde4ed6e50c8ae642.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 26.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA8ElEQVQY04XL3U7CQBCG4d7/JQiBBK7Cc5WIkRNDFQjlBGuyLbV02b/ubl9DMXJiwiRPZjLzTfLwNuBlPWH2PmS+GvH8MWKWDnlaDnhc3jFfj1lkU163ExZ/pr8m/e2cmaWDPpMcCoVW0HkgXoQWvAeroQvcrNhCcJc5yb8+kfKINie0PqGMoqkK8nRLIwT2u0Qfip4pBa2S+NDivbsKLTF6QvQkQghEWXFsGqSUSK057vfMx/fk6Ypql1FlGYfdjnqzQeU5LgSctTjnetZajDF0XUdSCEFd12it++W5KynBWaLWV8YQlSJ6Twf9839+AC9TdwDDeRBNAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/8a53ba301de6376ada05c0f60e404ad2/8ac56/b4537d99a7256495c7f8e5b22b15fdc2ea20a6ecef268b3bfe00efb6cca27bae.webp 240w,
/static/8a53ba301de6376ada05c0f60e404ad2/d3be9/b4537d99a7256495c7f8e5b22b15fdc2ea20a6ecef268b3bfe00efb6cca27bae.webp 480w,
/static/8a53ba301de6376ada05c0f60e404ad2/b0a15/b4537d99a7256495c7f8e5b22b15fdc2ea20a6ecef268b3bfe00efb6cca27bae.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/8a53ba301de6376ada05c0f60e404ad2/8ff5a/b4537d99a7256495c7f8e5b22b15fdc2ea20a6ecef268b3bfe00efb6cca27bae.png 240w,
/static/8a53ba301de6376ada05c0f60e404ad2/e85cb/b4537d99a7256495c7f8e5b22b15fdc2ea20a6ecef268b3bfe00efb6cca27bae.png 480w,
/static/8a53ba301de6376ada05c0f60e404ad2/0b533/b4537d99a7256495c7f8e5b22b15fdc2ea20a6ecef268b3bfe00efb6cca27bae.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/8a53ba301de6376ada05c0f60e404ad2/0b533/b4537d99a7256495c7f8e5b22b15fdc2ea20a6ecef268b3bfe00efb6cca27bae.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Creating a Zendesk subscription in Visual Studio online&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;To create a new service hook subscription, in the VSO project portal, we need to go to the a project control panel by clicking the cog icon (any project will do)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;230&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./393827befc2e7bb55ce5d2e7ae93859a92ceac7837c26cc6d3a66233a3f761ae.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 45.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB1ElEQVQoz52RS2sTURSAZ+kPcCX4J+pKhELxJwiiUBRtFR+xhYDopoqiEHxStNJUk1pMSmI0tYFicCUouhCLVBryUFs1mTQSzNTMe+6dT2ayMIIieOCDw4H73fNQooVPjC3UiORrjD6sEMlXiRY+cChb5UCmysG/ka0ynCoxkqsSTbxi+mKSk5lVlPWNDo1v33F1DbvbwepqmF0Naev4/8D+0WGz3ULvamw+K2LWP6O0NAO1o+MIGeK6AsfxQlxPYLteSC8XWK7AdHt16fv4PkhAdnVaX76iXF9pMlgosXOpwv7H70mNZ7i6b4Zre+Kkbi1yL5tjKpFiai7DkUcfGZwps+P2KjdebhCEkD6+lGFebzRQhp+vocTfoCSX2XbzBRMDlzi8/QwjW09z/tgk0csxTp29QGQixsDkClvOLaOMvWY0vx5KvEAYtAk0AmHsncquxRJDxRrjxTKzx9Nc2RsnfjRNLvmUOw/mmb4/T3phiRNP1tidqDB0t8zc23Yo6Y3dE6qqioJwQTj8T/REv4T1eh3Fsh08IUOEkEgpkUKGy3ZMC13T8IIDBHXphzsTfWP6fR22220UwzAwDBPLsrBtu+/nQGjSaTZDqRDiN8GfhMH7n88DdZTrX7E7AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/57b5ead41a1b8001aac47c443e1aabd2/8ac56/65dc5bb51fcfad23e0ef09dd200091b52fea68870db9d37b06a2206565da9ee3.webp 240w,
/static/57b5ead41a1b8001aac47c443e1aabd2/d3be9/65dc5bb51fcfad23e0ef09dd200091b52fea68870db9d37b06a2206565da9ee3.webp 480w,
/static/57b5ead41a1b8001aac47c443e1aabd2/b0a15/65dc5bb51fcfad23e0ef09dd200091b52fea68870db9d37b06a2206565da9ee3.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/57b5ead41a1b8001aac47c443e1aabd2/8ff5a/65dc5bb51fcfad23e0ef09dd200091b52fea68870db9d37b06a2206565da9ee3.png 240w,
/static/57b5ead41a1b8001aac47c443e1aabd2/e85cb/65dc5bb51fcfad23e0ef09dd200091b52fea68870db9d37b06a2206565da9ee3.png 480w,
/static/57b5ead41a1b8001aac47c443e1aabd2/0b533/65dc5bb51fcfad23e0ef09dd200091b52fea68870db9d37b06a2206565da9ee3.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/57b5ead41a1b8001aac47c443e1aabd2/0b533/65dc5bb51fcfad23e0ef09dd200091b52fea68870db9d37b06a2206565da9ee3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;In the project’s control panel, choose the tab Service Hooks&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;181&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./36f619560b24ae3ad4759032c0fb680e8f83d0776e8eb39282b80bd468e61089.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 36.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAAsTAAALEwEAmpwYAAABXklEQVQoz32Oz0sbQRiG16Oi4CmHQq3iTeih/0P/qCKlRgUDijV374EeSlQiFNHSYgJqIC4b0G5sYimlRJLsZndld9yZnackNPEnvvAw3/fN+70zxtxHi7ebZ7xaqzK1apFaMUllTGbWq0wunzK+aDKWrjCRrjC2ZDL97oA383u8/vCVF++LjC5UGJkvM7tm8TJzimFfXYMWfG90ydv+kG3bZ+uHxyerxedzj0LNZ6cecvDNonR8zmF+ny+FI3YuBdlSk41ik2zpCuPnhc1JuUwYeDylm948kYC6f/H3D5iVR36jsLtLLpej1e70BypJSLTuoxJNu+Pg+QE3sUQqRSQEUiqEBhFGyEggE02sFFIlGI1GA9uuEUVRP1Br3acnGcfUf/2m2Q1xQ4WIFV3HRUpJ4Pk4HZcguEYpNdw1XNel4zjDkLuBg/N/w3MaeA0hBD0ehjx8oNfe1o8Z/PAfkDP7SEw6oMUAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/af4897c671acaaf44a539e33d8b0d3d6/8ac56/e528a10f48ecdf351d909b2b0a406745f917a31c1f036b4cd580aeefae9e871c.webp 240w,
/static/af4897c671acaaf44a539e33d8b0d3d6/d3be9/e528a10f48ecdf351d909b2b0a406745f917a31c1f036b4cd580aeefae9e871c.webp 480w,
/static/af4897c671acaaf44a539e33d8b0d3d6/b0a15/e528a10f48ecdf351d909b2b0a406745f917a31c1f036b4cd580aeefae9e871c.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/af4897c671acaaf44a539e33d8b0d3d6/8ff5a/e528a10f48ecdf351d909b2b0a406745f917a31c1f036b4cd580aeefae9e871c.png 240w,
/static/af4897c671acaaf44a539e33d8b0d3d6/e85cb/e528a10f48ecdf351d909b2b0a406745f917a31c1f036b4cd580aeefae9e871c.png 480w,
/static/af4897c671acaaf44a539e33d8b0d3d6/0b533/e528a10f48ecdf351d909b2b0a406745f917a31c1f036b4cd580aeefae9e871c.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/af4897c671acaaf44a539e33d8b0d3d6/0b533/e528a10f48ecdf351d909b2b0a406745f917a31c1f036b4cd580aeefae9e871c.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Then, click on the link “Create the first subscription for this project”&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;159&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./9191b9295c462591ea848349a3d8ea3c7f9845090e3be1be9afccc73000143ea.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 31.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsTAAALEwEAmpwYAAABKUlEQVQY042PPUvDYBRGM/mB6F5EBBF/om5WO1nj6qKoUHDyDzg5aBGk0Hy1ute0SZM0b97UtE0bc6QRXJTiAw+Xw+FeuMp6RWfr1GI+N6smpROTjYpOqWqyfWaxUm6ydPjd5XKz4NUjjR3VYE/V2VUN1o61wikHDRS17lIzBpy/eNQMwWUz5EoLuWiG3MxZC7nSRcHXuqBmCm5bESKZkE1GJOOUu1dZuP17G4V8ymw64XM24XdyFuUvqwy9AGF3iR2XuOci57V7CKePHKfIeIgII2I5RApJFCe8ezEdN8LuS2xvSCecMvjIyPMcxX18wDPaBHoLp6HhaxaB9UZYfyZrt8izjP+mOJg4PRLPZ+T5RN0eSd8j8X1GjkNafyLVNLIg+FlY1PnLX+/SqIkh8cGaAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/782356f818652eca7e276aa1b679492b/8ac56/6ce3ce6424b9f4af295b85247dcdd4b73a4837a54c5d5e86511e402aeb862aad.webp 240w,
/static/782356f818652eca7e276aa1b679492b/d3be9/6ce3ce6424b9f4af295b85247dcdd4b73a4837a54c5d5e86511e402aeb862aad.webp 480w,
/static/782356f818652eca7e276aa1b679492b/b0a15/6ce3ce6424b9f4af295b85247dcdd4b73a4837a54c5d5e86511e402aeb862aad.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/782356f818652eca7e276aa1b679492b/8ff5a/6ce3ce6424b9f4af295b85247dcdd4b73a4837a54c5d5e86511e402aeb862aad.png 240w,
/static/782356f818652eca7e276aa1b679492b/e85cb/6ce3ce6424b9f4af295b85247dcdd4b73a4837a54c5d5e86511e402aeb862aad.png 480w,
/static/782356f818652eca7e276aa1b679492b/0b533/6ce3ce6424b9f4af295b85247dcdd4b73a4837a54c5d5e86511e402aeb862aad.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/782356f818652eca7e276aa1b679492b/0b533/6ce3ce6424b9f4af295b85247dcdd4b73a4837a54c5d5e86511e402aeb862aad.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Start by creating a new service hook subscription by choosing Zendesk as the target service&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;498&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./dde89d4e968738dbb0b5a162cdc53d797b28154e71af19b91599f6ac8484dcb8.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 99.58333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAACdklEQVQ4y4VU2XKcMBDc//8WV/IFfkr84mTXeXT5wWaXU0LcICQQdGrGBrOHE6q6hkNqZqZbs0uFQBKFEHEMkcSIowhxGILe665d0bb/Rtd1SJIEu6KzEJVB3lqUekDWWqSN5agag7wxHIdxhHPuJsZxxDzPqOsau6qzSOsetbaMsjNISo2ypZ8Yfle0diWkzbcwTdM74Tw5YHaguACb+8mNjFskNzNUqUIUx+j7/jwD52CthUwlTr6Poix500JCGdG6YRgYa4aZyiCEgEgS5Hm+klK0g0USJwj8AHEcwz/5OL55OHpHeK8ef1NSQQqJtmnRNA12WZZBSokkEWdZUqQ/k+rH4wm+77OKutPQWrOyS+9o7VoyESaxuCrZfZRcFDlnIoREnuUo8gJ1VYOu7fpNyYqzo82XhJRhKgWCIEAUBtyaXmuG6Q1/X/ashCpNIWXKIjh3ruBgLVSW4+RHCMIYYZRAygxZVnC226o+CZVCVVZwk7uyBGXN/uwdim5E2Q3sSW3HVfGrklOl0HX6yrQL4TgOmNziR8e4rOSMUEqBoihXX53Zxlru03jjhGzXnRmbfEiqsWHHa5W3jf/qlFDse8M+ZpWDIETTtGuWK6E5V/KrwUDRGPtOmOcFSGky6jxNa58INBD+NxQWrCU/f/uO1x8/oZ6eIPd7pIcDQx4OyB4fMXYdHJ2Gi75dZrmK8nx3h+eHB/i/fiPY7z/x5w+C+3uYPMc4TesQWAx/iWmeUVUVdq3voz0e0XjeJ+j57Q11FEHrHsb0bGICHdXeGJgNqF1lUSBNFXZxmuJLSMnDgYYCgSaO53l8zxPqA2EY8iR6eXnBXyTxBRJW19a/AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/f4bd9ccd0e3a6353aa3942f72568a5f4/8ac56/cdffa8b05619765c79669490b537ce30815e97d42572887fdb33bd40de0bee2c.webp 240w,
/static/f4bd9ccd0e3a6353aa3942f72568a5f4/d3be9/cdffa8b05619765c79669490b537ce30815e97d42572887fdb33bd40de0bee2c.webp 480w,
/static/f4bd9ccd0e3a6353aa3942f72568a5f4/b0a15/cdffa8b05619765c79669490b537ce30815e97d42572887fdb33bd40de0bee2c.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/f4bd9ccd0e3a6353aa3942f72568a5f4/8ff5a/cdffa8b05619765c79669490b537ce30815e97d42572887fdb33bd40de0bee2c.png 240w,
/static/f4bd9ccd0e3a6353aa3942f72568a5f4/e85cb/cdffa8b05619765c79669490b537ce30815e97d42572887fdb33bd40de0bee2c.png 480w,
/static/f4bd9ccd0e3a6353aa3942f72568a5f4/0b533/cdffa8b05619765c79669490b537ce30815e97d42572887fdb33bd40de0bee2c.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/f4bd9ccd0e3a6353aa3942f72568a5f4/0b533/cdffa8b05619765c79669490b537ce30815e97d42572887fdb33bd40de0bee2c.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The Zendesk service hook provides just one action to create a private comment in a Zendesk ticket. This action only supports the event “Work item is commented on”, and before creating a private comment in Zendesk, it performs additional checks:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;The comment should start with the pattern defined in the field “Contains only”&lt;/strong&gt;. When defining a subscription to events “Work item is commented on”, one required parameter is the “Contains string” field.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;402&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./82038b2ef25ad3cb3e84f0ec5116814abd7988bf04921b1a00a4a0e6d6b99e01.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 80.41666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAAsTAAALEwEAmpwYAAACBUlEQVQ4y5WT6U7bQBRG/f4PQ0H92bBIVVRoG1pVlARUFu+7neAZ7/apxqYBEgjqSEf3jsfzzXdn0QLPxzJNHMvCdWxsy8I2zQHHthFZRi4luRQI8T6aLGtEUZOIaoiKrKhJZYUay/KKpSx5yCvqpqF5By0RJW6ao0eCu0BgxhJ/VQzRWxW4yzEPVsUwoW3bnWh93zG2nr7vWbe+o2tbuq6lf6RtX7pRAlsOl+mSwA9Ik5QkTkiShDhOqKpqa8Kmm03hwWEURhi3Oq7tYZsWxp3O/e09uczpum5neUVRbAuqk1GuijynVSvWNXVdv1nSptstwTAMuVos8KOYdsPRrtOs/y28IazFUYznuCSyounUQTTrn3ZRliVCym2HaRwThzGllGQip6qbsfRmjG+h3ClRtUXtM1EtSlM8P2T1kJHIgrKHjp4WdlK2DbIsx37XPTn0j46xJofE0yn+5ymrbzPk7Adido6cnT/GsS/W/XOy7zOWp2c8nJ5RC7EW1czjY25NhziMML2A+fUc3zdwXB3X0/E8ld/jesaAN0Qdw/hDIpckv87ITQv1PMaST04IL35T3NyQLS5ZHB1wOdnn4tMe88N95kcHzCcfmB8ecHXycRhX+eVkD/fnV5ZfpuRB8CRYhSGFoSP1kdKyX8F59VuuG+Su9+LqaGpTu2e0/8F6zrNr8xcFOMosjo4p0AAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/705798e15bcfc436aa30caab68dec87e/8ac56/7e83f95d616cc5ca031f8ee2545608f4475ab2a971bb85579ff2199b25e5e8ca.webp 240w,
/static/705798e15bcfc436aa30caab68dec87e/d3be9/7e83f95d616cc5ca031f8ee2545608f4475ab2a971bb85579ff2199b25e5e8ca.webp 480w,
/static/705798e15bcfc436aa30caab68dec87e/b0a15/7e83f95d616cc5ca031f8ee2545608f4475ab2a971bb85579ff2199b25e5e8ca.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/705798e15bcfc436aa30caab68dec87e/8ff5a/7e83f95d616cc5ca031f8ee2545608f4475ab2a971bb85579ff2199b25e5e8ca.png 240w,
/static/705798e15bcfc436aa30caab68dec87e/e85cb/7e83f95d616cc5ca031f8ee2545608f4475ab2a971bb85579ff2199b25e5e8ca.png 480w,
/static/705798e15bcfc436aa30caab68dec87e/0b533/7e83f95d616cc5ca031f8ee2545608f4475ab2a971bb85579ff2199b25e5e8ca.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/705798e15bcfc436aa30caab68dec87e/0b533/7e83f95d616cc5ca031f8ee2545608f4475ab2a971bb85579ff2199b25e5e8ca.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;In other words, only comments that start with the pattern (In this example &lt;em&gt;Zendesk:&lt;/em&gt;) will be considered by the subscription. For example&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;148&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./753496f96e096307386c78b0c6f7f01eba8087ee1101612d99a284572fb2d6f9.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 29.583333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA0UlEQVQY05WO0WrDMAxF/f8/05f1R1bmktKyOO3mxJkdWZZsyBZ7OGlhbE87CMHV1RUSYSXGyMxbZyJmTinFB8xxGIbu2m3Lm5tSEofDc3M6KdU2L1Kprm1beWzO54u11nsP3sOKxwrcBbgVMZoRkHqtr63Sb9oM5nYz+r23o8UJJvOBk69XHMAE4CBgAAvz/JlzFk4eX5/281ISxUjMgSPVYo7kAHtDWF9Fj4zEgZmYPC1fSylFeCkvu10pJS9V/wsBSqHWNZzzbzPn8nf4I/wNzjlVk6Nu6CcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/dbb83ceb9c64de43d29b1e26e89cb6af/8ac56/bfb69cdb0893dcb74ad0809a5daf8f1e7f437db7d8c11d85303b2a973b92c8b1.webp 240w,
/static/dbb83ceb9c64de43d29b1e26e89cb6af/d3be9/bfb69cdb0893dcb74ad0809a5daf8f1e7f437db7d8c11d85303b2a973b92c8b1.webp 480w,
/static/dbb83ceb9c64de43d29b1e26e89cb6af/b0a15/bfb69cdb0893dcb74ad0809a5daf8f1e7f437db7d8c11d85303b2a973b92c8b1.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/dbb83ceb9c64de43d29b1e26e89cb6af/8ff5a/bfb69cdb0893dcb74ad0809a5daf8f1e7f437db7d8c11d85303b2a973b92c8b1.png 240w,
/static/dbb83ceb9c64de43d29b1e26e89cb6af/e85cb/bfb69cdb0893dcb74ad0809a5daf8f1e7f437db7d8c11d85303b2a973b92c8b1.png 480w,
/static/dbb83ceb9c64de43d29b1e26e89cb6af/0b533/bfb69cdb0893dcb74ad0809a5daf8f1e7f437db7d8c11d85303b2a973b92c8b1.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/dbb83ceb9c64de43d29b1e26e89cb6af/0b533/bfb69cdb0893dcb74ad0809a5daf8f1e7f437db7d8c11d85303b2a973b92c8b1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;The comment should be related with a Zendesk ticket&lt;/strong&gt;. The relation is defined using hyperlinks, which means that a given work item is related to a Zendesk ticket if it has in its links a hyperlink to the URL of the ticket details page in Zendesk agent app. (don’t worry this relation is created automatically by the app when the work item is created on VSO, no manual intervention is needed)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;136&quot; data-orig-width=&quot;362&quot; data-orig-src=&quot;./719c3eaaeeb3239f5670c7bae4fe1de9bdcc3829454d78c09493dc673dc47b88.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 362px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 37.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABsklEQVQoz1WMy27aQBSG/VJ9gD5eu2s3eYZsiiAJnklUFlRdVGmKb5BwKdgzYHvcALZhuHk8f2UTVfRI3/nPf27GeDyG67jwPA+D/gBWz8JwOKxr13Hw/DJC9/sjfjz24PbH8Lx+vWtbNqrb2Wz2H0aSCHDOEYYh4igGCxiEEIjDCOFiAZG8wvImGIx88GiJKIrr/pxxrFYr5HmOLMv+YaTrJXb7HcRS4HA4QCmF0+mEvZQ47Pe4jLIsobWGvvDV/iVGlQ7HI1SpcDweIaWE3O1wKgotdxJFUWil1Jmy1G+HZ60eXlI9zLIUcRQhW60QhyHCOIao/HqNP4nQWZpiu9lgm+e1ys1G1/4NeanbLYxQCLiDZ9ijKV7Gv+F/aSDsdMAfHjSj92CUFsw018w0U0ZpGRCCgFAdUFop/NoTBPQe/OYGBvIcinPg4wfIqyskhGCfriHDSE2fLPi28000Gu9iSt8HtutPniwEtlsyt4/Rz1+Y9mzMejZGjgPR7cJYXF+DtZpwPn3GhFLMO1/B7u7Aiak5IWDt9slvNhO/1XplZltVPU7IeWa2MacUdV1xe4u/jAZCQUAn2VIAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/27dbaabd32575d5ebea62f9cc9b9b92c/8ac56/bab91418679074b1daa3bbac9a35519bc952e6842103ffe3d4f479da47c67ceb.webp 240w,
/static/27dbaabd32575d5ebea62f9cc9b9b92c/c2de8/bab91418679074b1daa3bbac9a35519bc952e6842103ffe3d4f479da47c67ceb.webp 362w&quot; sizes=&quot;(max-width: 362px) 100vw, 362px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/27dbaabd32575d5ebea62f9cc9b9b92c/8ff5a/bab91418679074b1daa3bbac9a35519bc952e6842103ffe3d4f479da47c67ceb.png 240w,
/static/27dbaabd32575d5ebea62f9cc9b9b92c/10600/bab91418679074b1daa3bbac9a35519bc952e6842103ffe3d4f479da47c67ceb.png 362w&quot; sizes=&quot;(max-width: 362px) 100vw, 362px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/27dbaabd32575d5ebea62f9cc9b9b92c/10600/bab91418679074b1daa3bbac9a35519bc952e6842103ffe3d4f479da47c67ceb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;When registering the subscription, the following Zendesk inputs will be asked:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;The Zendesk account name&lt;/li&gt;
&lt;li&gt;User name&lt;/li&gt;
&lt;li&gt;API token&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;356&quot; data-orig-width=&quot;413&quot; data-orig-src=&quot;./2f3bffe0e669adbac9001f828f72d5680da0efc3e1c1a46a5843649dae5883d5.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 413px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 86.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAAAsTAAALEwEAmpwYAAAB8klEQVQ4y61SWY7iMBTM/a8zB5gDMBppPro/EBAnGDqJlyxAvLtGNsOIiOWrLZUqTpxy1Xuv+Pz4QE0IqrLEvqpQkTI/V7sdqpKAsw7j0GPoJaSUEEJkfoXi0HSYXYS8WIzK4awdJu3y/qR93vdng3G2sM4jhAAfQuZnKAj9QjtpUHHGrjuh5hd0o8JBzvgaEhSouICKGcpYeO/g3GsUnDFcV/zPMXgghsz38N7DuSvfYyFISgLWMvCOo2s7TNMJ1loYYzKse+8o4SaauCC5GXsc98fM3bEBaxgkl2BNC63NtW7+0ZnWOl++EKSUYuiHLCC4gOA8O+5lnx0bYx9i3Tu7F8uCdV2ja9vc8nTjDdYYKKUWh58hf891/VfD7XYLQkrQwyELJRGtFC7a5vF41tUklKJe4wa4fObmkBDQmoYjPXrJeeSMB8547MYLnA/xlbPUsFldcFJiUZJiX9VRdBxSjrC3ycnTE6J/Ezf9bKyBsWopSHYlWNv9bJn4QRt2UvP8uxe9Ukqn7r5xaJ87rKsKg+z/9Of5Vz9Oymi9PU9nmyJ57+Or2Uv100bDWL0UrAiJtN6DySFHDt4jxDx38V13k2ByOCm+FGyaBiHG4J0LztporQ32yrjjB9xcGqMX74thGPCdq1itVthsNliv19+Cv1aGIFY5ukrQAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/8b55a02f26ddd6fda2397b320eebc9ea/8ac56/eb2dfd65b0ce30134b793dad0be5e4bbc1e2264367db7711e2807595271850de.webp 240w,
/static/8b55a02f26ddd6fda2397b320eebc9ea/f2c1b/eb2dfd65b0ce30134b793dad0be5e4bbc1e2264367db7711e2807595271850de.webp 413w&quot; sizes=&quot;(max-width: 413px) 100vw, 413px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/8b55a02f26ddd6fda2397b320eebc9ea/8ff5a/eb2dfd65b0ce30134b793dad0be5e4bbc1e2264367db7711e2807595271850de.png 240w,
/static/8b55a02f26ddd6fda2397b320eebc9ea/6c1e7/eb2dfd65b0ce30134b793dad0be5e4bbc1e2264367db7711e2807595271850de.png 413w&quot; sizes=&quot;(max-width: 413px) 100vw, 413px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/8b55a02f26ddd6fda2397b320eebc9ea/6c1e7/eb2dfd65b0ce30134b793dad0be5e4bbc1e2264367db7711e2807595271850de.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;Zendesk account name&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;The Zendesk account name is the subdomain part of the URL used to access the Zendesk account like in https://&lt;strong&gt;&amp;lt;account_name&amp;gt;&lt;/strong&gt;.zendesk.com&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;Zendesk user name&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;The Zendesk user name is the email address of the agent that will be used to perform the integration (this can be seen as the integration account which will be used to perform operations on Zendesk). The list of available users can be viewed in People menu option in the Manage group.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;301&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./23bb69b5975afe2409d5d9c085e126a6dcbaa90dbd003191d3d4c909f31bbf55.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 60%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAACXklEQVQoz5WQy08TURTG589U0YBujUtXJhIT3MjSuHBB0AUQJY2gC43xEUtpeRUq4dEibYe2aacznem87p0793bOZ2YqIIaNX/Ll3EfO7373aB++5+nrxjbW9vb5i9x29/HLH5iZX6eZV0WamS/i2cIOZhfLmF08r+Ur+/R+eq6AJ3PrePB0EdrCl1v0vnwfC/mb6k3hBntbmMBy4Tbl1u/Qu9IkVjanrvXq5l2sbqV1CsuFCeSKk3j++h60k1+HGNgmDcwugqEB3zHId034oYNuv5VVLnywyLtix7NguRYGnp1ZyBDFUgFa/ahKdrWGoGdQ2OtTaJgIGjoFlk1G34J5YROWZcN2PHiuD88L4DguGg0dQcCRJEA+vwatUa3CODiE2WzC0XU4rRYG1WMKbBtCKQoYo4DxzCyKIOKYeCQwSghGv4+lpUW47hCptnZ2obXbbdheiMHQB+ccgnNEUQQWhuT2+wiGLiTjiEMGGUuK1QhRLBFLBalGGItolCQobmyR1m614PgMjEcQQmQwKSW1KxXUdivcaJwZpn7G/HYnEb1e1o2/RUCsRLY6PDpGBrR9lqUUIhoDlaJerYpmeSeKTWsQdTqRKJUSfnqa9hMR4dzpgVRx9kiz2ZQZ0AsYvJBdJlQKzsCibqcNkX5NSiRpBCmvwP4F1uv1kabrOnzfRxiGF0AhBKXVC0Kyhj5FIh4HwzjeJTBBQulMWfblk5MatEa9Di/k4GPQBVQphf9QllBvdEg7yOWy+QWMQ0TjGf5JiTiOr3U665ECOlYFn39O4+PeI3zaf4iVb7P4DTX9bEGXdyMSAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/2aa1682579509e1c48877f20bed99a72/8ac56/31e9f69b1926925427d577f66617a5f3fb219aa92354af4bb21d33b71592767b.webp 240w,
/static/2aa1682579509e1c48877f20bed99a72/d3be9/31e9f69b1926925427d577f66617a5f3fb219aa92354af4bb21d33b71592767b.webp 480w,
/static/2aa1682579509e1c48877f20bed99a72/b0a15/31e9f69b1926925427d577f66617a5f3fb219aa92354af4bb21d33b71592767b.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/2aa1682579509e1c48877f20bed99a72/8ff5a/31e9f69b1926925427d577f66617a5f3fb219aa92354af4bb21d33b71592767b.png 240w,
/static/2aa1682579509e1c48877f20bed99a72/e85cb/31e9f69b1926925427d577f66617a5f3fb219aa92354af4bb21d33b71592767b.png 480w,
/static/2aa1682579509e1c48877f20bed99a72/0b533/31e9f69b1926925427d577f66617a5f3fb219aa92354af4bb21d33b71592767b.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/2aa1682579509e1c48877f20bed99a72/0b533/31e9f69b1926925427d577f66617a5f3fb219aa92354af4bb21d33b71592767b.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;API token&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;The API token is the Zendesk API authentication token for the agent who will perform the integration. To be able to use API tokens a user must explicitly enable access with tokens, which can be done using the API menu option inside the Channels group&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;300&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./667f391741a423686c8ebb064764806c2ddbd8f23990a597d0567827d3ae7280.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 60%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAACfklEQVQoz22RXYscRRSG+1eKJCZ/wAsv/bgyN0Ewf8AIiijZbMDEBJK9WQghWXfRbGandzKQ2ZUJO9NV3T393V3V1V/zSHePCuqBh1NVFO857znWwbHN899n/Hp+yd3H53z53Wtu/zjh9k9nfHXP5s6DOXf252P+H77en3Prhwm3vv+NL745wbr/4gZPJh+zd3Sd+y+vDewffcSDV9f4+eg6v5zc5NHJTR4e3/gPj47H970XH7L3/AO+ffg51uXFW7zZBH8+IVrYhD1v35DGLm6ywYs8wliiTYo2Ccoku3OKKpMRk9BtFe+Wa6zV8gp/8Qfp1RrlSArHpXi/wuSKKE7xvAB/ExEEMb4fsdmEhEF/j8hzRZ4VZJmiMob5xRpr7ThEqkSZClNXlFWFaRpKYxDCQbgewtuwFi4r4bKWLmshcaRESIGUEkc4eJ7g1F5g9Q9Rpsi0oaprTE8vagxZXlA1LU3bMcR2y7aq+Hdst2N+74RY0nXxbRv39SmhPSU4OyO0bVSaUqiCQpdUpqKUkvTwkFrKUaTraNuWrs/dWHC5DrCEdIldl0Q4qCAYCUO01jR1Tde2w+fw4oLVdEogJXGSEobhQJ7naF3CtmWxdHvLLnGhSbUZ7db1MMeyLAehTkq2vk9Z1ai6+XscPdXO/s7xaNkRgiTLidKcrFCYsqTUeujwr+hWK6JXR/hTm8Q+J53NyGYz0tk58XRCEUe0XcViKbCurlYkSYJSaqjad9bTV6/rmrppBlHVFw1CdJbTaE2tFF3ZQP1Pi8Irsd4dHBCkOUm+627HsOUsG2ZUVxVhFNEvMM0y4jQhyzSXzjEHZ5/x9PRTnk0+4fDNPf4ErOxqrDUeE5kAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/0ae762fedabdbe72b638448cfd88369e/8ac56/e19bc0eee0d2e6b5f5e3bc766844e74c3c27afc781f7aa85bddbfc050d9207cc.webp 240w,
/static/0ae762fedabdbe72b638448cfd88369e/d3be9/e19bc0eee0d2e6b5f5e3bc766844e74c3c27afc781f7aa85bddbfc050d9207cc.webp 480w,
/static/0ae762fedabdbe72b638448cfd88369e/b0a15/e19bc0eee0d2e6b5f5e3bc766844e74c3c27afc781f7aa85bddbfc050d9207cc.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/0ae762fedabdbe72b638448cfd88369e/8ff5a/e19bc0eee0d2e6b5f5e3bc766844e74c3c27afc781f7aa85bddbfc050d9207cc.png 240w,
/static/0ae762fedabdbe72b638448cfd88369e/e85cb/e19bc0eee0d2e6b5f5e3bc766844e74c3c27afc781f7aa85bddbfc050d9207cc.png 480w,
/static/0ae762fedabdbe72b638448cfd88369e/0b533/e19bc0eee0d2e6b5f5e3bc766844e74c3c27afc781f7aa85bddbfc050d9207cc.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/0ae762fedabdbe72b638448cfd88369e/0b533/e19bc0eee0d2e6b5f5e3bc766844e74c3c27afc781f7aa85bddbfc050d9207cc.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;We have now a Zendesk service hook subscription created&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;159&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./67ef5e51c25f87b839b0b88446c86c8eae5e51af36d1d05d424a5121cdecffd5.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 31.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsTAAALEwEAmpwYAAABS0lEQVQY022OzU4UQRSF6x3cEBZCIm6ML+OCJ2GBTyComEl4BMI7sGChW4ILQjeto2Y2QLBnaqb/6n+66yPdM4ENlZycU9+5uVXi9deUN6OMndENb0c3bH1LeXec0fONw4SNzwmbXxK2j1I+nIzZPR3z/jjj1adrxP4lYu8C8fGSnaOEzYMrxM/bmqu7ijQ3ZNKTzRzpzPFben6t9WfumZQB6ICW/2pJMrWc/6s4G5ec/634Man5PqkR0WmCqumcIXq7cmsG76wGb4ne0TSG6UIxKwylCsQu8tIRbhkwocUag7MW6zxdjLTdSsu2GxTaZxY6aOP6vz3rc1xlYYwhz6dorSnLEjmTFItiyMViQdM09DNlUSClHLxad3M5p2kUUj6Q5/c45xAhhGGZ9x5rLUqpQT1TjRpY3/VL+/tTp9TwmLUOrSu0rglhySOIN7Ky4cvKFQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/8bf08eab73efb064405a167a7d63beb0/8ac56/1735fc46020a510598c0f07938e55373672b34e48524b2eb881f66785bf39819.webp 240w,
/static/8bf08eab73efb064405a167a7d63beb0/d3be9/1735fc46020a510598c0f07938e55373672b34e48524b2eb881f66785bf39819.webp 480w,
/static/8bf08eab73efb064405a167a7d63beb0/b0a15/1735fc46020a510598c0f07938e55373672b34e48524b2eb881f66785bf39819.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/8bf08eab73efb064405a167a7d63beb0/8ff5a/1735fc46020a510598c0f07938e55373672b34e48524b2eb881f66785bf39819.png 240w,
/static/8bf08eab73efb064405a167a7d63beb0/e85cb/1735fc46020a510598c0f07938e55373672b34e48524b2eb881f66785bf39819.png 480w,
/static/8bf08eab73efb064405a167a7d63beb0/0b533/1735fc46020a510598c0f07938e55373672b34e48524b2eb881f66785bf39819.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/8bf08eab73efb064405a167a7d63beb0/0b533/1735fc46020a510598c0f07938e55373672b34e48524b2eb881f66785bf39819.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Using the Zendesk application&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;The VSO App for Zendesk is only activated in a Ticket side bar. Let’s start by creating a new ticket and submit it.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;320&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./7469c72a5b020300fef905c46ae57aedbc1fccdd764f6dcf2c8ba53eebef3ea7.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 64.16666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB7UlEQVQ4y4WSy27UMBRA50dhS3+iQNmwQWKHxA74BFZMWVWIFaIvJKYUpg+m0xnn1UziOLEd5yB7Ju20oGLp6PqRe+Jre7Cz/5KL6WcmYsS5+MKn7y8Y7j3m4+Eztg+22D68w8FThgdbDPefMNzdZLj7OPBhd5P3O88ZZMmC1jTQAY7QOtmhJyldJHGipBNliG5eQKIgkiC7ZU67woHVMBDRnLpp0LrBGE2LQ8ZzpntfSY5HZMdHpMdHIebjn1STc/IfI4rZlNo0KFUiq5K6rlCqYpAkCVpr6rrGaB1+pmYzstGIq5MTsl/jwNV4jPw9QQtBfXqKuryksZayLCmKgqqqgiMI27YNeKH1sapoi4JWyhvKEruaU2mGWhRUSrHIc/I8D1Kl1FJoV8KAtbRudZirY+34u/kcL1ksFtdIKRmkaYoxJpTdR2sMdB2dx7llXMOv+W/82TdrXJfcD3q8ONx2d7O3vt9Ha+2tnFvC/lL6yXXh9a7WxuvCPuefO7xPeFcehL7U9R36S4nj+FbJStVofb/QO42xKCmpjQnSIF4KI6w14cn4h+3Lb1vL/5qjw0QCfXZK7RyNc9TWMjg5myDijHmUBkSUMhMJF9M5UZwRJ1dh3ffFCt+fi4SkVHx7845XDx7y+tEGbzc2+AMUlNzeZVTmqgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/4e41232d62c7c9d974a76cd12da27b63/8ac56/57473c3768710af72a2b5f68f5455df1e6b12b88ec9f3e1659ccf22a99ae3368.webp 240w,
/static/4e41232d62c7c9d974a76cd12da27b63/d3be9/57473c3768710af72a2b5f68f5455df1e6b12b88ec9f3e1659ccf22a99ae3368.webp 480w,
/static/4e41232d62c7c9d974a76cd12da27b63/b0a15/57473c3768710af72a2b5f68f5455df1e6b12b88ec9f3e1659ccf22a99ae3368.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/4e41232d62c7c9d974a76cd12da27b63/8ff5a/57473c3768710af72a2b5f68f5455df1e6b12b88ec9f3e1659ccf22a99ae3368.png 240w,
/static/4e41232d62c7c9d974a76cd12da27b63/e85cb/57473c3768710af72a2b5f68f5455df1e6b12b88ec9f3e1659ccf22a99ae3368.png 480w,
/static/4e41232d62c7c9d974a76cd12da27b63/0b533/57473c3768710af72a2b5f68f5455df1e6b12b88ec9f3e1659ccf22a99ae3368.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/4e41232d62c7c9d974a76cd12da27b63/0b533/57473c3768710af72a2b5f68f5455df1e6b12b88ec9f3e1659ccf22a99ae3368.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Go to the details page of the ticket just created and you should see the app in the sidebar. The first time the app is loaded it will ask the agent for his VSO alternate credentials (this gives you full auditability capabilities since the work item will be created in VSO with the agent’s account).&lt;/p&gt;
&lt;p&gt;If you don’t know how to enable/set alternate credentials you can read more about it on &lt;a href=&quot;http://blogs.msdn.com/b/buckh/archive/2013/01/07/how-to-connect-to-tf-service-without-a-prompt-for-liveid-credentials.aspx&quot; target=&quot;_blank&quot;&gt;this Buck Hodges blog post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;206&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./5b229f53b323953a729fa8ecd36dbe4f70ed0e437978693281b60747c6ac3806.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 41.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABb0lEQVQoz4WQ22rcMBBA/eFN8l76OaU0oRT6EFpomstLKF3SwG72Zq/XtizbkkbSKdLGkLcOHDSDpMPMFF9+feD55Z6n1QN/V5d8vTvj0807ru7OM5dvyPXt2Yn7C65mHi74fHvOx+v3FIdSYSZBXCSIQIQgYAZQjaVvHX0rOe8ahxnJ4asBu+2wO5WRvab5vaLYbjdYaxBxiPdEIrvdhuvv3/h584OmPTCMHToxdIyTYpgUzfOC/XZN1x3p2iN60FR/nijKskREMtZZnHN47/HB4oMQguRzJtXGGfR2jXfCNE04a3HeM1YlRVVVWZYkSRZjpG1bdvsdxk6I2CwJwb8iWHFMZZlHlxizLIWp65Mwiay1mSQ+HA68rJcopVCqR2uN7jXGGGKI+bPdbHB1jTQNY2pKKYbl8iRMD1PriXEcCSGcFp9GT7yuJDHfpTH7x0f0YsHU94zHI3rucBbOZ+r4fyEhMNY1kzEY5zIp/wflmFxCUUUedwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/3923fd3be2954539468f99686b260cf9/8ac56/ae14833bc87e9399c9c254916178c0034416b84bfe550867f4b57dd90914b1b8.webp 240w,
/static/3923fd3be2954539468f99686b260cf9/d3be9/ae14833bc87e9399c9c254916178c0034416b84bfe550867f4b57dd90914b1b8.webp 480w,
/static/3923fd3be2954539468f99686b260cf9/b0a15/ae14833bc87e9399c9c254916178c0034416b84bfe550867f4b57dd90914b1b8.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/3923fd3be2954539468f99686b260cf9/8ff5a/ae14833bc87e9399c9c254916178c0034416b84bfe550867f4b57dd90914b1b8.png 240w,
/static/3923fd3be2954539468f99686b260cf9/e85cb/ae14833bc87e9399c9c254916178c0034416b84bfe550867f4b57dd90914b1b8.png 480w,
/static/3923fd3be2954539468f99686b260cf9/0b533/ae14833bc87e9399c9c254916178c0034416b84bfe550867f4b57dd90914b1b8.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/3923fd3be2954539468f99686b260cf9/0b533/ae14833bc87e9399c9c254916178c0034416b84bfe550867f4b57dd90914b1b8.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Fill in the agent Visual Studio Online alternate credentials and click &lt;strong&gt;Login&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;403&quot; data-orig-width=&quot;472&quot; data-orig-src=&quot;./cfe963931ded2b646177023d966b33ed96c7c6a5e808e0fb4a8091f4beba1983.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 472px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 85.41666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAAAsTAAALEwEAmpwYAAACnElEQVQ4y5WUaW/TQBCG83f7d0BFSFwSCFUqh9QPtOJIOAqVKB8AtaoCheZyErtxHK+9vo8HjR2nCQgJVno1I3vn3Xd2ZqcVhiHr0FoTBMH/IQyJ4pDecEorjmOiKFpBSNM0Jc9zsixb2caXf+u+IAwilK0wpnZN2GwSX2DbM4zxmMl4TH/QZzyeMBwM6A+GmKbJ2DAYDYe4ykNW9/iczu0PTEyHVlmWaN9HKUWSJBV838O0LDzP27gC3/eJ44hA66WfUJYFvtKYfZOp5dAqioLFYlGdLCmL2rltc3Z2hloq+JdVFCnm5aJW2Cy5l0alQNLXQVCpFEVBmhIkCWFlY+I8r3w/iikAa+7REiIhFTSEkpJyXXy/JhLoQLP4+JHRwQFmu43x/DmTly8q298/YP7mNebYqlO+kl0Trq88y1Cex2wywXrVRmmN4zgEQUhRlhR5Ha+/fME47dLK84K5F3K50PiBVDxZKS6rgBw5VIcho/sP6G1f53z7Ghc3tzHu3sK4c4vRvdtMb2wz+nZRp+yFCW4QEyXZSmFzt3me4SoX31XMXu3jDM7xRn3UsIf78zvej2+o4QVu5xm9z6ebRaEsq0KsE0pbVK8oCHH2nnL55CH23i7W44fYHzo4X4+Zn3zC7ezTO+luFkWwrnB12NLqoyN+tDv8PHzPvN1BvXlLFkakM5tSa6ZN21ypKTeLsk5qWfg7O0yOjjCPj1GHh+hud6OA1sy9UthYSVmKUBWjLj1pt4u3tYX76FHVWoVSpEpVHSB75RuUdWP/nl41JGR6yKM3DOa7u9jv3uFpTQTESUIkTZ+mawMlIk0SJtb8T8Jm+khAMJ3iz2bIJVQvRw6Sf+tY7s9SIXT+TlgFZhmJKFkSVfht3DVoCH8BuE8Qk/zs7X8AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/e76848fe620fa897126b2539e75ffe08/8ac56/7beee5217dda121925ed6966972d3d91f9f41bd32fe539a40cbe93940bc4c02e.webp 240w,
/static/e76848fe620fa897126b2539e75ffe08/ef93e/7beee5217dda121925ed6966972d3d91f9f41bd32fe539a40cbe93940bc4c02e.webp 472w&quot; sizes=&quot;(max-width: 472px) 100vw, 472px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/e76848fe620fa897126b2539e75ffe08/8ff5a/7beee5217dda121925ed6966972d3d91f9f41bd32fe539a40cbe93940bc4c02e.png 240w,
/static/e76848fe620fa897126b2539e75ffe08/3c5de/7beee5217dda121925ed6966972d3d91f9f41bd32fe539a40cbe93940bc4c02e.png 472w&quot; sizes=&quot;(max-width: 472px) 100vw, 472px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/e76848fe620fa897126b2539e75ffe08/3c5de/7beee5217dda121925ed6966972d3d91f9f41bd32fe539a40cbe93940bc4c02e.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;You should get a success notification.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;296&quot; data-orig-width=&quot;420&quot; data-orig-src=&quot;./1308897af648f9023681d93724b04ddf91354c6a42d34adb3529ec19025d3b1e.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 420px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 70.41666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB70lEQVQ4y6VSy27TQBSdJd+BVPZ8G2LVP6Cs+gNlwZ4mElJQu4ANDTR9KG2TiNh5OIljktSJ4xl7/Dzo3mQokSqEqK2je+beO2d8z1i8fidAeHUksP/+Gb50jvC9X0PdruLMrnI0+GpVHni3gjOrikvnE65GNVwNT3F6ewhxcLyHg+MXePPhOQ4/vsT15DMunAYawzrOB3VcjM7RGH7DndfE3c8m2rMbtGe3vG7NbtBfdeFIG240wfWkBhHpNQixDhHpAHPpwg2GmAYOvLXDkTBXLhbRFAu1BXOX87bbRrPbwOR+AKF1gj+R6BRpsgHzLRKqxwlHwwnU57kerB8WfH8JoZSCihSkDCGlRChDBvNwE03ecLntUWqz1olm+EsfIo5jaK0RRRHSNAU9RVGiKIotL37zPM+Zl2UJlCX3Z1mGSEZYLQLWEJQkQcLK99G1bDiOg0G/j1arhfF4jEG/h067A286hW33uG7ZPWRphhwZLk+aqLw9Yct4ZBIlJEnCY7INSiEINqcaLtWaR1RSYr0OkWc5ShRYzgKMOx7vF6PRmJtI0Iz22JMVCvehRSbsFsoHShqC/CAhUv+bYElv+Xh94+lW0BhPHtIFkTBxigb/uqb9O4LkFyWfAmF+C3OCufH/hZgvQyzDeEfwKV/4C84xIXLtDuHZAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/23636efc43da24683bd6973ed745c8ed/8ac56/98ba9c36807518e4ea8bbff6184220effc16fd876fdb50d8bbed42854e86d3fa.webp 240w,
/static/23636efc43da24683bd6973ed745c8ed/ce09e/98ba9c36807518e4ea8bbff6184220effc16fd876fdb50d8bbed42854e86d3fa.webp 420w&quot; sizes=&quot;(max-width: 420px) 100vw, 420px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/23636efc43da24683bd6973ed745c8ed/8ff5a/98ba9c36807518e4ea8bbff6184220effc16fd876fdb50d8bbed42854e86d3fa.png 240w,
/static/23636efc43da24683bd6973ed745c8ed/d10fb/98ba9c36807518e4ea8bbff6184220effc16fd876fdb50d8bbed42854e86d3fa.png 420w&quot; sizes=&quot;(max-width: 420px) 100vw, 420px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/23636efc43da24683bd6973ed745c8ed/d10fb/98ba9c36807518e4ea8bbff6184220effc16fd876fdb50d8bbed42854e86d3fa.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Since the ticket is not yet associated with a work item, you obviously don’t see the work item, but you can now see the actions that will allow you to create a work item associated with the ticket.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;New work item&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Now let’s create a work item from a ticket. In the ticket details page, click in &lt;strong&gt;New work item&lt;/strong&gt; button.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;188&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./ccfa4ac6c244215121d34229676a026fa57042dff34a51ae8383e6c705766200.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 37.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABWklEQVQoz32Oz0ocQRCH5wHzCmEj5O7bePABAhq8esgp7BrCYoyKF2FjUHTVjc7OzM70/+75pNqMzMmCr4vqqt+vqrhenrG4Pebv1ZRv022+zD6yN5uwdzRh/8cnvr6xlZE/6eW+5NmEg5+f2T38wM7+hEK1BqUctu6IlSJGSAGCA9UGNrWlrV3OTWXQXQKZieCF8Dq/fu5Y3qwonLMYo3HBk+jRWnF+ccp09p3Fn0vqZv2fkqpes2lrOr2hK5+4P55zf37Kv4clnW6pVhVFjBEhhJBxzrF6euTh8RalWlIKxBRyHnDBYnWLvbtDzed457IupkjhR0aDqUTqA30vyzwxvRKiy3RGoa3Bp4Qty6zNWEchBsOVKSWMMZz8/kVZPtM0DVprrLUZmen7Pi/03ueecS5rBgpxHgQDSnU5a6VRSr0hAjEdDKW2wkhbyDPeIPV7Mb5wmDcj0xetg1k3RPKZ2QAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/aead825b550858ec5ba4422da06c6388/8ac56/09fe759081a7c1ce5217ae04415c9dbf3c108daf668e70ade761ea38e218048d.webp 240w,
/static/aead825b550858ec5ba4422da06c6388/d3be9/09fe759081a7c1ce5217ae04415c9dbf3c108daf668e70ade761ea38e218048d.webp 480w,
/static/aead825b550858ec5ba4422da06c6388/b0a15/09fe759081a7c1ce5217ae04415c9dbf3c108daf668e70ade761ea38e218048d.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/aead825b550858ec5ba4422da06c6388/8ff5a/09fe759081a7c1ce5217ae04415c9dbf3c108daf668e70ade761ea38e218048d.png 240w,
/static/aead825b550858ec5ba4422da06c6388/e85cb/09fe759081a7c1ce5217ae04415c9dbf3c108daf668e70ade761ea38e218048d.png 480w,
/static/aead825b550858ec5ba4422da06c6388/0b533/09fe759081a7c1ce5217ae04415c9dbf3c108daf668e70ade761ea38e218048d.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/aead825b550858ec5ba4422da06c6388/0b533/09fe759081a7c1ce5217ae04415c9dbf3c108daf668e70ade761ea38e218048d.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The app will open a modal dialog in a loading state while is fetching some data from VSO, and then will show the following form&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;336&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./bf7cb3ebbef4d4aa30a00ed5da9f04b7e819a4c50b9e7642a99067f6aac637b3.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 67.08333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAABlUlEQVQ4y4VTS4rCQBDNgRTdObPSceEFFBeu3Cp4EOcQBhEMODiKnxuIigfwCupCMDH/3xuqY8U4Rix4VHd1+tXr1x0pl8vhu9vF72SCfr8v0OvJkGUZw6GC8XiMxWKB+Xz+hNlshul0iuVyicFggI+PT0jZbBa73Q4UQRiK7HoePM+DYzsIb7V3cb1eUS5/QcpkMthsNqLo+74goEXDNOG6LkzTxPl8FjAMQ0DXdVH3bo0pDocDSqVSpDBJSOE4TjwOgkDMCTSmSKrm2ul0uhOu1+snQiYgEAGB1SSDyVMJ6YicLxcVlmXF5ASa0xo15mYsIiYkD5mQNlHQRvJR07QHqKoqsm3bsX8sIvYwSUhE7AsfMw2sLqnweDzeCf/fchgGKV6lPxf28CVh9A592I4H243g+8FLpbzn4cir1UoU2RvDsqHpJjTDEtl2nNgvAvvH1vClFIvFiHC73T68qXdBqqj5fr+Hoij4GY3Er1ipVCDl83k0Gg10Oh20Wi202+23oO8IzWYT1WoVtVoN9XodhUIBf8M6iL1A6aaTAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/2211a2ccf78aeebce633b70cd9185c9a/8ac56/a60120ea64a900ccf7e6cc537dbcdb3a1022a759014516812205de193a6dcc98.webp 240w,
/static/2211a2ccf78aeebce633b70cd9185c9a/d3be9/a60120ea64a900ccf7e6cc537dbcdb3a1022a759014516812205de193a6dcc98.webp 480w,
/static/2211a2ccf78aeebce633b70cd9185c9a/b0a15/a60120ea64a900ccf7e6cc537dbcdb3a1022a759014516812205de193a6dcc98.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/2211a2ccf78aeebce633b70cd9185c9a/8ff5a/a60120ea64a900ccf7e6cc537dbcdb3a1022a759014516812205de193a6dcc98.png 240w,
/static/2211a2ccf78aeebce633b70cd9185c9a/e85cb/a60120ea64a900ccf7e6cc537dbcdb3a1022a759014516812205de193a6dcc98.png 480w,
/static/2211a2ccf78aeebce633b70cd9185c9a/0b533/a60120ea64a900ccf7e6cc537dbcdb3a1022a759014516812205de193a6dcc98.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/2211a2ccf78aeebce633b70cd9185c9a/0b533/a60120ea64a900ccf7e6cc537dbcdb3a1022a759014516812205de193a6dcc98.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Fill in the form fields and click &lt;strong&gt;Create work item&lt;/strong&gt; button (the fields should be self-explanatory).&lt;/p&gt;
&lt;p&gt;Notice you can choose the work item type; the available work item types depend on the process template where the work item is being created.&lt;/p&gt;
&lt;p&gt;The summary is pre filled from the ticket title, but you can change it if you want.&lt;/p&gt;
&lt;p&gt;The description is not pre filled, but you can copy the ticket description, by clicking on the link “Copy the ticket’s description”&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;319&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./4fa35df2728e3ce1dda260dd2f9177f1266e3237d789efdc02f603238bd16697.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 63.74999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAACkElEQVQ4y2WS3UrbcBiHvRsLOvAaPNODnQ53CwOt8wq2YxluMBAZKI5N52GdOGRr13VVhl9LjRatFsHaf5K2aW3SfCfPSLrp5l54+L0k5Pd+ZWBxcZFqtUqpVLpFkiSOj2XOKucITUP5hwaKqiKEoF6vU6vV6HQ6zM/PMzg4yMDm5iZxRFGUqOs62I6DE6thYOs6druNpetYrRa23sIxDIIg4O9YW1vrG25sbCQPfN9P1LZteoaR5FalgpLPU9/ZQT84wCyX6ezt0ZVlgigiCsPb71ZWVv41TCpGEaYsY1arOFdX9MplbnZ3udnfT+j++IErBH63eztV8L/hx36HsaHn0cxkUD59ov3lC91CgW6xiFEs0s7n6eRy3I8wDBNd/fDhrsO4kuM4yQtjfx8tm6VRKNDe3qYdmxWL6N+/08rlcIQg0HWCVivBbTbBsni/tMRgKnU3suu6ycjG4SHa1hZaoYCay6F+/donzvN5Gt/6hTq/0be3cXd2WH7xgtTw8N3IPdfFFwJdllBlGfWnhCpJaKUSmlRCKx0leePoCP3kJKF1fEz79JSgUmZ5bu6PYb/DeBOeEJg3Tez4wo5LLwgxw5BeGGF6PqbrYXk+/n+LdFl+OUdq6J6hryi0T0o0Lyq0zs9oVE4T7V5ecHNx1ufygk7tEqMhsJRrTFHDq1V5+/o1qaEhBtbX1/s79Dx8x8HSNLqijqHUEzVVgaUpWA0Vq6FgSoeYB3vY2c/YZRnztAzimncLC/2jZDKZ26PE/2LcafQX4T18y8JUVdRsltVnz3kzO8vqq1e8TKcZfvCAgYmJCWZmZpiamiKdTpOO9T7p38T59DSTT5/yZHKSx2NjPBobY2J8nIejo4yMjPAL2Nl8xKO1LcQAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/8f3c471b0baa6b79172b6b7ef862da49/8ac56/7c42fa66d190be95f5182e4d6f8dc824fe35219480dfd8067cc468085fe479fc.webp 240w,
/static/8f3c471b0baa6b79172b6b7ef862da49/d3be9/7c42fa66d190be95f5182e4d6f8dc824fe35219480dfd8067cc468085fe479fc.webp 480w,
/static/8f3c471b0baa6b79172b6b7ef862da49/b0a15/7c42fa66d190be95f5182e4d6f8dc824fe35219480dfd8067cc468085fe479fc.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/8f3c471b0baa6b79172b6b7ef862da49/8ff5a/7c42fa66d190be95f5182e4d6f8dc824fe35219480dfd8067cc468085fe479fc.png 240w,
/static/8f3c471b0baa6b79172b6b7ef862da49/e85cb/7c42fa66d190be95f5182e4d6f8dc824fe35219480dfd8067cc468085fe479fc.png 480w,
/static/8f3c471b0baa6b79172b6b7ef862da49/0b533/7c42fa66d190be95f5182e4d6f8dc824fe35219480dfd8067cc468085fe479fc.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/8f3c471b0baa6b79172b6b7ef862da49/0b533/7c42fa66d190be95f5182e4d6f8dc824fe35219480dfd8067cc468085fe479fc.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;While the operation is being performed you should see a waiting spinner, and when completed, you will be notified and the work item is now visible as being linked&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;484&quot; data-orig-width=&quot;383&quot; data-orig-src=&quot;./e0340f57d3565ccff6135d6a5bccb9d9534db823d44eae873ad1aa7ab0b85fa5.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 383px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 126.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAZCAYAAAAxFw7TAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEXUlEQVQ4y52VXW/cRBSG/Rv4OfwBrvgRgIS4QELiigvgolBUgQAJSEVL21SUhpKoEqFSk26yLekm2tB8NeSjTdLdfKzXa3v8vV6vvev1AzObVG1URNWRjt5zPOPXZ+a8Z6wt/fople/fZ+3aOXYnLrEzfoHd8YvsjF98iju/XWDr+ggbv4zw8OfzrIx+zYPLXzI/cpbV0W9ZvvwNK9e+Y/OLj9DOfajx7ojG5PZnrIvHrFhLrIk11p11lq1lVu1V1uw1VqwhrjsP2fQ32evsUevW2Ovs8iR6xDYtnlw/izbx1ev8cO41Kr9/wM69MTZnLrM1e4Xt8igbpUvKf3T3Ktvlq2pue3ZUxfsLNzisjlOvjFH78xpPViepn30PLb34E+KH84ijOvbfS4itVWX2psQ1xObQV/HmKtbGCv7uBj+e+Zh33nyDuYnrPLxzi+rkBEd/LaAlb7+FuHGDHtDLCzKJx/asfxKnA9SYvD3NJ2c+53Gtjul67OsGca+PJsbG8EyTOI6J223iuD3E0/4p6/d6UBSk3S5JkhCFIYHnoYW6riaDMMK2BUVRkOc5+WBAv99T/kD5feWfYJZlikhiPuiTdBPa7TZakmWkaYpt2ZiWhes4CCEwWy3CMMI0TeX7vo9l2wrlhzudDsWgIMtTylfmWZveoqBAy9KUbpKg6zqHh4fYlkWj0eDw4ADhuBweHbG/v4/rOjSbTYRtU6/XCaNInWVe9FkYX2Lj7mMGDNBUynmuJgPfV9l5rosjHKIoohPHuDJ2HDzPU/PyHfm82dAJgoCTIXeqMsz7/aeEtm2rbctM5ZnIw7bUtk21/ZZhEMoC+D6GzFgI0m5KMRioAmm9fp9eUXDU0NGbLfwwxLRs3CBENwwc3yft9XmZIXm0nu/jTU9jTE3Ruj2FM1PCvjONKJUwp6YQpTuE9+4SVyrElft0KvcVJvOVp5gszBOVywRzc2i9Wg1RLquU246H2RQYTYEvPFzbU/7BQQvLsGk1bRpHJoZuqWeGblOrG+wftEiFg3frD7RMVvDBA5XygR2x0fBZ3LNYPXSp1gTL+w5LNZvFPZuaFdIQAV4nxYxS3E6GESTKL/IBQbmM1qvXcatVRdiO2jiuTxDFCC/A9UNcPyCOO3Sz/znHPMcvzaBlzxAGrqM0KKtqNHUlHUcIVUlZcdkZnU5CJxl2RdLtKoHHsmPimGB29nlCKRGpNdkJkkRqLH5Gh0qjno/jOiqW8pEyczyPvNslmJk5teUwVK0lBX0iYs/3VZaSVHaLHwQqlijXqQ85zosJu50Yx3FVZpJQ4pBoaJ4SvoUt7OFxOA5Gq4XnBy8mjNuR6hDVLZLAc4+36SlfYpJ0VYvJ9suOL5b+YDAsiiKUsqlWKaTS01QtOP1CmnbpHcdqYVE8Z/LKI8uOCWs13MVFte5lRvEfJomDUgmtb5rYExOE8/OEc3OvZpUK0ews1s2bw8shlFXTdfxm85XN03XCf38B/wADxypH5KrKTgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/9d2fc5c48223f8dfc06bbe56c84c03b4/8ac56/01d7bfd9e40bb93fa3b01f043a9483764dd294fbe0b9c27da7c29cf27a8cc534.webp 240w,
/static/9d2fc5c48223f8dfc06bbe56c84c03b4/8c481/01d7bfd9e40bb93fa3b01f043a9483764dd294fbe0b9c27da7c29cf27a8cc534.webp 383w&quot; sizes=&quot;(max-width: 383px) 100vw, 383px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/9d2fc5c48223f8dfc06bbe56c84c03b4/8ff5a/01d7bfd9e40bb93fa3b01f043a9483764dd294fbe0b9c27da7c29cf27a8cc534.png 240w,
/static/9d2fc5c48223f8dfc06bbe56c84c03b4/d0c94/01d7bfd9e40bb93fa3b01f043a9483764dd294fbe0b9c27da7c29cf27a8cc534.png 383w&quot; sizes=&quot;(max-width: 383px) 100vw, 383px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/9d2fc5c48223f8dfc06bbe56c84c03b4/d0c94/01d7bfd9e40bb93fa3b01f043a9483764dd294fbe0b9c27da7c29cf27a8cc534.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;If you click on the work item title in the sidebar, a new window will be opened in VSO with the work item details. Click on it to the work item in VSO side. You will be able to see how the work item has been created correctly (Id, title, description, work item type, tag and link).&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;273&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./a0cd0e6aaebe3b686a9580c26b1c91ded503faf49a55762a3896f533909878db.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 54.58333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAABg0lEQVQoz5WQ627TQBCF/f6PgwL/eAKgQNKSFkFFSxI5sdfXtfe+H/ImdkXVCmHp04yPds+c2ezdesebdc777ZHV+sBqk/P2+riwSuRJX7h+nUxpRy8HrOqJVgMeiEC48H9fJuqWqq5o+5ZRG2QvGZTGOI82FudDYuqVsWjnF+0lsrwQtFITXMAqTX8qqU4lzlgIAWJMk0MItG1P0w3pP76WcJcLKqkZ8iPVZkN59Zndh48cPl1x/PKV+u6OUU6pFeWvR4rb74xqZBxfJguXBNZ5RqWTqLXGGMOoVKpTukSMqXrvn7RnZHNU5xxl3dG0XTKc8SEQY/yLtPIzbSabD0yXm6ZBTamsQZszs2G4XJgGW2uJ4R+Gk8kgJVopvHOEaS3vU++cTUz9NLjrOrq0iUnmLp05sxiORcHv9Yb9ty2H7S3Fj580D48XHpba7fcIIdI2Tdsj5XB+HqXSdouhbRp0UaJLgSpLtBDYuj5TPWGqCtn1NPf3iJsbqu02VXk6pSf6AycOTcvSC3VGAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/1f5b85394c347db6b761b20220f04acb/8ac56/14ba4dca1fbc9ce9492197411247e7107b77d9bacad49d10e9102e410707756d.webp 240w,
/static/1f5b85394c347db6b761b20220f04acb/d3be9/14ba4dca1fbc9ce9492197411247e7107b77d9bacad49d10e9102e410707756d.webp 480w,
/static/1f5b85394c347db6b761b20220f04acb/b0a15/14ba4dca1fbc9ce9492197411247e7107b77d9bacad49d10e9102e410707756d.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/1f5b85394c347db6b761b20220f04acb/8ff5a/14ba4dca1fbc9ce9492197411247e7107b77d9bacad49d10e9102e410707756d.png 240w,
/static/1f5b85394c347db6b761b20220f04acb/e85cb/14ba4dca1fbc9ce9492197411247e7107b77d9bacad49d10e9102e410707756d.png 480w,
/static/1f5b85394c347db6b761b20220f04acb/0b533/14ba4dca1fbc9ce9492197411247e7107b77d9bacad49d10e9102e410707756d.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/1f5b85394c347db6b761b20220f04acb/0b533/14ba4dca1fbc9ce9492197411247e7107b77d9bacad49d10e9102e410707756d.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Notice the link to the ticket on the Links tab. This not only allows the Service Hook to determine the association between the work item and the ticket, but it will easily allow the developers to go directly to the ticket Zendesk if they wish too.&lt;/p&gt;
&lt;p&gt;Remember, if you delete this link comments made on the work item (using the keyword) will NOT be propagated to Zendesk.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Comment work item in Visual Studio Online&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;For the work item just created, let’s make a comment in Visual Studio Online&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;146&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./ffb49b72b254c45a532912ad43ad3a3a3d750d9b0d3a8489619239b3504ed243.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 29.166666666666668%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA8ElEQVQY01WPvW7DMAyE/f4v0u6Z8ggB2iQdkqBLg7qZLPlHIi2JEikWsWGg/QYCPNwBdw0EUtXCPDkPAJQLUSql8AYRhRBE5Pn80Zm5mRyoKjMDeCLyzqeUcs6qKiKqmnN241RFRjsYO1bVutHUWmUhhIiIfmFGjAuUEmVyABOAd96ez75tQ0ozIuLcICIzi4gxpm2/H4+f3vZdZ6y14zDMRND3j+Pp63i8Hw63l9fP3c503dAPxtgmxlhKWRv+o9bnRQz7vX17t+eP6XLprzd3velmbojy2nydsaTqmpQY4+lE9/tTKSUCSErKrNvsX7jjV2Jh8whzAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/f4f7f7189a94c603c4d895fddcbf75e9/8ac56/e70cf01aa23016dfbafb7894e56f6eff54c41fc01430dd67fa17c68a6507b7b1.webp 240w,
/static/f4f7f7189a94c603c4d895fddcbf75e9/d3be9/e70cf01aa23016dfbafb7894e56f6eff54c41fc01430dd67fa17c68a6507b7b1.webp 480w,
/static/f4f7f7189a94c603c4d895fddcbf75e9/b0a15/e70cf01aa23016dfbafb7894e56f6eff54c41fc01430dd67fa17c68a6507b7b1.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/f4f7f7189a94c603c4d895fddcbf75e9/8ff5a/e70cf01aa23016dfbafb7894e56f6eff54c41fc01430dd67fa17c68a6507b7b1.png 240w,
/static/f4f7f7189a94c603c4d895fddcbf75e9/e85cb/e70cf01aa23016dfbafb7894e56f6eff54c41fc01430dd67fa17c68a6507b7b1.png 480w,
/static/f4f7f7189a94c603c4d895fddcbf75e9/0b533/e70cf01aa23016dfbafb7894e56f6eff54c41fc01430dd67fa17c68a6507b7b1.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/f4f7f7189a94c603c4d895fddcbf75e9/0b533/e70cf01aa23016dfbafb7894e56f6eff54c41fc01430dd67fa17c68a6507b7b1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Notice that we started our comment with &lt;strong&gt;Zendesk:&lt;/strong&gt; which means that the subscription will integrate this comment in Zendesk (this was previously configured in the Service Hook configuration, if you used a different pattern then use it accordingly). Go to your Zendesk app and open the ticket, you can now check the new comment is there&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;168&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./e205bc709fb5bf36271ed7992488afd1e705593ead9d3834754e920722d86499.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 33.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAAsTAAALEwEAmpwYAAABBElEQVQY02WQz07CQBCH+/6v4Bt4NcSjBwQVDppgND0UopGWpLHAzu7O392aggSMX77DzGFmfpnCOQcAqmonmLlt23pdl2W57bbOgfcBwAMA+OA8qiozE3ERYzxOpgM55xDiZDp+eBqPRjdN8+X9njggBeKIHBBBFEME8LsCcdikqiLCzMfCTNSw7/ucLSVNJimdNZOcjcUXIYTjZT5gZiLS970m4USa5L+WFTDuMQ6x0wU5ZyKez2fNsnKbDXWdOZcAsveXGoDt9r+x5YSKINH766KZ3HZvd9+LO1fe8+qRLq2mtHmW66sh9uF1Z4Y2RvyouF7iuqJ6Kc3qj/VS2k95mf0ADYKNW9UAbtcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/ecd9f5fab10af2c911974eb0db2f16fe/8ac56/48cc5b4158c0e5abcfd5e5a6cced4b0784f379c80643c7b0d630955922d5b735.webp 240w,
/static/ecd9f5fab10af2c911974eb0db2f16fe/d3be9/48cc5b4158c0e5abcfd5e5a6cced4b0784f379c80643c7b0d630955922d5b735.webp 480w,
/static/ecd9f5fab10af2c911974eb0db2f16fe/b0a15/48cc5b4158c0e5abcfd5e5a6cced4b0784f379c80643c7b0d630955922d5b735.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/ecd9f5fab10af2c911974eb0db2f16fe/8ff5a/48cc5b4158c0e5abcfd5e5a6cced4b0784f379c80643c7b0d630955922d5b735.png 240w,
/static/ecd9f5fab10af2c911974eb0db2f16fe/e85cb/48cc5b4158c0e5abcfd5e5a6cced4b0784f379c80643c7b0d630955922d5b735.png 480w,
/static/ecd9f5fab10af2c911974eb0db2f16fe/0b533/48cc5b4158c0e5abcfd5e5a6cced4b0784f379c80643c7b0d630955922d5b735.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/ecd9f5fab10af2c911974eb0db2f16fe/0b533/48cc5b4158c0e5abcfd5e5a6cced4b0784f379c80643c7b0d630955922d5b735.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;View work item details&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;You can view the work item by click on &lt;strong&gt;Eye icon&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;396&quot; data-orig-width=&quot;372&quot; data-orig-src=&quot;./8b774aae603bd324504990506955525a77d8e9de54e2c520eb5c9c2a3585d930.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 372px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 106.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAYAAABG1c6oAAAACXBIWXMAAAsTAAALEwEAmpwYAAACvklEQVQ4y61UyW7bMBD13+Yrcm8/IIcWyC1fkFtzKdBeggZoG9hO4kWWLMmWLXGRZEvWylfMJHLsdAHalMDziOT48c1C9rIsw263Y+R5vv/+GzSmQV7kUEqhRyRVVaGqarRti7IsUdc1r5GledM0qKqSfeibQHuMpobT9xjk26MfEYUYDvqYWBZm1gyD4QD9wRAL38P3b19xdz+C4ziYTKaYjicYDoeIhASNbJfh6v0nXL37xCJ6JLlTRmrJ0lqx27FDURQMWi+L8mhO+03bIBEbxGH6SEgkNGji2DZsx2ZrWRaU0lguFqya1m1rhunUgtYaSkqM7h/guh6qumIODpnU1HWFPH8uChWKv4uCLSnq8trl9tASTGuec6iVwng8heu68D0P7tx7VGY7WC6XyLLHKNC2gDH43dgrPBy/8jdti9YYNMQJoKkb1F21ueIN7x8QGt6YrWLcuxH6c4FpoDH0JG6tFW5mEUaTBawPHzH6fANHbHHnSszDFA+eRH8eIa9a1F2VibBpW8yCGFYQo+9K3NoR7nyFsS8xEhlGXwaYvXkL++ICBRWxrFA3Laq6QVk1MIchU5jGtNBKcgXTJEb8ZGkt26Qcep0kqM7PgST5cw6NMYzVaoVgtYK/WGKxWEJKCaUVwjCEEgJEW56cQJ+egto6VQpJkkDHGpvN9rgPiZAVxjGiKGIkSYo0TbFer3kupIQIAkRnZ1C+jzhN977d5ehtNhsEwZpJSRERpJ1jGHIKwiiClAqC7G4HeX0NcXmJuCzYhyKj1qK+7G23GcslhUQupeBXg5TGccyHdKppHq7XWEcRQs9HJCIm0zrmOhz1IfWa1orD49wpBSEkHyDE0yFac2jUf4b7vGWYp+b9qSidwyG656qbd/l+iT0hFaX702tAh9Gd73WX/3+Aot0T/svT/xJHCruF1yr8AUeHS1r5VnE1AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/8c9e9712ea5f4a45d7772f94dd63524b/8ac56/c8c7c6e1acee41828c0a1dba858af249ad57d6f9ac138f06dc579406d764d4a0.webp 240w,
/static/8c9e9712ea5f4a45d7772f94dd63524b/7fd57/c8c7c6e1acee41828c0a1dba858af249ad57d6f9ac138f06dc579406d764d4a0.webp 372w&quot; sizes=&quot;(max-width: 372px) 100vw, 372px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/8c9e9712ea5f4a45d7772f94dd63524b/8ff5a/c8c7c6e1acee41828c0a1dba858af249ad57d6f9ac138f06dc579406d764d4a0.png 240w,
/static/8c9e9712ea5f4a45d7772f94dd63524b/98b6e/c8c7c6e1acee41828c0a1dba858af249ad57d6f9ac138f06dc579406d764d4a0.png 372w&quot; sizes=&quot;(max-width: 372px) 100vw, 372px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/8c9e9712ea5f4a45d7772f94dd63524b/98b6e/c8c7c6e1acee41828c0a1dba858af249ad57d6f9ac138f06dc579406d764d4a0.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;This will pop up a modal window that will allow you to see a work item a detailed view without leaving Zendesk&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;281&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./439eb95021a2716b558f306466237075c6bb842292403b5cc2ed5cd34f728b5f.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 56.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAABmElEQVQoz5WSz2rCQBDGfRcVEbTgwYM3FXwKqYoPIkK9qBEsiFcVD76UF3U1bmxqmz8mMYlf2YlJbUtpHfixmdndbyYzG8tkMqjX6xgMBug8ddBqtdBut9HtdtHr9SBJEiH8fr9PiHhfkmgdDp8xGo1QqVTwkM0ilkgksFgscPF96LoBYY7jEJ7nwvU8uK4Ly7JwPp8Jx7bheR6dCa3ZbCKVSgWCk8mENt81DZfLBb7v/+C3uEggrFarIZ1OB4Kz2YwEVVWFaRhwrof+sjCJsMfvgqZhwjRN2LYFwzAIXdcjbv1w37LsqEIxhxvBKU6nExRFwdvxjSpVuEK+4HB4wYHWAzjntM+5AlV9xfF4pCobjcan4Hw+pywiu6Zp2O122G4Y5J2M9XoNxhjYhmHLthHr1Qr7PYfCOd2NBOPxeCQY9kT0M5imE3Cdevht2/b1FXhRP7/88nQ6paB1Cp6GeCb/QZwVfReFRFNOJpMYj8fUZFmWqUf3sFwuwdgW1Wo1EMzlcigUCiiVSigWi3cj7pXLZeTzeQitD2HjxxazaDpyAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/cd2182878673a0328c40b2d33cb5195d/8ac56/ba8de716042da494e24f4073e13697d171ed45e588ed196e1d251e2eab71b28c.webp 240w,
/static/cd2182878673a0328c40b2d33cb5195d/d3be9/ba8de716042da494e24f4073e13697d171ed45e588ed196e1d251e2eab71b28c.webp 480w,
/static/cd2182878673a0328c40b2d33cb5195d/b0a15/ba8de716042da494e24f4073e13697d171ed45e588ed196e1d251e2eab71b28c.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/cd2182878673a0328c40b2d33cb5195d/8ff5a/ba8de716042da494e24f4073e13697d171ed45e588ed196e1d251e2eab71b28c.png 240w,
/static/cd2182878673a0328c40b2d33cb5195d/e85cb/ba8de716042da494e24f4073e13697d171ed45e588ed196e1d251e2eab71b28c.png 480w,
/static/cd2182878673a0328c40b2d33cb5195d/0b533/ba8de716042da494e24f4073e13697d171ed45e588ed196e1d251e2eab71b28c.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/cd2182878673a0328c40b2d33cb5195d/0b533/ba8de716042da494e24f4073e13697d171ed45e588ed196e1d251e2eab71b28c.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;You can customize the fields visible in the summary view and the detailed view by clicking on the &lt;strong&gt;Cog icon&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;484&quot; data-orig-width=&quot;390&quot; data-orig-src=&quot;./efc0d9d81e34dbdfc0e68b34ad414ffc0e36d8be7657ee452c8effcab2ec150f.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 390px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 124.16666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAZCAYAAAAxFw7TAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC+klEQVQ4y81Uy27cNhSdf8yHpOgfpNt+QtdBgHbTLm20RQMENVB708KJi2jSOIlHTz4kURJJPXiCQ83Yk7oIAiSLCji4lxJ5eO5LG+ccPhnzjMFaIAScPXuGrx4+xOnJCYo8x4vnLyClxKbrOnwybm7Qdx36EDAAcCHA0ncenTFQSmFjrcUwDJim6RYzMc+rP89xPYUAd3aG4ckT+NNTTI8fw263cJeXmNoabhrRdQYbkjGcuq6htUZT15BSoaoq1HUDIQTKskTbtqi0gtY1yt+eonrwAOLRI7z++QRPv/kOv//4F9xgsRnHEQTzkCQvkaYpdrsdkm2CNMvx5voaSZKgKEqkuxukaYZ/djuky4L5/AKvfvgeP339LS5O/obtBmwYFhXyoRVVFZUyH7TOWmilo6+VioqZr8k7pFdXePXLr2iKLJ4fR/8hIcMviyKGSKukgmlbFHmBPM+RZVmEVCqmIOPepoH1HmEJ8OPIkKfILISM4dAyh2seBSoh0DQtPvYsS9grHA859DCmi2GatonojdnbFqOz+6PhCDiy6xMVHoc8LgGqc8hUH63qPVI94G3VIlUdCt3hXWVQNQOuywaZ7vC2bJGkGm5im/2LUBuLP19XuHwjcL4t8Me2wHmS42JbRFy9E9iVCqLuUNQ9pLHRptJgmhdMVOjGCd6vhN6PKIRC3RiUUqNSDaSq0bQtrBuxhI+mch/yPN8q9M4hz7JY4aIoIIVYIWVsfF7MWeZ09X2PYbCwzsWxdM6vRVmOCFkcTgiLw0am5TixB9n4XJNc7C859CrbjBwr4bLcIzTGxANVVULXdSSgL0iidVyTrGma2JO8nKpZjw8I+SPQWkEpCV038ZCQIs4v3/ESgk2++iL6vID5v6fQe7+qEQx7HT8qJlalEoefCQm4n8pIdNvYB8IQQlTonIXzPhaABw5tdQD3rT19V3K+I+4R0g9HG+5w9457/gv8RgGRkGHYfTt8LiIhHao82M/BrcID4RdReEz4xRX+7wjfA2rMf+ijix0XAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/b507ff562f245068be635ceb03538b9e/8ac56/14e3412d5df117864431663b2a8d71c043df0880bfbc9c419d8f7cd7230dc79b.webp 240w,
/static/b507ff562f245068be635ceb03538b9e/a9b47/14e3412d5df117864431663b2a8d71c043df0880bfbc9c419d8f7cd7230dc79b.webp 390w&quot; sizes=&quot;(max-width: 390px) 100vw, 390px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/b507ff562f245068be635ceb03538b9e/8ff5a/14e3412d5df117864431663b2a8d71c043df0880bfbc9c419d8f7cd7230dc79b.png 240w,
/static/b507ff562f245068be635ceb03538b9e/727ba/14e3412d5df117864431663b2a8d71c043df0880bfbc9c419d8f7cd7230dc79b.png 390w&quot; sizes=&quot;(max-width: 390px) 100vw, 390px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/b507ff562f245068be635ceb03538b9e/727ba/14e3412d5df117864431663b2a8d71c043df0880bfbc9c419d8f7cd7230dc79b.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;You should see the following page&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;734&quot; data-orig-width=&quot;446&quot; data-orig-src=&quot;./d6382a8121b0d505332b54b19c1a5241a5d18938d9f99669b8a7ea2fd116b5f4.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 446px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 164.58333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAhCAYAAADZPosTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC6ElEQVRIx51WyZaaUBDl/z8if5F1lllkk2U6RtHGAQGBx6SPwZtzCwtpWu223zl1qsTi1q3hlTqn0wmU4/GIqqpEPyN8p25qVKcSm80GzvgLaoLXdQ0NdLJ2sOvaig+/pzR1g7ZrEXgR1n92CMIATtM0aNsW1vZAhyiC67oIghAr18VyucJ+7+Pl5S/Wngd3uRI9m81gbQ2eX99/48e3nzjEEZw0TXGIY2FA8DRN4Ps7+P4eQRgiiiIEQYCiKCUwhX4M3nYdzuezfDbGIAxDOGmSyAtVdRRnf7fFv9kM8/kci4UrbGmnJsOjQ1DiOPqAYGT56HRdJ3q73cJ151IWZjRfLJAkiYhDykrbWiupZFkmUpYl8jwXTZ9ulGKeZ6ibRp7Rh8/oNzDspDF995IklWh5XogmOI8Gp7Db1DxqF0UBJ84qUPKKTekB2SiTGmTGDOmOwShko4zVFoZhWiEyFfKjFUDWkawISs3oLMVUyJq+alMLwyuFTtgVeY71ei2F5+T7vi+OrBOFNgE4TvqZtvoMTSFlAjISmTFlzlZzmT2VPrUKnrcRm88IRC0MtbAKONTQGGEyrZ0GH9fwTVPeAVqLw+EgLDmojP6oKTw6VtIUBaRmum3bSKTevqY5FS6TqX035SRO3t0aTe/DsblXw8xk0nHabML4pmi99LPaNwGrssBq9Qrv1UMYRuKka2p86Kvv0uZ5k/K1hq2A9Au3H9zTZQmzDFpTPtca0r7f5fraZY4NdRzHsnipCfhUyv1y6AebI2MyM4zHeHyeaooC0oHRm8ua+vLYMDWCjc/Tg62AzWXBlkUhkdsbQ01hk6b2TYZML8v6+h2ZijDii/fvstr3l8Olw0VeDL9s05vyqS5znvrfi37PabHPD+4y33/cFGulKexycdlzynAsX0t5lNZUpgxvdllTJpBev+5GDZ9Lub6mzFreY/hhU3Q5kGFVlsNfvI8W7CcY1sNy4O8K5+/W0dvBM67hf008ED5QDlA/AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/bf2f7c2cc915242427df4cee83e69e51/8ac56/e5614585cc29a8022da2f16c70300ea118716bae9fc6a760eb037e63693a6efd.webp 240w,
/static/bf2f7c2cc915242427df4cee83e69e51/5021b/e5614585cc29a8022da2f16c70300ea118716bae9fc6a760eb037e63693a6efd.webp 446w&quot; sizes=&quot;(max-width: 446px) 100vw, 446px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/bf2f7c2cc915242427df4cee83e69e51/8ff5a/e5614585cc29a8022da2f16c70300ea118716bae9fc6a760eb037e63693a6efd.png 240w,
/static/bf2f7c2cc915242427df4cee83e69e51/6244b/e5614585cc29a8022da2f16c70300ea118716bae9fc6a760eb037e63693a6efd.png 446w&quot; sizes=&quot;(max-width: 446px) 100vw, 446px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/bf2f7c2cc915242427df4cee83e69e51/6244b/e5614585cc29a8022da2f16c70300ea118716bae9fc6a760eb037e63693a6efd.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Here we can choose the fields shown in the summary and the details page. As you start changing your selection, the settings are automatically saved. Let’s add the State to the Summary page and the State and the Severity to Details page.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;744&quot; data-orig-width=&quot;393&quot; data-orig-src=&quot;./28c5f48f8e745dcffa9fc94cda548d7c6e7c1ed70ce8e4b3ca2c0b556b14b2d4.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 393px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 189.16666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAmCAYAAADEO7urAAAACXBIWXMAAAsTAAALEwEAmpwYAAAD4ElEQVRIx51WS28jRRCeX8DP4cKdf8MViX8BJ0DiABxAXCAB7QkJCWXZbGznnXjj2FEcr7Mznvf71WN/qGqmxxPPxEm2pVL1VNfUfNVVX/co3+x+hq93PsW3rz7Hf1e/oj/5C/uj33Fw/Qd6k91SxjulTHbRv/kT/cpGmueTHQxuXuGf8++gfPnDJ/jiewVf/aLgUtvHpXaGC/UI5+oRjud9nH04xOn9gPWZeljbx9YQd/4YU+8aU2+EmX+Ht7e/Qeld/Yze6Ef0xz/hUv0XQ+11JXsYqnvlXN1ryTvt9Ya8wcX931BQjdUKmJhDnBKq+wFO5wMczQ4Y3cn7Httpfv7hEEezHkbGBabuCLfOFetr4xxzbwolCDyEoY8g8jCzJ5ja15hapdzZ41pvivSRcmuNMLdvocRxhCROUKxyjIwzHL9/i5P5AY7nBxjcveHnw9k+6+M5rfXY/k4/xY0zxMS+ZH2lnzAYJY5jJEmC5aqAHRswQw1WtGBtBGqpGyLt5GPHOosV6bBiHU5kQqFgaZpCiBymYcI2bTw1sjRDHMXV5gOBH7AuRAFFCIEsy7BcLpFmaR2cnotl0RKy53lev1MUBZI0YZ3nGRRaIKEghmlA0zQ4tlNVftUSGpRVFEU8p6C+79cfYoRp9TVyIoT0Ij13Ca1JhNKPa9AMKBHqCx2u43Yi24YwCIJ2QNqDIAjZUYhiK0Lyb2ZCnVIHLAqBNM1QCAHbtuH7Hiog9ZCBSNOgYBREroVhuA4YxilPCKlj2/A8D67jwHVdOI7L6TULJANKeytgnOZcbk7Z93k/yCGOIniu1yrSkymvuP8yiDyHoeuwbQe2ZTO69cGxaiFspvygKNzQaVp+KYrYUdKxq32ebBua0CKlrS8WMHSDKaiqGhzH6US4tbGbCElTxemFLCsL9RyE8v0WwoWmcZUXmoqwIv+Lqdf8QpKUe0dCVf8o6q0R5jBNEwttAcu0XkS9FsKSeoKdVlWaH009GZAOB2rkLspJeRb11gEFF4TOQuI0OW0GbQZsUo8y60i54I6Xsq2xyb+53hmQHgiZ63pcHLdKv6soz6BehmVRVLRLEIZB+dUXUo+27cEeWpYFyzQhiuLZdwrZVFWtq92iXsa3nniybZoIZfq0ZeuiCAFNWyBJ0tY9vImQu6FxcBBC0mTboF5SHRApHw6kNyn42OFAow4o99AwDIZNd7Ou69A0tUa8jXqE+EFAiZCcyFlSCR00fIx6LYTy1iMjIc2F6Gzsx/rwIcLqz4EWKHX5B/pY29Aeyn0jGwUnTbY1U7KM946OIrnpXUJrxHPpR0HoyiVNTPkfKqRutvCA97kAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/673bf6a28f42b376e6a0ea6257cd4bc2/8ac56/960789ba15de15b25d747b2d5418e1204941b371bddc15e3808adddb58d16925.webp 240w,
/static/673bf6a28f42b376e6a0ea6257cd4bc2/8efa6/960789ba15de15b25d747b2d5418e1204941b371bddc15e3808adddb58d16925.webp 393w&quot; sizes=&quot;(max-width: 393px) 100vw, 393px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/673bf6a28f42b376e6a0ea6257cd4bc2/8ff5a/960789ba15de15b25d747b2d5418e1204941b371bddc15e3808adddb58d16925.png 240w,
/static/673bf6a28f42b376e6a0ea6257cd4bc2/d72ec/960789ba15de15b25d747b2d5418e1204941b371bddc15e3808adddb58d16925.png 393w&quot; sizes=&quot;(max-width: 393px) 100vw, 393px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/673bf6a28f42b376e6a0ea6257cd4bc2/d72ec/960789ba15de15b25d747b2d5418e1204941b371bddc15e3808adddb58d16925.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;And now let’s return to the summary page, clicking on the back button.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;197&quot; data-orig-width=&quot;412&quot; data-orig-src=&quot;./7404b1c34cc94e75f19fac095b29d31f61cd1eb9d300b929a099be3ced90e927.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 412px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 47.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAABsklEQVQoz31S227bMAz1F/Zv9gEF9hX7gaEPfdgeBxQYtrYPeVoSB2mMpPE1iaM4bmVJluTLKagmXoYNI3BAgqTIQ4peXddQSuFS/wuXOc5WJ79UaFoDITniKIZ3Tmgai7Zt0TTNH7DWOk0xskkPecagRY8kPGKXcuQHBo+6GGPA9jkWiwWWq2fEUQR/NkMUrhGGa/waj5EkKYIgwOp5jeDpCVm2AUnNS3z78AkPHz+DpRE86kQFSVdVBSEEJEFKh1opaK0HpkZrmL5H07ZAGKK+u0Py/SeyH/dYff0Cj4rRCJtNhtFoBN/3MRlPMJ/PMZ1MMfV9cF45Nn3XOY3tDvrmBurqCuz6GmIyBn+4R3B7+5th3/fDfrquG2wCxQgkQikcsxT7IIDgHMWBIXx8RDGbIV4u4dEDGul/Qg26E7uXskS6zRBvt5BK4fX1BcluB641tDFnhtbtqCgKMMZQFEf38MAYhJR/FXU7t3bwy1MO+b2ubZ1BATqf989Q0HUNUVWOPY17Lkg25V+uiS6FYq6gUNrdoLXGsWP7PfI8dz/+/hP9sMMzQ3G6AhKasCzLodEbh/77SdkzUcMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/3bbb17121bdcfe292862bcf6641ae0b4/8ac56/cd6ab04f16a177b70b78242203dbeefb17462c514d31ece71b4d7da15c11be15.webp 240w,
/static/3bbb17121bdcfe292862bcf6641ae0b4/3b1af/cd6ab04f16a177b70b78242203dbeefb17462c514d31ece71b4d7da15c11be15.webp 412w&quot; sizes=&quot;(max-width: 412px) 100vw, 412px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/3bbb17121bdcfe292862bcf6641ae0b4/8ff5a/cd6ab04f16a177b70b78242203dbeefb17462c514d31ece71b4d7da15c11be15.png 240w,
/static/3bbb17121bdcfe292862bcf6641ae0b4/9e32a/cd6ab04f16a177b70b78242203dbeefb17462c514d31ece71b4d7da15c11be15.png 412w&quot; sizes=&quot;(max-width: 412px) 100vw, 412px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/3bbb17121bdcfe292862bcf6641ae0b4/9e32a/cd6ab04f16a177b70b78242203dbeefb17462c514d31ece71b4d7da15c11be15.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;You should now see the State field&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;394&quot; data-orig-width=&quot;392&quot; data-orig-src=&quot;./4de1c9e4d29b8f57e7c0e3b375b3289cd65dd0c6f09f29c4f9128d0a669ff1dc.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 392px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 100.41666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC9ElEQVQ4y5VU2W4cNxDU/39BfsJPeYnhW4oceO2FbEsyLAvKrsGdg8NrDs5w7gq6d0crOYkBE2g0OUMWq7ureRJCQNM0GMeRbRgG9tM08Zz8Ml/20Lrve7Rtyz60Leapw1+fBU7qukHfdciyDDJNobVGmqaIogjGWOyEQBwnMMYgTRMopZEmKeq6Bo3CFfjjtzfYfthifSNxQjeQZVJCCMEHpUwhxI4BBQPGsNZCKYUsU3xJVXkGDE3A6vdPkF8TrL+mOKFQuq7jn1VZIYljyANbAqnKElJmyDIJmUpmH0LL37ebDaxzWMa7y2jPcAGkMJy1yPN8D1Z5eO95bo1h9pQS+l6WJbRScHmOEPbn311FS8gdhIiw2Ww5X1EUc57Ebse5LA/h/d8Yp/kxIDFc/ND3GIYe4wObxhHADMwTMB88jn6eJgZcXf0QchV6CFXiLnGIrYcwHt9ih5vIYiMLfJc5NmmOyFS4jR2ErnCzM/gW2WMOqSjtATDLa1x9N7iJHD7cZVj/rXBxJ3EtDD5uNSJdwhUVmm6Abwc03Yiq6VGF4QjY9scqtyFw4p01UNogzws0TY3aVyiKgovmqxLeV6iKnBuiqT2KIgcwYXUdE8PxHpA2kM4Mi1syeMmykaxNYy1XmcRtjIZzDplSvL4vyjAO6Np2z7BtoY1hJuSpe+wBZJGMOQic5EWASiskScrFYYbUm92wz8EQApzWsCpD4RwKY2DznA9qo+/BiRVplebEfpEVMyRBdEkC//Il3Okp1PPnUC9ewLx+DfP0KdSrV7BlyReQiOd5ZqOx+OmhDgmwvb6GffYM7vYW2/NzRO/fY7deo7y8hHryBP3+9CMxPwR9JOxxmtB5j+bLF+jVCruzM6Rv3yL+8xzJ2SnExQVMnt8Xbv4B+N8MKYd9/9PWIpDlXfwvG7iTDp1CgFRdfuO859aj9/Ghkfh/Zl3Xc5VZ2ARIr7ZzOb8sBE7rX7G6aYB5OIZMgl6edNpA/lesaQKJjgH/AaLp954P46GOAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/6e278f3e71d4141c4887b8ee9535220c/8ac56/857fd0476436ad5138ed5c1610341eac1de0df4630c722988063180e11bae437.webp 240w,
/static/6e278f3e71d4141c4887b8ee9535220c/86099/857fd0476436ad5138ed5c1610341eac1de0df4630c722988063180e11bae437.webp 392w&quot; sizes=&quot;(max-width: 392px) 100vw, 392px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/6e278f3e71d4141c4887b8ee9535220c/8ff5a/857fd0476436ad5138ed5c1610341eac1de0df4630c722988063180e11bae437.png 240w,
/static/6e278f3e71d4141c4887b8ee9535220c/0acb4/857fd0476436ad5138ed5c1610341eac1de0df4630c722988063180e11bae437.png 392w&quot; sizes=&quot;(max-width: 392px) 100vw, 392px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/6e278f3e71d4141c4887b8ee9535220c/0acb4/857fd0476436ad5138ed5c1610341eac1de0df4630c722988063180e11bae437.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;And click again in the eye icon to check the details page and see the State and Severity fields.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;354&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./a06302a6328dc94cfb9e36f829efb9f72302fbfe8f8684b37206d0a2078c8776.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 70.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAACFElEQVQ4y51S227aQBD1R/HC7W/gGRA/Vt7ykD4gVAzGQYoCCRSILyFpwDb2rtfY5uJT7XBp1YeqZaSjoxmtzs6cGeXr/T10XYeq9tDr9dBut4lVVYWmaeipKgaDAbrdb1Tvn2v9fp8ga6PRGIvFApVKBYppGlh9fiIIGGTEcYw0TQm73Q5pkhBvt1uqJUmKKIqQJAnlh/0el2g2m1AMw6DH8sGtcTgciGu1GhTLtiGiCI7nQURbcCEQMIaAczDGCJxzmiAMw1POONV83yd4nkeC9XodyrtlAUmCvRCINh7s7zO8zedYzhewLRumacIyTRiGZAuWZWG5XOJ18Uq567hwXZcEG40GlGmrBWc4hPswhHh+xo9eH2/dLnz9AezpCbssIx9P/iVXfy8eH49HZMjOgnUo49YXOI6DaLNBzBj81Rq7KMKBMUTD4V+9y7KMBPfnxZw6vLvDejBAOp2CPT5irWlwdB3vnQ5WoxFYGMLf+Ah8HywIyC8WnLyVQlLwshQSnEmPPj6w8jxsOIcbBBBJCh7HCOOYzP8TIQ+J5XVICCF+CS5mM6xXK4ScI5KLEQJJHCPebgnStwvkjf7O8hqkmLzLq6DcmAzZvmz9X3Aa9XA9cDn29Wxs26ZEbkw+/B+cPtiDc0aiJNjpdDCfzzGZTG7ECzStj/F4jGq1CiWfz6NYLKJQKBDfgnK5jFKphFwuh5+1FuQclpTpYAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/988bbdfa5b3cb4cd0f50d28f90a5786b/8ac56/55334dfd5b2fa0f2d686d104c14af55de2c9dada082982281133da0d3fab0d4b.webp 240w,
/static/988bbdfa5b3cb4cd0f50d28f90a5786b/d3be9/55334dfd5b2fa0f2d686d104c14af55de2c9dada082982281133da0d3fab0d4b.webp 480w,
/static/988bbdfa5b3cb4cd0f50d28f90a5786b/b0a15/55334dfd5b2fa0f2d686d104c14af55de2c9dada082982281133da0d3fab0d4b.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/988bbdfa5b3cb4cd0f50d28f90a5786b/8ff5a/55334dfd5b2fa0f2d686d104c14af55de2c9dada082982281133da0d3fab0d4b.png 240w,
/static/988bbdfa5b3cb4cd0f50d28f90a5786b/e85cb/55334dfd5b2fa0f2d686d104c14af55de2c9dada082982281133da0d3fab0d4b.png 480w,
/static/988bbdfa5b3cb4cd0f50d28f90a5786b/0b533/55334dfd5b2fa0f2d686d104c14af55de2c9dada082982281133da0d3fab0d4b.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/988bbdfa5b3cb4cd0f50d28f90a5786b/0b533/55334dfd5b2fa0f2d686d104c14af55de2c9dada082982281133da0d3fab0d4b.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;To summarize, the summary view is what you get in the sidebar and the detail view is what you view (in a modal window) if you want to see a more detailed view of the work item. This allows you to show the most relevant fields to your agents without the need to ever leave Zendesk&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Link to work item&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Instead of creating a new work item, we can choose to link the ticket to an existent work item. Click on button &lt;strong&gt;Link to work item&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;194&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./e3c7b370abcd69988d9b73349401d57c6682a6d5d04625e3620fcec508a4f3e3.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 38.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABWUlEQVQoz22Qy0rsQBCG85S+wQHxsnLpa/gOgi7GnehORvGK14Ur8QLOqJhMOtOXdJLOJ9WZ6Cin4Cd/p7q+qurk+fWO5/E9L48XDIfrbB8vMjheYnDyV8vs9F7yp8sMzlbYOVtl++gfG1sLbO6vkVhTYq3Ha0drArRAA96CnbaYIqCVqGGqArWniymQy0VoK0g/DCZvSJxzOGfxlScQsFZzdXPB8PCAx6cHtCl+yTod7yiV8X55zuveLuPLc/LRCDUpSOq6pmka5CuqqgpjDVrr6Nu2/aUQAlVd48qScaZ4+8jIJwVT46iamqQsywiU4h5orY3/JDrQbE0E2OJ813z0nvL2OaEwFuMcwkpkEu99BIisddzcXpOmnyil4qRaG+Rp+iYSAswnGVmWkuc5RVF0QDcjzyuEbmLxMR/f2cXG/eqSl7Oo3078N9DNisT/rPj/EOB8zby+ACggWxj9xyMiAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/cfcbd09958533d9d4346c3c2b00057b3/8ac56/505cd530d447828bf2efa5a7a333b95f9f858fa10d32828d14eca21b93f4b109.webp 240w,
/static/cfcbd09958533d9d4346c3c2b00057b3/d3be9/505cd530d447828bf2efa5a7a333b95f9f858fa10d32828d14eca21b93f4b109.webp 480w,
/static/cfcbd09958533d9d4346c3c2b00057b3/b0a15/505cd530d447828bf2efa5a7a333b95f9f858fa10d32828d14eca21b93f4b109.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/cfcbd09958533d9d4346c3c2b00057b3/8ff5a/505cd530d447828bf2efa5a7a333b95f9f858fa10d32828d14eca21b93f4b109.png 240w,
/static/cfcbd09958533d9d4346c3c2b00057b3/e85cb/505cd530d447828bf2efa5a7a333b95f9f858fa10d32828d14eca21b93f4b109.png 480w,
/static/cfcbd09958533d9d4346c3c2b00057b3/0b533/505cd530d447828bf2efa5a7a333b95f9f858fa10d32828d14eca21b93f4b109.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/cfcbd09958533d9d4346c3c2b00057b3/0b533/505cd530d447828bf2efa5a7a333b95f9f858fa10d32828d14eca21b93f4b109.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;You should see the dialog below&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;218&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./02090d2663b8f53f9c2e19da38042c31d90ed5d9d8e164616ea4146f4177c7e1.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 43.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsTAAALEwEAmpwYAAABVklEQVQoz6WRO27CQBCGfRowFBQUbqgCDeewSywKI15XgIIcwJ2R6CyFe9BxA2yCvH6BHwLb6I9mnSCTNFEy0qeZnd35d3ZW6Pf7UFUVg4EKRVYgyzJfa5qG0WiE2WyG6XT6xHg8xmQyeazn8zmGwyEkSYLwulqB7HKJkKYJoijC+XxGEITIsgy/tTiO0ev1ICwWC5643W7I8xzX65X7+/2Ooih4XIVyu90O+/2en6U6Mtd10e12ISyXS57I84JvhmGINE0fYlXRoigv2mw22L5t4XkekiTh9b7v46Uq+P15zHFgHSy8H4+wbRu2VXK0bLiMgTkMp9MJ9sECYy4XfOqQuqNuvoijiHdL8yRfUsZBEDw8CXmeD8dxyhmuPj/lv0Zj4oKKosA0TRiGgfV6/Sdoprquo9PpQGi1Wmg0GhBFEfV6/YlarfYjV4VqqJZoNptot9v4AILzP8saqm1YAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/6ed50a5c0f7b3e49358e7595b03cd3ab/8ac56/86059f659eb58ba80b4f6fd0dab6bcd314c6741484059007b3336e9c27e9d32e.webp 240w,
/static/6ed50a5c0f7b3e49358e7595b03cd3ab/d3be9/86059f659eb58ba80b4f6fd0dab6bcd314c6741484059007b3336e9c27e9d32e.webp 480w,
/static/6ed50a5c0f7b3e49358e7595b03cd3ab/b0a15/86059f659eb58ba80b4f6fd0dab6bcd314c6741484059007b3336e9c27e9d32e.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/6ed50a5c0f7b3e49358e7595b03cd3ab/8ff5a/86059f659eb58ba80b4f6fd0dab6bcd314c6741484059007b3336e9c27e9d32e.png 240w,
/static/6ed50a5c0f7b3e49358e7595b03cd3ab/e85cb/86059f659eb58ba80b4f6fd0dab6bcd314c6741484059007b3336e9c27e9d32e.png 480w,
/static/6ed50a5c0f7b3e49358e7595b03cd3ab/0b533/86059f659eb58ba80b4f6fd0dab6bcd314c6741484059007b3336e9c27e9d32e.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/6ed50a5c0f7b3e49358e7595b03cd3ab/0b533/86059f659eb58ba80b4f6fd0dab6bcd314c6741484059007b3336e9c27e9d32e.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;If you know the work item number, just enter it in the Work item text box and click Link. Otherwise you can click &lt;strong&gt;Search&lt;/strong&gt; to execute a VSO work item query.&lt;/p&gt;
&lt;p&gt;I will notice you can now see new section called Search that allows you to select the team project and the query to execute (this is the list of queries stored on the team project)&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;265&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./df63a770ba4bbc37c84a3f87c1c268c90b19fd79cbb25491181b2f5e74c54c1e.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 52.916666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB0ElEQVQoz42R227aQBCGeZqAxAVvg8RLgATXVREvkBfoJb4g1KgGkdiOUFCitBLq4bK5SG+qprZxIDY+7Xpt/9WsCyWqehhpNDN7+Hbm38pgMICmaRiNRhgOh1AUBRNVhaqqmM/PYRgGdF2XblxeQj87w4WiQL++hm6auDAMLJdL9Pt91Ot1VBaLBchSzpHnOYTIwBlDHEX4o61WwNVVmXMuw2w2Q7VaRYVeJsuyDFEUwXvyJHy/JoQ4OIoCj76PV6enWL54ifvVJ2zefwSs73itaagRkEY6vpzyFJkQ2O12CMMQYRDIGAQB4jjGeu1CU1V8eDPF55t3+Hb7FnAcqNMpqicnv4Cyg59WFDlsy4Jt23BsG7Zlw6LasrF2HIRRhMeHBzhf7vH17k7emUwmqNVqqJimKRdIv6IoZCTnnIMx9szLtUR2mlAtBGLG5H36RAk8n8/BGcd2u5XAssMC/2sk1TMg/Q7p465deJ4ntaPxqRvf98tukljuUZ0kidTUdV3Z9W/A/S+zpByFnIB0kKBpmiJNuQTRHtWUbzabvwMJQqMe65gX+SE/3ttLsteabDwel8BWq4Vut4t2u41Op3OI//Lj871eD81mE41GAz8AYQv8KOr536kAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/755acca5e1a23d0050236e88885b5974/8ac56/8f0c53d640e8f453c448a277ea18d114949bc8602a43532d747a495ccc94233f.webp 240w,
/static/755acca5e1a23d0050236e88885b5974/d3be9/8f0c53d640e8f453c448a277ea18d114949bc8602a43532d747a495ccc94233f.webp 480w,
/static/755acca5e1a23d0050236e88885b5974/b0a15/8f0c53d640e8f453c448a277ea18d114949bc8602a43532d747a495ccc94233f.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/755acca5e1a23d0050236e88885b5974/8ff5a/8f0c53d640e8f453c448a277ea18d114949bc8602a43532d747a495ccc94233f.png 240w,
/static/755acca5e1a23d0050236e88885b5974/e85cb/8f0c53d640e8f453c448a277ea18d114949bc8602a43532d747a495ccc94233f.png 480w,
/static/755acca5e1a23d0050236e88885b5974/0b533/8f0c53d640e8f453c448a277ea18d114949bc8602a43532d747a495ccc94233f.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/755acca5e1a23d0050236e88885b5974/0b533/8f0c53d640e8f453c448a277ea18d114949bc8602a43532d747a495ccc94233f.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Choose the query you want to execute and click on &lt;strong&gt;Query&lt;/strong&gt;.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;421&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./9d0ec8407af02486c1f51224a7dbc0e60e27406bf0b826d4b21387c56c1af7bb.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 84.16666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAAAsTAAALEwEAmpwYAAACbUlEQVQ4y52UT08aQRjG+TJ6Q1z9FvYTkNTEEHvRAxAOfgDxgImevHktgg2NvbU32/TQmChUwRib/gEC7p+I7M7s7OKyu0/zzkLQGKnpJE92Znb2t+/zzjsTSyQSeLW0hNU3q0ilUkgmk1hefo21tTWsr68jnU4jm80ik8k8q1wuh5WVFSiKgtjs7CzeHR4i9EM4woUjHNjMBrc4bO7gpe3q6moCLJbeQsBCt9+CxrrQeRca68DgN7gV2lTRGhFaqJ1XsaAsRMCDUhGmf4tm7yfad7/RMf/IfsdswhBd6HbnWamsDRb0UD2vQhkDS6WSDNvsm3AdF5zxiZdwugI/lMvq9frEcrlclpMWYxgMBhBCwHEEgiBAiBBBGCAMw0eiOWq2bcP3fTQajadAeul5HhzHgc05XNeF7z+FSWAQAU3TlOtqtRqoYmIzMzNPgGSboJxzeN7wn0BydXZ2hrm5ucdAziMgWSbRDwg8DWhZ1vPAieUoQhoPh8Nob/4nQtsWkWU3AorRmD6mxJOoP9YLgFGE9CRR+RCUMQbLYjKnFN3DZvb7EfD0NAI+3GXK29DzMHAH8gjKXNpiFG2UT86YrACbMVmHzHVw7/uoXlxMgOPCpgS7o9xRVFKWBca4nJMb5boQ9/cQgHRjnJyAXf/At6MjJObnR0fvoChfqqqKu14Pum5A0zSoqgb1RoWu6xJOllmrBdZogB0fo7+/j/MP71H/+gWf9/YiIOWwUqm8+FZBu43AMABNQ3h5CX5Zh9/8he8fP0FZXEQsHo/Lu6xQKGBzcxP5fH6qtgoFqfz2NrZ2dmR/e3cXuY0NefT+AmEqiaRGZmXmAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/a184700b2f94ca7d9ed2ec993e54d1bb/8ac56/8383bdf1bdb2e40dc823b272efcfde861671c211eb07ef635e0a97c1951fb05c.webp 240w,
/static/a184700b2f94ca7d9ed2ec993e54d1bb/d3be9/8383bdf1bdb2e40dc823b272efcfde861671c211eb07ef635e0a97c1951fb05c.webp 480w,
/static/a184700b2f94ca7d9ed2ec993e54d1bb/b0a15/8383bdf1bdb2e40dc823b272efcfde861671c211eb07ef635e0a97c1951fb05c.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/a184700b2f94ca7d9ed2ec993e54d1bb/8ff5a/8383bdf1bdb2e40dc823b272efcfde861671c211eb07ef635e0a97c1951fb05c.png 240w,
/static/a184700b2f94ca7d9ed2ec993e54d1bb/e85cb/8383bdf1bdb2e40dc823b272efcfde861671c211eb07ef635e0a97c1951fb05c.png 480w,
/static/a184700b2f94ca7d9ed2ec993e54d1bb/0b533/8383bdf1bdb2e40dc823b272efcfde861671c211eb07ef635e0a97c1951fb05c.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/a184700b2f94ca7d9ed2ec993e54d1bb/0b533/8383bdf1bdb2e40dc823b272efcfde861671c211eb07ef635e0a97c1951fb05c.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Click the Link icon of the row you want to select and its work item id should be copied to the text box. Now you can click the Link button.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;196&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./6ea5548eef787d55eb24012a6b9a15f7d7a075735b3822df289e0eec05ada926.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 39.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABiElEQVQoz3WR3WriUBSFfSOD3gn6CGL8ey3nBXrTuZiLUuZWkCpTSKC0JGkthTaUlsYkx78mBrFqfr4haUcnDLNhsc9ZZ+219+YUFEVhNBoxHA7p9/tZ/qUoqNfX3D48oBsGuq5nMAwD4+oK4+Ym4zVNYzweMxgMqFQqSJJEAWCz2RBFUYbddkvw+MjGNMFxyIVtw/MzPD3l6MViQa1Wo1gsfhrGcUy43xOs16znCwJVZbtcstE01pZFnGrSxnd3/Dj9zs/eN6avr+zC8KuPnTdMJ0tN92FI+PHBXFVxNZ2ZqjJ/eWEVRawvLpj2elyenaGcnCAsC8/zszpXCKrVKpL0l2GSJIcVlr7PmzXBEVMcV+DYNm/n51j39yze35nN5riuwJ5M8H0fx3H+XTkXf7yTJGuURNHxKY4/uSQ51Akhjoa73Q7P81itVv9HECDEFD/VBUc+nS79UNM0v1aWKHS7XVqtFrIs05TlLKdoNBqHc4p6vZ67N5tN2u02nU4n05bLZUqlEr8BRiESmyLn3moAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/d71218464c53ea8e3fd32e80e0880d1b/8ac56/84be8eaba4dc8b1896f3b08cb879cf9f019837d3952b66f2f7697e3aa8f979b4.webp 240w,
/static/d71218464c53ea8e3fd32e80e0880d1b/d3be9/84be8eaba4dc8b1896f3b08cb879cf9f019837d3952b66f2f7697e3aa8f979b4.webp 480w,
/static/d71218464c53ea8e3fd32e80e0880d1b/b0a15/84be8eaba4dc8b1896f3b08cb879cf9f019837d3952b66f2f7697e3aa8f979b4.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/d71218464c53ea8e3fd32e80e0880d1b/8ff5a/84be8eaba4dc8b1896f3b08cb879cf9f019837d3952b66f2f7697e3aa8f979b4.png 240w,
/static/d71218464c53ea8e3fd32e80e0880d1b/e85cb/84be8eaba4dc8b1896f3b08cb879cf9f019837d3952b66f2f7697e3aa8f979b4.png 480w,
/static/d71218464c53ea8e3fd32e80e0880d1b/0b533/84be8eaba4dc8b1896f3b08cb879cf9f019837d3952b66f2f7697e3aa8f979b4.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/d71218464c53ea8e3fd32e80e0880d1b/0b533/84be8eaba4dc8b1896f3b08cb879cf9f019837d3952b66f2f7697e3aa8f979b4.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;While performing the operation you should see a spinner loading, when the operation is completed you should be notified and see the work item in the list of linked work items.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;544&quot; data-orig-width=&quot;413&quot; data-orig-src=&quot;./162fbe19e9674cda061657d81c03bd07725d88509076d7b35273e1c3dc8f7709.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 413px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 131.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAaCAYAAAC3g3x9AAAACXBIWXMAAAsTAAALEwEAmpwYAAADfklEQVRIx6VVS27cRhDlQXKdLJJL5AQ24NzB2/gACeSlYCDZZqN4kR8wtuwgIzvSjEbSiN8Z/rrZJJv/4QuqOGQm8cAK4AYeqtjd9bq6qrpoPDkx8PVzA4++NfD0h8+wCOeYu29w4Z7jwns76N4blu+8t4z3m2H+MphjFf+FtVrgJr7CpT+DcfLTFzh5+SW+O/scL377Ctf+a1xtZlhsZiwJy+2rae4Q76xfsfBmWAXnWPnnuPR+hoEeGNHvgLZt0LUtOpaD3k56g7ZpgL6HiCM8fvwIz559A891cDGfY7vdwNA6x4RCoyiKB1FVFZIkwenpKc7OziBiAcu0EMcCRlmWvEnr/0c2gux49EBDnvcthNgTjqQtXbXr0HXtpLftqLeTPoI8JTIVpXBXGxRlAaNpGiYkGfg+blbXuDdN2LaF5XIJz/WwWCywurmF49gw7++xXt/jbr3mA8nFP1++x/dPf2QOgzyjhbqueSJVCkqlyPMcUkqWaZry3BiaLMt4vt57mCU5IkcMhK7rMVld1RySqixhmiY8z4PjOAjDCImUsC0blmnCsizYts2EruPg7vYOeaHZlgl3ux3Hgz50rhHHMRKl2Lsk+UfqogDtHWLcod3Lbm9Pa0zY9z0vUq0ppUAeU7bCIGCyIPAhRMyePzQmQjqJMjaOvGqR6BpV06HpetbjrERa1BBZCZlXiNOCEaUFtjJHXg6PwOj7HXYHhLqs8cdtgNlyg1fXG5zf+vjl0sXr6w1+v/Jw58VwAokg0fBEzjADhYwIuxbGJkqRasrwkBSKRxhLSJUhFAqRVBBSIdcFirp9+Mq6alC3VDbVROg5DnzfR+BvEYUhg5KVZ9lUOgTKdFlVLHOtB0J+PX0/XZniEEUxYiHgc2ISrkMiDMOQE8Z6MOiUODq8KEt2xuiPEJKhSlNEUcT6SEagOcp6EITcIKghECHtZ8IPPOw6SCF5s9rXIxGSwVCTCZNGVK9JMh041eExQjKgTTJJJkIhJYSQSLOM91NB7w4wJWUkpOc3LlIp4bDzjn3qyCDbwaY/4iEt9j1UUcMTGoIKOKsm3ZOai9iXQ/0lecnldtTDwyuHIoHtC3ihZKzsAG6kmCRQwwshmRVDh3qQMJECRZ6joN9ClkFnivWPXfujMRznBmCPIRFdtxvkf5LyQQypa3Nf/ATQLf915fH/8in4G7YdwHkxBYIQAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/c329bab27c0157e1c73303bb6b9a2c31/8ac56/ab678393aa2c00cd4c2a60eaec0a640c714552a5a82eb678fbbe05d3f171f1a1.webp 240w,
/static/c329bab27c0157e1c73303bb6b9a2c31/f2c1b/ab678393aa2c00cd4c2a60eaec0a640c714552a5a82eb678fbbe05d3f171f1a1.webp 413w&quot; sizes=&quot;(max-width: 413px) 100vw, 413px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/c329bab27c0157e1c73303bb6b9a2c31/8ff5a/ab678393aa2c00cd4c2a60eaec0a640c714552a5a82eb678fbbe05d3f171f1a1.png 240w,
/static/c329bab27c0157e1c73303bb6b9a2c31/6c1e7/ab678393aa2c00cd4c2a60eaec0a640c714552a5a82eb678fbbe05d3f171f1a1.png 413w&quot; sizes=&quot;(max-width: 413px) 100vw, 413px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/c329bab27c0157e1c73303bb6b9a2c31/6c1e7/ab678393aa2c00cd4c2a60eaec0a640c714552a5a82eb678fbbe05d3f171f1a1.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Let’s check how the work item was updated in VSO. As a result of the linking process, the work item should have been updated with a hyperlink with the ticket URL.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;226&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./8d8d1639d83718bb8b0be106c491bdd7bdeb0ff59f80e54c7bfb5cbb2d69cb0d.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 44.99999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsTAAALEwEAmpwYAAABPUlEQVQoz5XR326bMBTHcb//a1Tqn6tqb9FV2TRp09KrXDDYlAQDwTY2tvG3s1WqdLtJjvQRAs75+SDE49df3HyuedjUfPrWcP/ld3GXbZqL3Obrc8Xd0w7hrcFYB2mGkFlwCmYDyQPLhSIQEFJZejURloRxnsl5nA/4uBCusSTikhDVfuBPZ9AuYYxGyo6u6zgNJ5ZlIaV0FSFlS9/3ZVgphVYaO1mcdeXZuTxgjCGE8N+7lTgcW4aTKs3W2ncxxg+N673SqoR2R4mfPcG/CaEQo9JM+acA4zjS1DX7/Z7j4YiUsny61oZpmspBwzDQSsmoNe1J0yuDcQ4XI9Y5BG+VN8wnzPP8zntftsibrZWDu7ZlqCpUXaObBpVVFZNSiBy0Bp4P/ltrXwgRpzV6t0P+3CK32Qvd9x+4v4Gvi0azPF+8SQwAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/caebfaf59fc7c78ccf891375cfb0d666/8ac56/e1a447a7307a6d68c64c11d129eb3839ac66ec82ed077e76721d79299a0f540b.webp 240w,
/static/caebfaf59fc7c78ccf891375cfb0d666/d3be9/e1a447a7307a6d68c64c11d129eb3839ac66ec82ed077e76721d79299a0f540b.webp 480w,
/static/caebfaf59fc7c78ccf891375cfb0d666/b0a15/e1a447a7307a6d68c64c11d129eb3839ac66ec82ed077e76721d79299a0f540b.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/caebfaf59fc7c78ccf891375cfb0d666/8ff5a/e1a447a7307a6d68c64c11d129eb3839ac66ec82ed077e76721d79299a0f540b.png 240w,
/static/caebfaf59fc7c78ccf891375cfb0d666/e85cb/e1a447a7307a6d68c64c11d129eb3839ac66ec82ed077e76721d79299a0f540b.png 480w,
/static/caebfaf59fc7c78ccf891375cfb0d666/0b533/e1a447a7307a6d68c64c11d129eb3839ac66ec82ed077e76721d79299a0f540b.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/caebfaf59fc7c78ccf891375cfb0d666/0b533/e1a447a7307a6d68c64c11d129eb3839ac66ec82ed077e76721d79299a0f540b.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Notify&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;A Zendesk user can send a notification to all the linked work items. This will result in the addition of a comment to all linked work item(s). To notify linked work items click on &lt;strong&gt;Notify&lt;/strong&gt; button.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;493&quot; data-orig-width=&quot;412&quot; data-orig-src=&quot;./a7b0da9ffc891d0e606e569031c3e329b65e8f09d56749da3474c88a9460ff92.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 412px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 119.58333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAYCAYAAAD6S912AAAACXBIWXMAAAsTAAALEwEAmpwYAAADIUlEQVQ4y51Vya7URhT1z5LfyJLvSAQSioTeKoJNHiB2YVAkghhet5vXg9uuwa7y7PJwonvt6jTQIERJp6u6hlN3OLccFEUBQp7n8OOfhdYaQdu2INR1Decc+r4/YRiG/+fOxtx3HdqmQUvnuhbOtbC5RdA0DZNRX5Ul30JI0xRSClibQykJJRWstVBKweY5MiLC3I6RwfW9F7DSIpimiW/tnIM1BuFmg8PhgCSOEYZrCKmw3++wCUMIIREdj4i2W7y7fw/6+gm61y8Q/vYH/vr1d1jbINhtd2jaFl3X8W3kJpEJIaCEhE5TVFXFFkohILWGWK0hHj/GZrXGP3+/hFrdoHr+FMQQlGXJMaE4krU0zrKM3cuyFEVRcigoBBnBGOj9HuLBA9z++QhvH17BXF0hffpsJvRWEZExButViOMxnt1OEuz2Bx6nmcF564oCrdYcqvb6Gu2dX+D6fo4hEZKFTNx16J3jC8ahx9DPPaZxZpom+sGXrb57F9XNzWzhOI6cZWqNG7CVOd5sJD5GGd5HBv9uFV6tYry5Vfi413i/0/iUGKxig9vY4HUoEDlg6h2CvGzQtG5JyoTODbz5NjH4cEjxbq+xjg22wnKf5hXqumFdDuPI6PsB4/I/iHSBvOrgXMeODH0PkcQsIcqqMRlSrZBqzWvfaxSywMeFYsjuDwNLhhBFR2idcllmmWHBkwJMlnGvU30qOUpo75MynREOQw+1bKCqkEuFkKhZm0otVSTZCyJOhGDik4WekHpKkFk2shVan0jUUpIkJyKntSQhTyIYa2cLzwnnjA98exzHTESH6DDNeXL/utAbQFVUlhW8/L6ykEASopeEMj+/Rg3P0X9fot9Niickdxl02yKJcZxmLOEYxoll4vphls6CkeXzlcsTH8gbh5tDhiirsVMlPkQGUVoiTCxrcy9zhLHBQRfo2paJLlroJ5WU/AhIpaHTDEJqHrddt1i6WLyEaJqmy4Q+yz5eTV0vcWxOtT6dkfj9hItJ8Yt+7rxnBZwRfAn/UH9G6D8F1H8LtH4Jfu0zQpbL8tH6WVwk/JYVP4L/AIK5N2NUSlrbAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/48272050ef0c294901eb3ff7368e75a3/8ac56/4e6621748c3265b14b30f165495e9e9237cbcdf47deb354315bbce0ce361dce3.webp 240w,
/static/48272050ef0c294901eb3ff7368e75a3/3b1af/4e6621748c3265b14b30f165495e9e9237cbcdf47deb354315bbce0ce361dce3.webp 412w&quot; sizes=&quot;(max-width: 412px) 100vw, 412px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/48272050ef0c294901eb3ff7368e75a3/8ff5a/4e6621748c3265b14b30f165495e9e9237cbcdf47deb354315bbce0ce361dce3.png 240w,
/static/48272050ef0c294901eb3ff7368e75a3/9e32a/4e6621748c3265b14b30f165495e9e9237cbcdf47deb354315bbce0ce361dce3.png 412w&quot; sizes=&quot;(max-width: 412px) 100vw, 412px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/48272050ef0c294901eb3ff7368e75a3/9e32a/4e6621748c3265b14b30f165495e9e9237cbcdf47deb354315bbce0ce361dce3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;You should see the following dialog&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;259&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./b37e684cce2c1e32bf9b7d26af66ab29b7363bac65a7b5ba416be96e2bffee59.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 51.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAABY0lEQVQoz52SzWrCQBSF8y7+IeJCcWXyIK5d+gO+RXUXH8A+g4tGxfdwMzYi2CBWLAkmmUxMcsqdNHXRSMEDH5eZyT1z5hJF0zRsNhtcLhdY1geOxyM+z2ecTifYjoP/FMexrKvVCoVCAYqqqjBNU24GQYAwDCVCCIifSuvb7ZYL9ZCWy2VqSAkZY/LQdV14nnfH93G9XmUTJYmi6A90Kentzbgn3O12eFZkSjIWiyyhCsa2iOIEns/hcwEeiIdPzMhGwzlPDQ0DxWIRiqaqYO8meJjAcTkcN4DLhfwoSZJc8rRer9OE7XYbW8aoHZz7EEEgZ0Y3P4JmbVkWDocD9vs9bNvGfD5HqVRKDbMZ0lNo+HlQMt/38SV/Lwu6rmMymeBlPMZUn+J1NkO1WoXSarXQ7XYxHA7R7/cfMhgMZO31er/rbG80GqHT6aBer0NpNBrSuVwuo1KpPAX11mo1NJtNfAMmbYe7pkRp3QAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/aa18e1af627cd4c7ab89c49d4d0faa69/8ac56/6a4ae483a61c0ee4df9f93f19286f6ff05c3f962a91bc38b58d3403aaec031d7.webp 240w,
/static/aa18e1af627cd4c7ab89c49d4d0faa69/d3be9/6a4ae483a61c0ee4df9f93f19286f6ff05c3f962a91bc38b58d3403aaec031d7.webp 480w,
/static/aa18e1af627cd4c7ab89c49d4d0faa69/b0a15/6a4ae483a61c0ee4df9f93f19286f6ff05c3f962a91bc38b58d3403aaec031d7.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/aa18e1af627cd4c7ab89c49d4d0faa69/8ff5a/6a4ae483a61c0ee4df9f93f19286f6ff05c3f962a91bc38b58d3403aaec031d7.png 240w,
/static/aa18e1af627cd4c7ab89c49d4d0faa69/e85cb/6a4ae483a61c0ee4df9f93f19286f6ff05c3f962a91bc38b58d3403aaec031d7.png 480w,
/static/aa18e1af627cd4c7ab89c49d4d0faa69/0b533/6a4ae483a61c0ee4df9f93f19286f6ff05c3f962a91bc38b58d3403aaec031d7.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/aa18e1af627cd4c7ab89c49d4d0faa69/0b533/6a4ae483a61c0ee4df9f93f19286f6ff05c3f962a91bc38b58d3403aaec031d7.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Fill in the notification and click &lt;strong&gt;Notify work items&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;246&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./84267dc2193768c3e8e7780fda81067ea54b60a23305d2873275b832300fa960.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 49.16666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB5UlEQVQoz53R3UuaYRjHcf+cKUWTTvwDAs0TLYLZBIsRzMF2ttGZsA1GbFDY0AMPgmfNhJrnezkZ0Ukx1yzNnLYO1MeXfEnwec++47F2IO0FdsGH3819w8V1c1lcbjfhaIRwJMKrlRVeLi/zOholGosRW1tjPZHgzcbGHwnxOImtLV4sLTE6MoLl/twctNr0SiWkSgVFFNFqdaRymX6zBZoGigqKArJ8U68Hl5BPp7HabFieTE9zntunevCFeuYr9cPUQOP6LH7bo7K/O3hr5w9oHQ87y6VRill21gVs5oSLd2dRjR49VUXWNWRdH6Si6wOqYSBpGga/r/517r5LcstqxbI46+MSnf+tXw33kkmsZsPHMzN0ixma37O0C6YjOsUjuic5zk9yQzlwmqdbL9H5kaNTyNIqZFFOj9mJv7368j2/n37jDLlcQamIqBURTRTRq9Vh5l2jgZbJoG9uQq0G3S60rhZ3mEpdLSUwPz8YWzEM1IuLv5INA1nTqK2u8jEc5lMiwXtB4HM8zgdBYHRsDEsgEMDQdSRJQjbJ8k2ShCLLtJtNqs0mhe1tngcf8OzhI0LBIE8XFhBCIezj41gcDgderxePx/NPXtPUFF6XC5/TyR2nE9/kJH63G/fEBLftdn4CXaiNnu/QrHsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/0aa7d2fa8cd3d25fd1e8eba6f527140e/8ac56/ecf9d6f7521a1a8f1613c139544ed881900b0a0f118d50586d3c2d3ee23eb3c4.webp 240w,
/static/0aa7d2fa8cd3d25fd1e8eba6f527140e/d3be9/ecf9d6f7521a1a8f1613c139544ed881900b0a0f118d50586d3c2d3ee23eb3c4.webp 480w,
/static/0aa7d2fa8cd3d25fd1e8eba6f527140e/b0a15/ecf9d6f7521a1a8f1613c139544ed881900b0a0f118d50586d3c2d3ee23eb3c4.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/0aa7d2fa8cd3d25fd1e8eba6f527140e/8ff5a/ecf9d6f7521a1a8f1613c139544ed881900b0a0f118d50586d3c2d3ee23eb3c4.png 240w,
/static/0aa7d2fa8cd3d25fd1e8eba6f527140e/e85cb/ecf9d6f7521a1a8f1613c139544ed881900b0a0f118d50586d3c2d3ee23eb3c4.png 480w,
/static/0aa7d2fa8cd3d25fd1e8eba6f527140e/0b533/ecf9d6f7521a1a8f1613c139544ed881900b0a0f118d50586d3c2d3ee23eb3c4.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/0aa7d2fa8cd3d25fd1e8eba6f527140e/0b533/ecf9d6f7521a1a8f1613c139544ed881900b0a0f118d50586d3c2d3ee23eb3c4.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;534&quot; data-orig-width=&quot;396&quot; data-orig-src=&quot;./b0c2823102cbace5f59c1912e10c05327c1159610e8490a5101e14cceb6c164f.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 396px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 135%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAbCAYAAAB836/YAAAACXBIWXMAAAsTAAALEwEAmpwYAAAECElEQVRIx4VVS48bRRCeG/+OAxJ/ATggceAHwIGfkAsE5QbZKEJiDxAURSgHNg5hd5192N6N12vPjMee90zPq+f9oarxeHfBm4xUqqrurq+/6qruUR798Ske/v4xfnz2Cf48+QGDyVO8muzh1XgPf41+Zs3+RgYXTzCYPGHNc+M9HIwfc9yL4QMoXz/8CJ9/r+CrRwoOtd9wtj7DUB/gxDjE6ep4I0c4XR3i3Bzy+Nn6CKfrY8zDSyzEO8zFBRbhHIPrx1CeH3+L58Nv8OLkO4zN1zhWX+NwcYBL9wwzf4Spd46pd7aRjU1zwRhGNoMaXWIWjBh4Yh1Awa0vK1IkeYS0iJHmcWfn8R2JpUCDCoN/DvDFl5/hl/2n0FcLHL59A8d3oCRJhDiJkKQxZCYhs3yjd0uWSlRlheXSwP6v+5iMJxCBwHplIgxCKFJKpGmKLMtYs2Tpe+0kTVAUBWdVVRXKuoQsJPzA7wAJrCxLNE3DUtU167quWbbjVbW1aTzPc1R1BW8dwFId5LmEQoO0WxiGmFxc4Ho2w3K5xGh0DlXToKoqTt6ewFiteE7TVEynV9D1ZcewLfHypwGePXiJXOZQaCcCJIZpkkAIwWmJMEQcJ0izDFEUIU026SYJ4jjeZlU3NUJbwNV99pW8KJg6fW3bQlNVaLqOpa5D1zTewNCX0HUd8/kc8+s5TNNi0NnVFY/lRRdPxLYMCZSYCBHx4iiK2SebmNL50dmypkLc8olZ27QdQzrgsig4WFU1GIYB2zJhmiZWhoH1eg3Lspj9h74tILG7HVBUDXqv3fhlVSMvKqR5iSwvkciCdSoLiJSq3XSAaFsG7NqlwUT3MJxZOLpaY7hw8ffUxODCwJupidO5jUvdge4IzMwQqhOxHmkusqJCXVVQ4qzglAmQWBqOgB3E0O0Qs3UAzQ5h+TGsIIGf5GjqCm3T7Ey5IIZJXt0BdG2Lz5Ak8Dy4jgXXdRBHAmipuW8K0ReG22ej+XHoU6b0XceB7ThcDMf1uOFFFMGybHieB9/34bouC/lBGHLRqEfLsvoPIMABURwzkOM4ECJEEAQcRHME4PkegiDkHg2DgNcVRcnM/wdIN4QCqR+JQc+qt0ks24Zt2zxO7UWbZVLuBiQ2tMgloM3ulB4Fkx0nXaPT1SOhqyhlftOHtwGpKFJ2C/kVkhI3z1vn13Xz/sbuAW+eqRYNN/k9N6NtuW2YwEb3ZHYwBKKsxGwdYmELGH6Kke7j2hJQnZgb+J0RYGEJvFsFCOMUuZTbW7YzZTpD3w/gcUUFt47t+oiTlG8SSd100rO8F5Ao9octs4wfzCxNO3vzxO0+hfb+M6TJ29IHkPS/hF1C8/we9oBUzV5TG9z1O/tDQuv+BeqvAdJukOh4AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/d5afb82365a7a517b9880753eca08286/8ac56/26c4493614090d94046ae3086b3b8817e54f90e537d122418a93946ac79dc3ca.webp 240w,
/static/d5afb82365a7a517b9880753eca08286/2a0bc/26c4493614090d94046ae3086b3b8817e54f90e537d122418a93946ac79dc3ca.webp 396w&quot; sizes=&quot;(max-width: 396px) 100vw, 396px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/d5afb82365a7a517b9880753eca08286/8ff5a/26c4493614090d94046ae3086b3b8817e54f90e537d122418a93946ac79dc3ca.png 240w,
/static/d5afb82365a7a517b9880753eca08286/db910/26c4493614090d94046ae3086b3b8817e54f90e537d122418a93946ac79dc3ca.png 396w&quot; sizes=&quot;(max-width: 396px) 100vw, 396px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/d5afb82365a7a517b9880753eca08286/db910/26c4493614090d94046ae3086b3b8817e54f90e537d122418a93946ac79dc3ca.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;We can now check on VSO the new added comment.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;264&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./a5f173e2f38960eeb6f2d64bc012c227dd8d19a53f80b0cd179379be75c8d7a6.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 52.916666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAABa0lEQVQoz4WSYVKkMBCFuf89/O0drP23qwcYncIRFEgCQyARCGQ+KzAojrqm6lWn6fTr16+I1M0fmuOR1hjatl1gWowx6KbBWMMwDHjvmaZpRrhv8y2iujrOzQF93zOOI8453DmGfCUJeYhhgBscp9PpnXxF1PUd1thZ2VbJ9tGaa63nd1VZoaRiHKdl+HlwQJRnGWmSIKVEColSimOw4Ly+aRcrrLXUdU2e5wghODwXCFlSVRVlWb5vGRVZgViRC5RQlFIhMoEsJEpIZCHmIZ+8C9H7ee0totGNn7yYCxe+fCA0sYAT352IX8/SGAZxQXKpblb4U2EFG5rWdjxLjawtyvZfNP5OGGpa45sGnKMfHC9PKVpV6Fozvb7iu47JWnz4pQLh/9QFQt+2jEnCdHdHen3N4+0txW6H3N1TxTH6cKBJU/TDA0brD4Xf27f57j3J1RXF33+o/Z5yd4+OY5r4ke4lo9vv8cPAG6MfVx8qfyCtAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/ecba918d1d0934622135be09e105b0f4/8ac56/214943d83063e473877851ea7305c4375983d7e57e0ac1195994888643c9f4f2.webp 240w,
/static/ecba918d1d0934622135be09e105b0f4/d3be9/214943d83063e473877851ea7305c4375983d7e57e0ac1195994888643c9f4f2.webp 480w,
/static/ecba918d1d0934622135be09e105b0f4/b0a15/214943d83063e473877851ea7305c4375983d7e57e0ac1195994888643c9f4f2.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/ecba918d1d0934622135be09e105b0f4/8ff5a/214943d83063e473877851ea7305c4375983d7e57e0ac1195994888643c9f4f2.png 240w,
/static/ecba918d1d0934622135be09e105b0f4/e85cb/214943d83063e473877851ea7305c4375983d7e57e0ac1195994888643c9f4f2.png 480w,
/static/ecba918d1d0934622135be09e105b0f4/0b533/214943d83063e473877851ea7305c4375983d7e57e0ac1195994888643c9f4f2.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/ecba918d1d0934622135be09e105b0f4/0b533/214943d83063e473877851ea7305c4375983d7e57e0ac1195994888643c9f4f2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;257&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./13973edbf709441482f0553a25bdac9afe3ccd5655c0424cf3b48e72293608ae.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 51.25000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAABO0lEQVQoz5VS7WoDIRD0/V8iD1LoG+RHSwi0JQ3BfJA7PU9vT0/Pc4qmCSFNAl1Y9tTZuXFHVr28Qn18wnqPzhhYazGOI1JKd3OaJpwjf9+es763cG5A13UIIRTgufG2YRiGUskQnHUX7DWeUU9QbYumaQppVuicgw8B3vtCkjP/TCkFISTqqoaoRcFSR+ipL5jcxzKIc47qeERdC1RVjUY20K0GERXQOfNaSlmIZdNAaw2jDTrTXTBsihFjGIuCkj6UdVYXY8R/gyWkp4DboV+d3DWNPXLzL1GC9wEuzyrXMT4mvKck/e6dtJyChgC+F6hbgrLDgys/U5bfmjGIhwOS1lDLJfaLBdRqBb1egziH5Ry02aC3trjOngzvVLI5bYs4n+NrNsP67R2H3R7H7Q6tEDBSglbfFxN/APZADJL3stDbAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/6d1e7ba635d43f2d6dfde13e8e8ec585/8ac56/d496596b38aa70a1b3c21215080edb1e61c27fedf73195fa864d2e282b3c164a.webp 240w,
/static/6d1e7ba635d43f2d6dfde13e8e8ec585/d3be9/d496596b38aa70a1b3c21215080edb1e61c27fedf73195fa864d2e282b3c164a.webp 480w,
/static/6d1e7ba635d43f2d6dfde13e8e8ec585/b0a15/d496596b38aa70a1b3c21215080edb1e61c27fedf73195fa864d2e282b3c164a.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/6d1e7ba635d43f2d6dfde13e8e8ec585/8ff5a/d496596b38aa70a1b3c21215080edb1e61c27fedf73195fa864d2e282b3c164a.png 240w,
/static/6d1e7ba635d43f2d6dfde13e8e8ec585/e85cb/d496596b38aa70a1b3c21215080edb1e61c27fedf73195fa864d2e282b3c164a.png 480w,
/static/6d1e7ba635d43f2d6dfde13e8e8ec585/0b533/d496596b38aa70a1b3c21215080edb1e61c27fedf73195fa864d2e282b3c164a.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/6d1e7ba635d43f2d6dfde13e8e8ec585/0b533/d496596b38aa70a1b3c21215080edb1e61c27fedf73195fa864d2e282b3c164a.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Unlink work item&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;You can also unlink a linked work item, by clicking on the Cross icon.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;466&quot; data-orig-width=&quot;387&quot; data-orig-src=&quot;./334ee311a4bcbc24065dc76888720858c97fa6784c7c58b3f59aa521d968b303.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 387px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 120.41666666666669%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAYCAYAAAD6S912AAAACXBIWXMAAAsTAAALEwEAmpwYAAADOklEQVQ4y5VVyY7bRhCdv3V+IVf/gq++GLnnaPiQW5AcYsQzGttaxiOJbGoh2Ts3ieLygipKloTxBJ4GCuzq5fWr6lfNm7IsUdc1uq5D33dou/bY79G27Xm8bQcjv+vQNA0OhwN/E6FQFxXuJgI3u90Ou6rCcrHAMgwRBgHm8zmm0ymSJMbDwwyz2TesVyvMFwusogiPj4/I8gLUrHX47dff8eWPCcbBFjd0CjHM8xxKaWRZBucctNIg9s5ZaG1QFAXPee9hjMF+v2f2xFCMN9i5CqNZhBsCa5qWT0uTBGEYMgsRCmhjoKVEJAREFGElIoRBiDwvoKTEw2yGJElwardfw4Eh56M+MItLI4Yn49QcjUiQUZ+Y1vWBAe/G4hTyHstlgGUgkCYxhIiQJClCIbBer7/n67nWdf01IDE83SaH33cA+uHb90MfPd8u3f5pLfk0f0oZAw45bHhgrXPMVgZ3ixQPG4uvkcb9MsXfkw3uA4X5xmCy0ljGDpOVwSL2uA8lxkIPgJMLhtRiUyBMHC+YRArTjcV8axEkHtO1hc0rVFWFhvXYszVtx/YkZGqZ90jiBJkn2Sg4a/ibZ34I72dyeBmyd45lEMcJtpst6420p5TiPomYNOq9Y5+0a62FMRZ912A0ia4B8yz7vkBrzQAEKKVkn4RPQpdS8TqKKJWS17MOx+F1yHTiiRWFqrRmnwCJJQtdK6RpejzYcETkkwqeXArVNG3kEK2FPYIRA2M0gxA7ozUclSCzVijL6scMqSKobgmMatZZx2Hbo+99xoqkSyA9sv2/sPuLu3uufx5jwKZB0z0jm7ppofM9ElfBlTVUtoP0FcxxbGsLKF8hMQXMvkM5ukP89i1qIY6PQ3ANWJQ7bJVHlDpsdQaROsw3GivpsdYFVjpHakvEJofatShGI0Rv3qCU6seAJGCZpigySrhigVszCHuobzxJQ/P6NQ7v3g0hf1meAa/zd9zSn7dSjq+M9tDc7Sf4V79c55DetNM/4qetadDWNbbVHsU/H4G//sRtIAfAy8fzJUZEZCr5BW8+vMe/HydnQJp8qdG+w6HGbl+jbQ/49HlxDfgS4Ms99KShb7n0/gPYHi5vioRYxgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/5f9d1f13636da02982c7b58c630d2af3/8ac56/83b0d563ce28258673ad407547d26a47f8d9580bb5102c49c38896dd80f0d30d.webp 240w,
/static/5f9d1f13636da02982c7b58c630d2af3/bbd0d/83b0d563ce28258673ad407547d26a47f8d9580bb5102c49c38896dd80f0d30d.webp 387w&quot; sizes=&quot;(max-width: 387px) 100vw, 387px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/5f9d1f13636da02982c7b58c630d2af3/8ff5a/83b0d563ce28258673ad407547d26a47f8d9580bb5102c49c38896dd80f0d30d.png 240w,
/static/5f9d1f13636da02982c7b58c630d2af3/691c3/83b0d563ce28258673ad407547d26a47f8d9580bb5102c49c38896dd80f0d30d.png 387w&quot; sizes=&quot;(max-width: 387px) 100vw, 387px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/5f9d1f13636da02982c7b58c630d2af3/691c3/83b0d563ce28258673ad407547d26a47f8d9580bb5102c49c38896dd80f0d30d.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;You need to confirm the operation.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;188&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./ef5637ad427bfb9a9a0825ae99c10fc6471f0278bbf6aea3011260f73cc04553.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 37.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABk0lEQVQoz3WQTWsTURSG80fqQichSh2a0FUgZJFFwJF8zFr/gZsUArYkQymIu+pe+zNqoKBrN8HUXVcG0zbTob3jJJlmPm7yyJ3U2Ppx4eE99/Del3NPqlgsYhgGpVKJQqFAuVymXq9Tq9YSNU2TRqPxf0wz8VQqFXK5HClxdclgMODs7JzT4Smj0YhYShaLOfP5XRY33O7FcYw6vV6PfD5PSsYxs9mMIAhWKJMiDEOiKFoRSkkYx0RSEkdRQhSGSWC/318GqkfT6RTf9xNVTMaTRMfeGM/zEMLFdX/gDod4jsPYtvGDgMn1NX6wDPxy/PV3oJrwX6ymVnUYMjk5wet28ff3EUdHiMNDrrof8D995PPBAZsbG6RU+p+7uo2UEiEEjuNw6brYFxfYQjB6/45vrS2+v9rDfr3H8ds3FFRgs9lkZ2cby7LodDoJqrZuVN3b7fYdrN1dtp8/o2U8oVWt8rJe48VTg0315bV7azzQ7pNOpxM0TfuLX/20tvRkMhmy6+tkdZ2Huk72sc4jXU92+BMbQd8/iaSiYQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/0844298c356c11bf8aa4dbe88bedbf96/8ac56/55a597d9ade1262670eee4818262e1ab21660fb126d8ac496a9ad21112a1e856.webp 240w,
/static/0844298c356c11bf8aa4dbe88bedbf96/d3be9/55a597d9ade1262670eee4818262e1ab21660fb126d8ac496a9ad21112a1e856.webp 480w,
/static/0844298c356c11bf8aa4dbe88bedbf96/b0a15/55a597d9ade1262670eee4818262e1ab21660fb126d8ac496a9ad21112a1e856.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/0844298c356c11bf8aa4dbe88bedbf96/8ff5a/55a597d9ade1262670eee4818262e1ab21660fb126d8ac496a9ad21112a1e856.png 240w,
/static/0844298c356c11bf8aa4dbe88bedbf96/e85cb/55a597d9ade1262670eee4818262e1ab21660fb126d8ac496a9ad21112a1e856.png 480w,
/static/0844298c356c11bf8aa4dbe88bedbf96/0b533/55a597d9ade1262670eee4818262e1ab21660fb126d8ac496a9ad21112a1e856.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/0844298c356c11bf8aa4dbe88bedbf96/0b533/55a597d9ade1262670eee4818262e1ab21660fb126d8ac496a9ad21112a1e856.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Click ‘Yes, unlink it’ and you should see a spinner while performing the action, you will be notified when the operation is completed.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;459&quot; data-orig-width=&quot;376&quot; data-orig-src=&quot;./d172a3ee4ab4a53f45c0cda4d9c7b852033a2a731f8db28573ddd41d4cf3ffc4.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 376px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 122.08333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAYCAYAAAD6S912AAAACXBIWXMAAAsTAAALEwEAmpwYAAADoklEQVQ4y61Uy24kNRStJb/BJ/BXwI4VCyQkdrBEAiSEhISQEKuRRiCxYZMhk0yS6Tx6ku6kU92kXt1VZZeryvV+HnTdVZ0eGJgNlo6ufX19fF+29tH3Gj756R28NH/BhXWEc+sZLuxDvDQOlDw3DzAxn2311h+4dA6VJN2Vc4S5f4Zb/xR3/hUO5t9B++LJu/jy1/fwyvkds80ZpvZzXDsvcGU9x2xzonCzfoGpfYRr5xjX62O8co6xYOcw4musxBVW4hJGNMeJ/jO0NBdI8wBJxpAVwQ55KWCvlwhjV81HfZpzVE2MH378Fp9+9jFmdxdY6FPMbs+x8Q1oTdOB0A5Soe7Qtj2EiJFnpZqTjvbqugWNr7/6Bh+8/yEWCx2WaUO/XyGKJDQpYyRJ8kZkWYY0Tf+hT9Nkp1dSJgjDEJxzaHmeoyxLVFWFsqqUHDHq3wTaK4oCZVEqj8u6gAjElpAMyBuaK5llSNJUHZJSqjXtkTd5XijZNDW6tkPd1Dh5eoHlxEDdVtCIjDOG2XyO1VKHaZi4X9zi9m4B23EwnU7x52oF07KwXC5hWRZubm4UKY2sSPHk899w+vQSLRpo5AUNui2OhnzKRHlGe+QZrYkgTVJImaBpGhR5ofJGNk3doO96FZ1GeaDRti0s04Jt21g7DizTRBzH8FwPpmEoGA8GHh4eEEURmO9D13VsNhvUdb31lggpZCKlsLdVTJV3cqhcmmXqsv3R9z36fphTdF2ndDtCOky581xXld53Pbiuh/XagQgCjGlRLCMT9ud49HAMebytqFs03eO6ajoUVYOqbpAWNbKyRpJXCmlRQeYVZFaie8zh0EdVg8Va4PRugzPdxWTlY7L0cDh3cDR3MNE9zE2GO5vDYhL3mxCGLzEzOe7XIdquV+31WOWugysSODyGzWMs3QgWi+FwCT9KsQkzlFWNtqnxbyPbJ+z7Dpx58F0XAecQnMH3PAScIQwF0G8TTxcTqFBKDvNdUcYc0mYQBGCMwfU8hXDoS9JTsUgKIRTILpZSXc6DAHlRqJ7dEdINZEifBckgEKrfxsN0KCSy4ROgPWovzpmyoYLvQu6H8lPfEaI4Vu3CGIcQW+8Y385J0gVEQnrXddV6fFVbwsFDehmM+cqQiIXYejN6PIYbCKFsyUtKwxjlnocjoVREZKwgJaIoHF6OVK/ov8ZrIY/P520Yq/x3vPZS6HHTD0LybRjtSO6foTn9SIrw/wBFSoR/ASBQHaRqClboAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/b0d2b2abc3c20d910ae9baac2c396af6/8ac56/03c6147f8d18748d02700404eccddf6915d241fd5b666ff0e62c865155dafa2a.webp 240w,
/static/b0d2b2abc3c20d910ae9baac2c396af6/f1608/03c6147f8d18748d02700404eccddf6915d241fd5b666ff0e62c865155dafa2a.webp 376w&quot; sizes=&quot;(max-width: 376px) 100vw, 376px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/b0d2b2abc3c20d910ae9baac2c396af6/8ff5a/03c6147f8d18748d02700404eccddf6915d241fd5b666ff0e62c865155dafa2a.png 240w,
/static/b0d2b2abc3c20d910ae9baac2c396af6/d38a6/03c6147f8d18748d02700404eccddf6915d241fd5b666ff0e62c865155dafa2a.png 376w&quot; sizes=&quot;(max-width: 376px) 100vw, 376px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/b0d2b2abc3c20d910ae9baac2c396af6/d38a6/03c6147f8d18748d02700404eccddf6915d241fd5b666ff0e62c865155dafa2a.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;If you now see the work item in VSO, you will notice the tag and the link to the ticket have been removed.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;265&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./a1b9615150adad25e55b9bb8d739f710f50257fc5bbc6c21c502c1e4816b860a.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 52.916666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAABUElEQVQoz6WRC2sbMRCE7///tVKXEptCQhJKw0nni+8l6/34ikQvBUPakg4MWq3E7OxuN376jFoX1m1j2za01qSUKKV8iN1VaWLKhOBboiLn/GF221XjvSeEgPOO+B/umsPXcUQKieh7hmHAOdcebivXXIzxbRzvOpymiRQTOeX2+U/tXKYJFwIZSFW0jqdU7nGhq1WN1ljnmoOKWwf1nnLGKEVxjnU4M4sBQgDvwHuKtZSU6KSUVFan8zyzLAtKKay1GGPa1rUxTaw/HPh++IK4u0Mej/z4ekSevrV4fnxkOp3ozsOZQUourxfG89jOZV6Ypxl91W1ZIUb8tjE/PaFiQFmL9o5rSJiYsTFSe1sfHuj27dzOax/+jtqqfX4mOYffVrxSJK2hLtFaSAlzf0/HX7CLlpwJUhKEaPRCYF5e8H3/RifEb4fv8ZcqhX/DT1yrWpKpTg3UAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/bcf29a522133f55cddb1ffe09f34bd01/8ac56/500f4daa7bbe0d8058acbfcafd1df80915445b265ec22b2bbf5fa335f0791f7e.webp 240w,
/static/bcf29a522133f55cddb1ffe09f34bd01/d3be9/500f4daa7bbe0d8058acbfcafd1df80915445b265ec22b2bbf5fa335f0791f7e.webp 480w,
/static/bcf29a522133f55cddb1ffe09f34bd01/b0a15/500f4daa7bbe0d8058acbfcafd1df80915445b265ec22b2bbf5fa335f0791f7e.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/bcf29a522133f55cddb1ffe09f34bd01/8ff5a/500f4daa7bbe0d8058acbfcafd1df80915445b265ec22b2bbf5fa335f0791f7e.png 240w,
/static/bcf29a522133f55cddb1ffe09f34bd01/e85cb/500f4daa7bbe0d8058acbfcafd1df80915445b265ec22b2bbf5fa335f0791f7e.png 480w,
/static/bcf29a522133f55cddb1ffe09f34bd01/0b533/500f4daa7bbe0d8058acbfcafd1df80915445b265ec22b2bbf5fa335f0791f7e.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/bcf29a522133f55cddb1ffe09f34bd01/0b533/500f4daa7bbe0d8058acbfcafd1df80915445b265ec22b2bbf5fa335f0791f7e.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span&gt;I believe this is a great example of what possibilities can be achieved with Visual Studio Online REST APIs and service hook integrations.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The Zendesk for Visual Studio Online application is an example of an implementation and a scenario, in which the collaboration between the development team and the support team is increased without going to great hoops, each using their own tools.&lt;/p&gt;
&lt;p&gt;I’m really curious what kind of other scenarios people will implement with these new VSO functionalities.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[How to use ngMessages in AngularJS - yearofmoo.com]]></description><link>https://bfcamara.com/post/85301843848/how-to-use-ngmessages-in-angularjs-yearofmoocom</link><guid isPermaLink="false">https://bfcamara.com/post/85301843848/how-to-use-ngmessages-in-angularjs-yearofmoocom</guid><pubDate>Sat, 10 May 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://www.yearofmoo.com/2014/05/how-to-use-ngmessages-in-angularjs.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://www.yearofmoo.com/2014/05/how-to-use-ngmessages-in-angularjs.html&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;ngMessages is a new feature in AngularJS 1.3 for rending error messages in forms&lt;/blockquote&gt;
&lt;p&gt;ngMessages is a great new feature in Angular 1.3 which &amp;nbsp;allow us to show/hide/manage form error messages in Angular in a much more elegant way.&amp;nbsp;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Jump Start ALM in Your Organization - Site Home - MSDN Blogs]]></description><link>https://bfcamara.com/post/85202847023/jump-start-alm-in-your-organization-site-home</link><guid isPermaLink="false">https://bfcamara.com/post/85202847023/jump-start-alm-in-your-organization-site-home</guid><pubDate>Fri, 09 May 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://blogs.msdn.com/b/cdndevs/archive/2014/05/06/jump-start-alm-in-your-organization.aspx&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://blogs.msdn.com/b/cdndevs/archive/2014/05/06/jump-start-alm-in-your-organization.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Microsoft Virtual Academy courses that will get you started&lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Send a message to an Azure Service Bus Queue with C# and reading it in Node - Interoperability problems]]></title><description><![CDATA[Send a message to an Azure Service Bus Queue with C# and reading it in Node - Interoperability problems]]></description><link>https://bfcamara.com/post/84113031238/send-a-message-to-an-azure-service-bus-queue-with</link><guid isPermaLink="false">https://bfcamara.com/post/84113031238/send-a-message-to-an-azure-service-bus-queue-with</guid><pubDate>Mon, 28 Apr 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The other day someone asked me to look at some code in Node. Basically, the code was reading a message from an Azure Service Bus queue. &amp;nbsp;There was nothing wrong with the code, however the person who asked me to help him told me &lt;strong&gt;that the message that he was getting from the queue it wasn&apos;t exactly&amp;nbsp;equal to the one that was being sent&lt;/strong&gt;. The message was being written in C#, using the Azure Service Bus SDK.&amp;nbsp;Looking at the C# code, the message was being written with the following code&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;137&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./727679f11d8524c7b5d05f5c5848ab065e01e96c12a7075b68b139e9d01f001e.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 27.500000000000004%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsTAAALEwEAmpwYAAABEUlEQVQY042Qy2rDMBBF9fIjiWRb1tiyEwqBLppCQ7vrpv//W6dYTqHddXHR1eEy3BkVD5bYd6zryjzPTPPEPAs+HOhig+9qjr7iFCrC0HAKNcdQ7ayrC/f9ntmyKnvLeZl4ud04r2dCf0ByIMqRk2+wVmOMQhuFdRrz+Jf3IesMxu4Z1bWWse9JaaRtatrWUDeWpnVleFVVaLUNMWitd683bwpTSqOUKn7j6tA4fBdoa80YKqJvCN4zRGGMiZSElBKShGmayllEhCSCTMIwDIQQysmWnFGX/Mm6frHED57ynRyvLOOVRZ7Jy52c33FuLC1KQ703+q0/bJ5eEbmx5jdif8Eag7MWZx3O1UU/a/1H3/xghoYtU9v3AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/6bd82747bfcf85b4752370a4880a32ce/8ac56/11afa1b6a2d00c36ccad59cb6bc1905a86fb68cd830117db6d27d60f74d78573.webp 240w,
/static/6bd82747bfcf85b4752370a4880a32ce/d3be9/11afa1b6a2d00c36ccad59cb6bc1905a86fb68cd830117db6d27d60f74d78573.webp 480w,
/static/6bd82747bfcf85b4752370a4880a32ce/b0a15/11afa1b6a2d00c36ccad59cb6bc1905a86fb68cd830117db6d27d60f74d78573.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/6bd82747bfcf85b4752370a4880a32ce/8ff5a/11afa1b6a2d00c36ccad59cb6bc1905a86fb68cd830117db6d27d60f74d78573.png 240w,
/static/6bd82747bfcf85b4752370a4880a32ce/e85cb/11afa1b6a2d00c36ccad59cb6bc1905a86fb68cd830117db6d27d60f74d78573.png 480w,
/static/6bd82747bfcf85b4752370a4880a32ce/0b533/11afa1b6a2d00c36ccad59cb6bc1905a86fb68cd830117db6d27d60f74d78573.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/6bd82747bfcf85b4752370a4880a32ce/0b533/11afa1b6a2d00c36ccad59cb6bc1905a86fb68cd830117db6d27d60f74d78573.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Nothing special. We are just sending in the message&apos;s payload a string representation of the JSON object { &apos;a&apos;: &apos;1&apos;}&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;And the Node code is reading the message with the following code&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;269&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./b3ea2612b3baed18402b3690017d660e196a0da4ae21d8c1446ddab0eecf9e12.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 53.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAABfElEQVQoz62R7arcIBiEjVHjtzFGkzSFQJfd7f3f4BTf5fR0oZRS+uNBo2acGZm1Fu04EZaK87phOy/EOsMvC0ZtwScNPpk/MihNcG3AnOI4jx2PxwOtVexHQW0ZIUm4IDDpAdpyWD/SSN+Gw1j+WncjrBPwQSLlCUyNA1KMWNeKeZ4RooP1Gt47aG3gfYAxFs45WOdhbcfBOQ9nHe0xxj5x1iDnjFIKaq00n+eM1hqx7Rva1rDvB3LyWOeAWlc6v5aCL+eJnGcYo1+CPgTkFLCUAu89pJQ/HVhy5l/urAVnDIIxTEphFAJSKRhjkFKif0lQiBGCM3w9T1zXhWXJiNkgzgYhaSLGiG3byOV+HAghkruPRMMwfEbujvpkrwXfn0/c73fcbt/weN6xlIyyLthaF9uJLjCOIyVRUtH4JtitayVQc6RHmKaJYggh38v+W7TWkFIgxfDqwnmK2Dv7J8H+Wr10iqDUG/2yD/oF3fmva7+D9fycc+rlf/ADPBb0eDl8cGgAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/68c44059b6381d7bd06e086b62ff9429/8ac56/3ef3a9a43f9b3aa834d9dee71a0c8139544a78ba0e5a25667abc05378a29f9f2.webp 240w,
/static/68c44059b6381d7bd06e086b62ff9429/d3be9/3ef3a9a43f9b3aa834d9dee71a0c8139544a78ba0e5a25667abc05378a29f9f2.webp 480w,
/static/68c44059b6381d7bd06e086b62ff9429/b0a15/3ef3a9a43f9b3aa834d9dee71a0c8139544a78ba0e5a25667abc05378a29f9f2.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/68c44059b6381d7bd06e086b62ff9429/8ff5a/3ef3a9a43f9b3aa834d9dee71a0c8139544a78ba0e5a25667abc05378a29f9f2.png 240w,
/static/68c44059b6381d7bd06e086b62ff9429/e85cb/3ef3a9a43f9b3aa834d9dee71a0c8139544a78ba0e5a25667abc05378a29f9f2.png 480w,
/static/68c44059b6381d7bd06e086b62ff9429/0b533/3ef3a9a43f9b3aa834d9dee71a0c8139544a78ba0e5a25667abc05378a29f9f2.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/68c44059b6381d7bd06e086b62ff9429/0b533/3ef3a9a43f9b3aa834d9dee71a0c8139544a78ba0e5a25667abc05378a29f9f2.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;When we run the Node code we&apos;re getting the following&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;202&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./270f5bf27de86c4758f1e199c0c1c3935a4e563a3886bb75fed027acb6175065.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 40.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABUklEQVQoz32RS2/CMBCETQABeSc84pCAEzlKC0hBqFLbQ4XUHnrp49r//0ummhVBnDiMZm2vv921Vdu2sE2Dp6bB1+GAn+NR9N11+D2d8Nd1+LQWb8bgo2nwbi3OxuBcVbKmXvIcr1rj+aGF2m63qKoKZVGIm6rCYrFAFEVwowiPYYg6CDDxPNnzfR9+EIgnSYI4SeC6LmazGchS8/kcm80GxhgBFkUhyZ7nSZLn+4hcF5PpFM5gAMdxMLi4Ukri4XAocRiGUFmWoa5roROe5znW6zXKshQ4PdMay+USaZJIThzHIunw4oQxV/GytVaAFIEcmQBepussAwuvVis511pf1zzvczmhvOF+v5cu+UF0PgEL9U7178pu0jS9dtfH1w5ZZbfbSWXCWZkAjkvJqDeAXoTfjh0EAcqygOKCUFbgRR4wplP8wdFodFfj8Vg+ifB/SDzJQnmEssYAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/5f0b6ee7b75e2b6999cfcd0b083ab354/8ac56/21426418acf3f2f909ec7659aeaae52bbc91819820fd762781c733769d296a60.webp 240w,
/static/5f0b6ee7b75e2b6999cfcd0b083ab354/d3be9/21426418acf3f2f909ec7659aeaae52bbc91819820fd762781c733769d296a60.webp 480w,
/static/5f0b6ee7b75e2b6999cfcd0b083ab354/b0a15/21426418acf3f2f909ec7659aeaae52bbc91819820fd762781c733769d296a60.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/5f0b6ee7b75e2b6999cfcd0b083ab354/8ff5a/21426418acf3f2f909ec7659aeaae52bbc91819820fd762781c733769d296a60.png 240w,
/static/5f0b6ee7b75e2b6999cfcd0b083ab354/e85cb/21426418acf3f2f909ec7659aeaae52bbc91819820fd762781c733769d296a60.png 480w,
/static/5f0b6ee7b75e2b6999cfcd0b083ab354/0b533/21426418acf3f2f909ec7659aeaae52bbc91819820fd762781c733769d296a60.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/5f0b6ee7b75e2b6999cfcd0b083ab354/0b533/21426418acf3f2f909ec7659aeaae52bbc91819820fd762781c733769d296a60.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;We are getting an exception when we try to parse the body of the message as JSON&lt;/strong&gt; because the body of the message we are receiving is&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&quot;@\u0006string\b3http://schemas.microsoft.com/2003/10/Serialization/?\u000b{ \&quot;a\&quot;: \&quot;1\&quot;}&quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And not just what we&apos;ve sent in C# &quot;{ \&quot;a\&quot;: \&quot;1\&quot;}&quot;. So, what&apos;s happening here?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The problem here is that we are using the BrokeredMessage&apos;s constructor that accepts an object as its argument&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;new BrokeredMessage(payload)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s look at its &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/hh322644.aspx&quot; target=&quot;_blank&quot;&gt;documentation&amp;nbsp;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Initializes a new instance of the BrokeredMessage class from a given object by using DataContractSerializer with a binary XmlDictionaryWriter.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;So, the payload is being serialized using DataContractSerializer with a binary XmlDictionaryWriter and this is the cause that explains why the body of the message&amp;nbsp;has in its start the type indication&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;@\u0006string\b3http://schemas.microsoft.com/2003/10/Serialization/?\u000b&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;How to fix it?&lt;/p&gt;
&lt;p&gt;&lt;span&gt;We have two options to fix the problem:&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;&lt;span&gt;when reading the message in Node strip the part that we are not interested in&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;/span&gt;&lt;strong&gt;or guarantee that the body of the message is just what we are sending, nothing more&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;I will focus on the 2nd fix because in my opinion is cleaner. &lt;strong&gt;To guarantee tha the body of the message is just what we are sending &lt;/strong&gt;&lt;strong&gt;we have to use other BrokeredMessage&apos;s constructor, passing a Stream as an argument&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;public BrokeredMessage(Stream messageBodyStream, bool ownsStream)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Here what it&apos;s said in &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/hh330764.aspx&quot; target=&quot;_blank&quot;&gt;documentation&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Initializes a new instance of the BrokeredMessage class using the supplied stream as its body&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;So, in this case we have full control what will be the body of the message. Let&apos;s rewrite our C# code to use this constructor&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;137&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./91bd4503ed1977e3e917c28c5f797c1f0c7f76e3ddc07ddd8c55f3068dfadc9c.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 27.500000000000004%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAAAsTAAALEwEAmpwYAAABDklEQVQY05WPTU/DMBBEozSxE8d24u9GLaXQA6ItiP//5x6KUSU4cniandnD7jSnped4WHm/XrlcLjy/PHE+H3HBEPeK2Q+YRWKdxGdV1S6yZksYqndp/MmdpLGyZbaGlAtqVLRdwzh1KN3R9S1N0/yPqAU5RkpOmEmidc+kJWoamJ1mHEf6vkcIgRD9L0Sl67rKMAxIKWlmM7E4z6xHilc4LVisJqVEDIGUIsF74na07FnXPaWUut/UO4c2hnVdq2+cmapJwbPPEW8GTnHgVDSHPHM+RI5lZg0TOQZyznjvK9sRpdTfyp+3K/f7B1+3N16fMt5KslOUYOsXD6xWzErW+m3b1pq73a6y+cf8DatBivtIZk9kAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/2718876ff216bb8b8228a8a0386cf64f/8ac56/54c0abde89faa6700947a34f4dad8d6ce9294f58e6613bde128e7e164486cacf.webp 240w,
/static/2718876ff216bb8b8228a8a0386cf64f/d3be9/54c0abde89faa6700947a34f4dad8d6ce9294f58e6613bde128e7e164486cacf.webp 480w,
/static/2718876ff216bb8b8228a8a0386cf64f/b0a15/54c0abde89faa6700947a34f4dad8d6ce9294f58e6613bde128e7e164486cacf.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/2718876ff216bb8b8228a8a0386cf64f/8ff5a/54c0abde89faa6700947a34f4dad8d6ce9294f58e6613bde128e7e164486cacf.png 240w,
/static/2718876ff216bb8b8228a8a0386cf64f/e85cb/54c0abde89faa6700947a34f4dad8d6ce9294f58e6613bde128e7e164486cacf.png 480w,
/static/2718876ff216bb8b8228a8a0386cf64f/0b533/54c0abde89faa6700947a34f4dad8d6ce9294f58e6613bde128e7e164486cacf.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/2718876ff216bb8b8228a8a0386cf64f/0b533/54c0abde89faa6700947a34f4dad8d6ce9294f58e6613bde128e7e164486cacf.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The main difference here is that&lt;strong&gt; we are converting our payload string to a stream and use this stream to build our brokered message&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;After sending the message to the queue, let&apos;s run again the node code&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;56&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./52a4cb4908fe0d98be2000f01de2e719622eb52e1750cd7830cea3c236562323.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 11.249999999999998%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAfklEQVQI1x2MQQrDIBQFs1FBxMR+JVHUakmRrptS6AG66/2P80r+ambg8aZ7a8g549E7vmPg0xreOeNXK577jmvvqLViXVeUUpBSgnOOO8bItNbCe88+vbYNRwg4iHALAcFaXIzBsSwYRDDzzOPzhIiYWmtIKZlKKQghuE//A6xEMtnkhFf2AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/b88cefe1d1f60cbaa0267a06c17f4f6c/8ac56/92a6e96cd1eb4af0aabce96aefb4e8b79e793830d870a7610957064ffc54503e.webp 240w,
/static/b88cefe1d1f60cbaa0267a06c17f4f6c/d3be9/92a6e96cd1eb4af0aabce96aefb4e8b79e793830d870a7610957064ffc54503e.webp 480w,
/static/b88cefe1d1f60cbaa0267a06c17f4f6c/b0a15/92a6e96cd1eb4af0aabce96aefb4e8b79e793830d870a7610957064ffc54503e.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/b88cefe1d1f60cbaa0267a06c17f4f6c/8ff5a/92a6e96cd1eb4af0aabce96aefb4e8b79e793830d870a7610957064ffc54503e.png 240w,
/static/b88cefe1d1f60cbaa0267a06c17f4f6c/e85cb/92a6e96cd1eb4af0aabce96aefb4e8b79e793830d870a7610957064ffc54503e.png 480w,
/static/b88cefe1d1f60cbaa0267a06c17f4f6c/0b533/92a6e96cd1eb4af0aabce96aefb4e8b79e793830d870a7610957064ffc54503e.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/b88cefe1d1f60cbaa0267a06c17f4f6c/0b533/92a6e96cd1eb4af0aabce96aefb4e8b79e793830d870a7610957064ffc54503e.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Now we are able to parse the body as JSON and everything is working as expected.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;: we have to be careful when we have two different worlds in the ends (.Net C# &amp;nbsp;vs Node) and double check for interoperability problems.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[How to be a great software developer]]></description><link>https://bfcamara.com/post/83823065657/how-to-be-a-great-software-developer</link><guid isPermaLink="false">https://bfcamara.com/post/83823065657/how-to-be-a-great-software-developer</guid><pubDate>Fri, 25 Apr 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://peternixey.com/post/83510597580/how-to-be-a-great-software-developer&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://peternixey.com/post/83510597580/how-to-be-a-great-software-developer&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;&lt;span&gt;I believe that your seniority and value as a programmer is measured not in what you know, it&amp;rsquo;s measured in what you put out. The two are related but definitely not the same. Your value is in how you move your project forward and how you empower your team to do the same.&amp;nbsp;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;Worth reading. Great post.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Angular and Durandal Converge]]></description><link>https://bfcamara.com/post/82783179663/angular-and-durandal-converge</link><guid isPermaLink="false">https://bfcamara.com/post/82783179663/angular-and-durandal-converge</guid><pubDate>Tue, 15 Apr 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://eisenbergeffect.bluespire.com/angular-and-durandal-converge/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://eisenbergeffect.bluespire.com/angular-and-durandal-converge/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Worth reading. Great news in the world of SPAs.&amp;nbsp;Rob Eisenberg, the creator of Durandal, has been working as a member of the AngularJS 2.0 Core Team for almost three months now. They are taking the best ideas of Angular 1.x and the best ideas of Durandal 2.x and converging them in Angular 2.0 to make a truly amazing developer experience.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[A List of Foundational JavaScript  Tools]]></description><link>https://bfcamara.com/post/82002765496/a-list-of-foundational-javascript-tools</link><guid isPermaLink="false">https://bfcamara.com/post/82002765496/a-list-of-foundational-javascript-tools</guid><pubDate>Mon, 07 Apr 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.codefellows.org/blogs/complete-list-of-javascript-tools&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://www.codefellows.org/blogs/complete-list-of-javascript-tools&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;In our boot camps, students are introduced to several tools and libraries to expand the abilities of their code. Kalina, one of our current JavaScript students, compiled a list of these tools and wanted to share it with other Code Fellows.&lt;/blockquote&gt;
&lt;p&gt;A list of javascript tools and resources&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scaffolding&lt;/li&gt;
&lt;li&gt;Build&lt;/li&gt;
&lt;li&gt;Package management&lt;/li&gt;
&lt;li&gt;MVC frameworks&lt;/li&gt;
&lt;li&gt;Template engines&lt;/li&gt;
&lt;li&gt;Testing frameworks&lt;/li&gt;
&lt;li&gt;Backend&lt;/li&gt;
&lt;li&gt;Functional programming&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Change careers like Tarzan | Derek Sivers]]></description><link>https://bfcamara.com/post/81199207103/change-careers-like-tarzan-derek-sivers</link><guid isPermaLink="false">https://bfcamara.com/post/81199207103/change-careers-like-tarzan-derek-sivers</guid><pubDate>Sun, 30 Mar 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://sivers.org/tarzan&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://sivers.org/tarzan&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;
&lt;p&gt;&lt;em&gt;So my advice is: Change careers like Tarzan.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Don&apos;t let go of the old one until the new one is supporting you.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;And&amp;nbsp;&lt;strong&gt;make sure you don&apos;t lose momentum&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As always, great advice from Derek Sivers.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Announcing RTM of ASP.NET Identity 2.0.0 - .NET Web Development and Tools Blog -]]></description><link>https://bfcamara.com/post/80260259710/announcing-rtm-of-aspnet-identity-200-net</link><guid isPermaLink="false">https://bfcamara.com/post/80260259710/announcing-rtm-of-aspnet-identity-200-net</guid><pubDate>Fri, 21 Mar 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://blogs.msdn.com/b/webdev/archive/2014/03/20/test-announcing-rtm-of-asp-net-identity-2-0-0.aspx&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://blogs.msdn.com/b/webdev/archive/2014/03/20/test-announcing-rtm-of-asp-net-identity-2-0-0.aspx&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;&lt;em&gt;&lt;span&gt;Today, we are releasing the final version of ASP.NET Identity 2.0. The main focus in this release was to add security and account management features as well as address feedback from the community.&lt;/span&gt;&lt;/em&gt;&lt;/blockquote&gt;
&lt;p&gt;Great news. Who&apos;ve worked with version 1.0 of ASP.NET Identity is going to applaud. Great improvements in version 2.0.&amp;nbsp;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[High Scalability - High Scalability - Intuitively Showing How To Scale a Web Application Using a Coffee Shop as an Example]]></description><link>https://bfcamara.com/post/79983013360/high-scalability-high-scalability-intuitively</link><guid isPermaLink="false">https://bfcamara.com/post/79983013360/high-scalability-high-scalability-intuitively</guid><pubDate>Tue, 18 Mar 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://highscalability.com/blog/2014/3/17/intuitively-showing-how-to-scale-a-web-application-using-a-c.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://highscalability.com/blog/2014/3/17/intuitively-showing-how-to-scale-a-web-application-using-a-c.html&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;&lt;em&gt;A fun and well written analogy of how to scale web applications using a familiar coffee shop as an example&lt;/em&gt;&lt;/blockquote&gt;
&lt;p&gt;Great analogy.&amp;nbsp;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Video post]]></title><description><![CDATA[Great way to start my week: watching a great presentation from Scott Hanselman at Fluent Conference 2014. Very good content with...]]></description><link>https://bfcamara.com/post/79855386457/great-way-to-start-my-week-watching-a-great</link><guid isPermaLink="false">https://bfcamara.com/post/79855386457/great-way-to-start-my-week-watching-a-great</guid><pubDate>Mon, 17 Mar 2014 00:00:00 GMT</pubDate><content:encoded>&lt;div class=&quot;gatsby-resp-iframe-wrapper&quot; style=&quot;padding-bottom: 56.2%; position: relative; height: 0; overflow: hidden; margin-bottom: 1.0725rem&quot; &gt; &lt;iframe id=&quot;youtube_iframe&quot; src=&quot;https://www.youtube.com/embed/UzyoT4DziQ4?feature=oembed&amp;amp;enablejsapi=1&amp;amp;origin=https://safe.txmblr.com&amp;amp;wmode=opaque&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot; style=&quot; position: absolute; top: 0; left: 0; width: 100%; height: 100%; &quot;&gt;&lt;/iframe&gt; &lt;/div&gt;
&lt;p&gt;Great way to start my week: watching a great presentation from &lt;a href=&quot;http://www.hanselman.com/&quot; target=&quot;_blank&quot;&gt;Scott Hanselman&lt;/a&gt; at &lt;a href=&quot;http://fluentconf.com/fluent2014&quot; target=&quot;_blank&quot;&gt;Fluent Conference 2014&lt;/a&gt;. Very good content with a very good performer. Many laughs...&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Expectations vs. Reality: 8 Lessons From The First Year As CEO]]></description><link>https://bfcamara.com/post/79058152660/expectations-vs-reality-8-lessons-from-the-first</link><guid isPermaLink="false">https://bfcamara.com/post/79058152660/expectations-vs-reality-8-lessons-from-the-first</guid><pubDate>Sun, 09 Mar 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://onstartups.com/tabid/3339/bid/105493/Expectations-vs-Reality-8-Lessons-From-The-First-Year-As-CEO.aspx&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://onstartups.com/tabid/3339/bid/105493/Expectations-vs-Reality-8-Lessons-From-The-First-Year-As-CEO.aspx&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;8 lessons learned from an entrepreneur&apos;s first year as a CEO.&amp;nbsp;&lt;/blockquote&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;&lt;em&gt;&lt;span&gt;IMO, there&apos;s an entire generation of entrepreneurs who have a skewed perception that &quot;a great product markets itself.&quot; That&apos;s bullshit. Sure, there are a few born-viral products like Mailbox or Pebble, but these are the extreme exceptions, not the norms&lt;/span&gt;&lt;/em&gt;&lt;/blockquote&gt;
&lt;p&gt;Worth reading.&amp;nbsp;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[An Overview of AngularJS for Managers]]></description><link>https://bfcamara.com/post/78198560842/an-overview-of-angularjs-for-managers</link><guid isPermaLink="false">https://bfcamara.com/post/78198560842/an-overview-of-angularjs-for-managers</guid><pubDate>Sat, 01 Mar 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://fifod.com/an-overview-of-anagularjs-for-managers/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://fifod.com/an-overview-of-anagularjs-for-managers/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://fifod.com/an-overview-of-anagularjs-for-managers/&quot;&gt;Worth reading&lt;/a&gt;. A great analysis of the AngularJS framework, focused on answering the manager&apos;s&amp;nbsp;&lt;span&gt;typical&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;questions:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Who is behind Angular?&lt;/li&gt;
&lt;li&gt;Is it easy to find Angular developers?&lt;/li&gt;
&lt;li&gt;Does Angular supports all browsers?&lt;/li&gt;
&lt;li&gt;It is easy to test an Angular app?&lt;/li&gt;
&lt;li&gt;Does Angular supports i18n?&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Promise Anti-patterns]]></description><link>https://bfcamara.com/post/78199512442/promise-anti-patterns</link><guid isPermaLink="false">https://bfcamara.com/post/78199512442/promise-anti-patterns</guid><pubDate>Sat, 01 Mar 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://taoofcode.net/promise-anti-patterns&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://taoofcode.net/promise-anti-patterns&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://taoofcode.net/promise-anti-patterns&quot;&gt;Worth reading&lt;/a&gt;. If you are using promises, you should read this post. In my case, I&apos;m using some of the anti-patterns mentioned. I&apos;ll have to review my promises code.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[API's testing tools]]></title><description><![CDATA[API's testing tools]]></description><link>https://bfcamara.com/post/77074334893/apis-testing-tools</link><guid isPermaLink="false">https://bfcamara.com/post/77074334893/apis-testing-tools</guid><pubDate>Tue, 18 Feb 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve been doing recently a lot of work integrating different backend systems, using its APIs, tipically in some form of a REST API. &lt;strong&gt;The current post has the main goal to enumerate tools that I currently use to become my work easier to explore and diagnose APIs, before getting my hands dirty with code.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://requestb.in/&quot; target=&quot;_blank&quot;&gt;RequestBin&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&apos;ve already introduced this tool in &lt;a href=&quot;http://www.bfcamara.com/post/41699252979/webhooks-testing-tools-requestb-in-and-localtunnel&quot; target=&quot;_blank&quot;&gt;another post&lt;/a&gt;. Basically, this tool allows us to check the requests that are being made by our application to a given endpoint.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;395&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./dd7109b6bbf55be3053b2b6d31363d25b29639fe7040f6032da00791159122a3.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 79.16666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAAsTAAALEwEAmpwYAAACjklEQVQ4y41S2W4UMRCcXwZFEeI3ACkgJD4DeOOBB3ggIJIN2URhs3PZc489l4/ZLdS9m1WCgoSlku12dXV1y8H7jyE+fV3i87cVvvxY4d2HFY5fL3B8co5nby7w/O3lP0HvRycLPHn5HU9fnOLo1SmCXrfoVI2pV2jKDHzXClorODthu/GYvTvAO7uDtxj7DnWrkaQx4jRHnKYIqqrG6jZEFCXQukPXdej7HkophGGEdRhDygxJIiCzHFrrA4iXZTmKSsFag3EYEAghcX19g/VtCCkkiqJAVVUQQmC1ukUUxcjynEVpL8ryAOItr66xvL4B6bRKIXDOYRxHBrkjWGtB8WmaeJ/nGd57hvOOY3ccYwzn0p0cB/0wsDIF6IFEaBGZ3AmZoet69P2AaTIYBkp2eGwN1DJV3263jz7+PPuFs/NLnm/TKrRKo6oa1HXDZ+c8c+/yWZAuf4MWOT1fXOLi4gpJmkEpjbZVaJoW4zhhMgbzZvNAkNoP7ru6L0htkuBisUQUpYdWjbUHzhYPTbCg3w9/M28etOydx3odQ6kO3s34n8WCxk6odQPjDIw3sPRh3chwGwc7G0x+gpsdrDeY3MS8Ow6htz2MtzvByY3IuxxREyGqIyRtgqRNkekMcRNjXd0iaRIIJVH1FZImhmgFc8M6QtkVfC/6gn9K0JmOSatqxbgpf2NdhwirNYTaCRddgbRND7tUAkIJFF0OqXaFpZYYpxHBYAeINmWRsis5gQqQU3JOICESznUGqSTqvuZYPVT7ThKUfbmfoTccpIr5PlHqDKkSfKYkGgcJi32MdhKWreAxsHsWtDuHVI3bUSkKnSOq472znTtyRg64XS134q1A3MbcVclua57hH8kHuHPVN/HxAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/2b21b4b75960a8b01e89cc3d587d7f4c/8ac56/339204d713fedee50c4a7b68251efbbf00f93e50be41b5e5d21cc68a463d0720.webp 240w,
/static/2b21b4b75960a8b01e89cc3d587d7f4c/d3be9/339204d713fedee50c4a7b68251efbbf00f93e50be41b5e5d21cc68a463d0720.webp 480w,
/static/2b21b4b75960a8b01e89cc3d587d7f4c/b0a15/339204d713fedee50c4a7b68251efbbf00f93e50be41b5e5d21cc68a463d0720.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/2b21b4b75960a8b01e89cc3d587d7f4c/8ff5a/339204d713fedee50c4a7b68251efbbf00f93e50be41b5e5d21cc68a463d0720.png 240w,
/static/2b21b4b75960a8b01e89cc3d587d7f4c/e85cb/339204d713fedee50c4a7b68251efbbf00f93e50be41b5e5d21cc68a463d0720.png 480w,
/static/2b21b4b75960a8b01e89cc3d587d7f4c/0b533/339204d713fedee50c4a7b68251efbbf00f93e50be41b5e5d21cc68a463d0720.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/2b21b4b75960a8b01e89cc3d587d7f4c/0b533/339204d713fedee50c4a7b68251efbbf00f93e50be41b5e5d21cc68a463d0720.png&quot; alt=&quot;339204d713fedee50c4a7b68251efbbf00f93e50be41b5e5d21cc68a463d0720&quot; title=&quot;339204d713fedee50c4a7b68251efbbf00f93e50be41b5e5d21cc68a463d0720&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://www.getpostman.com/&quot; target=&quot;_blank&quot;&gt;Postman&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Postman is a REST client that runs as a Chrome packaged app. &lt;strong&gt;It&apos;s an absolutely essential tool to use when you start exploring an API&apos;s service provider&lt;/strong&gt;. Here are the main features:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Create requests quickly&lt;/strong&gt;:
&lt;ul&gt;&lt;li&gt;supports different formats (json, xml, url parameters, etc.)&lt;/li&gt;
&lt;li&gt;suports basic authentication&lt;/li&gt;
&lt;li&gt;provides oauth helpers&lt;/li&gt;
&lt;li&gt;key/value editors for adding parameters or header values (works for URL parameters too)&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Document and share APIs:
&lt;ul&gt;&lt;li&gt;Use collections to organize requests and share them quickly using URLs.&lt;/li&gt;
&lt;li&gt;Document requests inside collections&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Collections:
&lt;ul&gt;&lt;li&gt;Collections can be any group of requests.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;You can save any kind of request. While saving the request you can also add a name and a note&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Collections can be downloaded and shared as a file.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;475&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./e5c7bf8503249f18a812b6bb0a5f366be5eb8674e763048a0388887528a621aa.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 95%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAACXBIWXMAAAsTAAALEwEAmpwYAAADVklEQVQ4y41Uy27bRhTlXzqJG8OyXKPNykD8D8muaFe2bG/rdBEgi2yLtkCeTlG3rh3KEimJ7+FLJCW+RekU98oyLKQFOsDBJTWjw3PuY6SzszP89OIFTk5OcHp6ik6ng+Pj47v3o6OjJQ4POdIeRdqnsx3a63Tw/fPneLa5CenpwVMcHBzg4YMH2Nrawvb2NlqtFmNjYwOPv3qMzUePeI9++3p3FzutFvb29tBut9He2cFuu41vnzzBN/v7kHzXh3AEXNdFGASYTCaYTKaIohiy3EWSJPi/q6lrSBdKH7I6gik8hu2FsNwAlhfA9kN4YYT5fI7ZbIamabBYLNZAK8kKxHmFIEogvb18hcubC1wrOj6rIwxtD4Y3ZmhuCHccI0tTxHHC6on830AryzJI5sURhvKvUIcmFKUPXTfg+z48z4freoiiCFmaIc9zFHmO2azBdDqFEA48z2OoqorRaMRpk4bKFXo9GYZlQ7guwyUyz4dwPYyjCFVZMklRlGyTFNV1ffdM6aCYpimk37qfcN3rQtN0DEcjOELAu1UoWGHMB4MgQBzHaxbDMERRFHdFIRfSL9ev8bn3JxRlAFmWYVo2PD+4Zzlmy77nM/H9RWSkbo1Q+/sVBjfn0AwbmqaxOpdz47N9ymE6nS4VRjGSOFnGJGGQ9TXCS3WAnjri5AZhuLR7ryiUw7Is+TD9uaoqVGXFz/Qxel8j/HB5Brn7EbpuwbIsmJYF23GWSm+rXFYVynr2nw296kcmtLrvMVKuYFgONF2HYRiwbJtbhyyTQjQlMMuwaGrkRcH9Rqq/IJ7PIb27+QM3qgLbsmGaS5WGacK2HVaYxDHe9X0c/tzHheJgHHjQDYN7jorC6aBIowdA+qt/BXU4gGM7rIxhWXAcwQoncYSXn0Ls/6jjTTdEU6aIkwmrpKJMsxyBrkH+4Tv45x8h6VevMez9Dk23oGsaTNPkAvmcQxfj8fjLfC0WTNjMZqibBjWN5vkHFKYBSVg9CEdnRY7jQAjBVomUb6Aw5NsnLysuzqrSg8GAz4jbAq6WJNyAx4zn0vfv5vM+YRD4MAyd1Y7HIUdSSB83Od82hGPzrEu6rnFlSSE1L1ldgcio2akdVjO7usYof6SU3kk1nUnTDP8A5aloG/7VbbQAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/9d02d47f03a2526e30399c2c6b070bc6/8ac56/434904c8d2b52ad7718bebd9b81548f85e31a16b93dc474be5dd55d23b29c3ba.webp 240w,
/static/9d02d47f03a2526e30399c2c6b070bc6/d3be9/434904c8d2b52ad7718bebd9b81548f85e31a16b93dc474be5dd55d23b29c3ba.webp 480w,
/static/9d02d47f03a2526e30399c2c6b070bc6/b0a15/434904c8d2b52ad7718bebd9b81548f85e31a16b93dc474be5dd55d23b29c3ba.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/9d02d47f03a2526e30399c2c6b070bc6/8ff5a/434904c8d2b52ad7718bebd9b81548f85e31a16b93dc474be5dd55d23b29c3ba.png 240w,
/static/9d02d47f03a2526e30399c2c6b070bc6/e85cb/434904c8d2b52ad7718bebd9b81548f85e31a16b93dc474be5dd55d23b29c3ba.png 480w,
/static/9d02d47f03a2526e30399c2c6b070bc6/0b533/434904c8d2b52ad7718bebd9b81548f85e31a16b93dc474be5dd55d23b29c3ba.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/9d02d47f03a2526e30399c2c6b070bc6/0b533/434904c8d2b52ad7718bebd9b81548f85e31a16b93dc474be5dd55d23b29c3ba.png&quot; alt=&quot;434904c8d2b52ad7718bebd9b81548f85e31a16b93dc474be5dd55d23b29c3ba&quot; title=&quot;434904c8d2b52ad7718bebd9b81548f85e31a16b93dc474be5dd55d23b29c3ba&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://www.runscope.com&quot; target=&quot;_blank&quot;&gt;Runscope&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Runscope is the company that brings us RequestBin, and it has developed a SaaS app which allows us to test our APIs. It has different components:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Runscope Radar: a test runner and framework&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API traffic inspector: allows to check all the traffic that is flowing through our account&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Passageway: Passageway allows you and your team to temporarily share your local web server with others via a public URL&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;For the current work that I&apos;m doing, I&apos;ve just used API traffic inspector and Passageway&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.runscope.com/docs/debugging&quot; target=&quot;_blank&quot;&gt;API traffic inpector&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It&apos;s similiar to Requestbin, &lt;strong&gt;since it allows us to capture a given request, but it&apos;s more powerfull&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;it can act as a gateway to a given real endpoint&lt;/li&gt;
&lt;li&gt;it can replay a previous response&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;383&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./2734dc421d21a1230e24bb90dd565ee67ec606379fa15bcc460c27856e61f62f.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 76.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB/klEQVQ4y5VUyW4TQRDt/z8TccgF7iwSHMIPIC4IiQMRqyBWbBLs2dxbVW8PVdljxZFBUNJT9XT3vH5Vr2fM63ff8PbDd7z/vMDFmwUePvuI8xdfcP7yq+ZHFz/w+NXVHyHrZ88/4cGTS5w9vYRx2wF9f4tIFjVH1BQQ/RaJPGoOADJQaJdR95BxOswzWVDYYho2MP0UYK2FhLUOV4tr3P7aoDagzcAuy1wuFUVQ2wEyL+F9gJk8o5a8J7RYLBZYrVaYphHjOGKz2WC9XmuW5xgjUkq6v7aGNgOAcx5m3VswkW4gZn3JOYcQAnLOICIlkTwTtb10Sx7MDO89YmroBgvTdZ0qK6Xo4jRNSiBkp2JWJOEo6DsigHLDMFqYEFkJam2IxKpMlAja3ZLuQRT6O4ScG3ohjJTATEilwQbGOPS6QRTvNd0DDtnGXcnOOkSumGyEkd6E4JFyReSiC6VCS/chIDAQqIJSA+cKTwWcqipsdad2PrzkDONDVEJOBS4wft7coOt6DEOvreCUwZw0i6tVr0k72V/puxFVOTGklz4mTOOoJs3OEs2Z7pSM435idxd9YJgDewW4NL2TYsxph49dPiaFHmpmx6Q/QsgUsVwukfd9+ZvTJwnn00vbqZSYr87/hjhunA/6DU7WY9x6HXd9j03f6dj9I7yP+i/4DWzpimX/DKsEAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/a7fbfd80c38504d6878f85a8a4801f28/8ac56/76003d9c943386c1d2eafbbb2c5b90cbd09b81e7435a8903df456189a1c648f8.webp 240w,
/static/a7fbfd80c38504d6878f85a8a4801f28/d3be9/76003d9c943386c1d2eafbbb2c5b90cbd09b81e7435a8903df456189a1c648f8.webp 480w,
/static/a7fbfd80c38504d6878f85a8a4801f28/b0a15/76003d9c943386c1d2eafbbb2c5b90cbd09b81e7435a8903df456189a1c648f8.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/a7fbfd80c38504d6878f85a8a4801f28/8ff5a/76003d9c943386c1d2eafbbb2c5b90cbd09b81e7435a8903df456189a1c648f8.png 240w,
/static/a7fbfd80c38504d6878f85a8a4801f28/e85cb/76003d9c943386c1d2eafbbb2c5b90cbd09b81e7435a8903df456189a1c648f8.png 480w,
/static/a7fbfd80c38504d6878f85a8a4801f28/0b533/76003d9c943386c1d2eafbbb2c5b90cbd09b81e7435a8903df456189a1c648f8.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/a7fbfd80c38504d6878f85a8a4801f28/0b533/76003d9c943386c1d2eafbbb2c5b90cbd09b81e7435a8903df456189a1c648f8.png&quot; alt=&quot;76003d9c943386c1d2eafbbb2c5b90cbd09b81e7435a8903df456189a1c648f8&quot; title=&quot;76003d9c943386c1d2eafbbb2c5b90cbd09b81e7435a8903df456189a1c648f8&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.runscope.com/docs/passageway&quot; target=&quot;_blank&quot;&gt;Passageway&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It was never been easy to expose our local web server to the world.&amp;nbsp;&lt;/strong&gt;Just download the app and run it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://zapier.com/&quot; target=&quot;_blank&quot;&gt;Zapier&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Finally I want to say someting about Zapier. Zapier makes it easy to automate tasks between web apps. Sometimes I have to use Zapier to allow me to test an end to end scenario. Let me give you an example: the system I&apos;m working on provides me an abstraction (a class) that allows me to call a web hook. Internally, the framework that uses that class does not allow to use HTTP calls, and requires that any call would be HTTPS. I was using requestbin to check the payload that the system was producing, but Requestbin does not allow to have HTTPS endpoints (at least without the SSL certificate warning). By that time I didn&apos;t know Runscope. So, my solution was to create a Zap in Zapier, that receives on a webhook listening an HTTPS endpoint and sends the request to another webhook on RequestBin. &lt;strong&gt;I strongly recommend to check Zapier, since it opens a variety of integration scenarios out of the box.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;238&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./8976714baa0f3ca4620277de4c8f02034a6113fd5310fdbba17cd6895826669e.png&quot;&gt;&lt;strong&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 47.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAABiElEQVQoz4WRS08UURBG+/+vTCSi0QVrDUIwUbf+ABcIMowjBGmGhJ6evu/b9/brmL7NjDGOujipSqrqq1d2l98xz6/4dj/jYnnN/sfP7B1/5fnbS/YPZ7w4nideniw4eH/DwYdfvHr3nWdHC568PuPpmxl7h3MynV/zcHvOrcxZipzSLvFhjVUlTq0JThC8pKk1DBH6MDFEhtYRvEGqgsvZOWX5QNadfWK4uWDoYWgH+nYghAZtLN4HnPNbtHUIbdHapLhzNUprYmw4Pf1CUazIpKuR1qGUREqJkCLZDUqp39BKIR/9KUchpMQ5h9aaTP1YIO5zlsWKdVVNomISHROstRhjkh0ZC2OMOxnjmVwViLKkrKqt0Mb+jbHRhu3kj36mylW6g9pROArvoqqqxKax2g4hyIQyKO3Q1uO9wzo3reYdbdv+kyZGjHWstSHUdTpNVkpLJQ1SO+raJ7Hxi+Ot+r6n67qdpFjbooyhkCoJjptmIdSEEIgx/DlB0/yXUbTvupTvvecndRH1B+FULxcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/238eeded2780b2771acc68997a9c538e/8ac56/96a6677992c99cfd170d39f3bf93f71bdf3d607d64cd3bbeb6ab64035fd362b2.webp 240w,
/static/238eeded2780b2771acc68997a9c538e/d3be9/96a6677992c99cfd170d39f3bf93f71bdf3d607d64cd3bbeb6ab64035fd362b2.webp 480w,
/static/238eeded2780b2771acc68997a9c538e/b0a15/96a6677992c99cfd170d39f3bf93f71bdf3d607d64cd3bbeb6ab64035fd362b2.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/238eeded2780b2771acc68997a9c538e/8ff5a/96a6677992c99cfd170d39f3bf93f71bdf3d607d64cd3bbeb6ab64035fd362b2.png 240w,
/static/238eeded2780b2771acc68997a9c538e/e85cb/96a6677992c99cfd170d39f3bf93f71bdf3d607d64cd3bbeb6ab64035fd362b2.png 480w,
/static/238eeded2780b2771acc68997a9c538e/0b533/96a6677992c99cfd170d39f3bf93f71bdf3d607d64cd3bbeb6ab64035fd362b2.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/238eeded2780b2771acc68997a9c538e/0b533/96a6677992c99cfd170d39f3bf93f71bdf3d607d64cd3bbeb6ab64035fd362b2.png&quot; alt=&quot;96a6677992c99cfd170d39f3bf93f71bdf3d607d64cd3bbeb6ab64035fd362b2&quot; title=&quot;96a6677992c99cfd170d39f3bf93f71bdf3d607d64cd3bbeb6ab64035fd362b2&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/strong&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;: I&apos;m sure there are other great tools out there, but these are the ones that I&apos;m currently using. Besides the tools I&apos;ve mentioned,. we should have a good understanding of REST architecture style, and how HTTP protocol works.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[An AngularJS Style Guide and Best Practice for App Structure]]></description><link>https://bfcamara.com/post/76616496329/an-angularjs-style-guide-and-best-practice-for-app</link><guid isPermaLink="false">https://bfcamara.com/post/76616496329/an-angularjs-style-guide-and-best-practice-for-app</guid><pubDate>Fri, 14 Feb 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://docs.google.com/document/d/1XXMvReO8-Awi1EZXAXS4PzDzdNvV6pGcuaF4Q9821Es/pub&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://docs.google.com/document/d/1XXMvReO8-Awi1EZXAXS4PzDzdNvV6pGcuaF4Q9821Es/pub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A common question that arises among AngularJS developer is &quot;How should I structure my application?&quot;. Here are the &lt;a href=&quot;https://docs.google.com/document/d/1XXMvReO8-Awi1EZXAXS4PzDzdNvV6pGcuaF4Q9821Es/pub&quot; target=&quot;_blank&quot;&gt;recommendations &lt;/a&gt;published from AngularJS team.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[A Tour of the LightSwitch HTML Client APIs (Elizabeth Maher) - Visual Studio LightSwitch Team Blog - Site Home - MSDN Blogs]]></description><link>https://bfcamara.com/post/76412572580/a-tour-of-the-lightswitch-html-client-apis</link><guid isPermaLink="false">https://bfcamara.com/post/76412572580/a-tour-of-the-lightswitch-html-client-apis</guid><pubDate>Wed, 12 Feb 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://blogs.msdn.com/b/lightswitch/archive/2014/02/11/a-tour-of-the-lightswitch-html-client-apis-elizabeth-maher.aspx&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://blogs.msdn.com/b/lightswitch/archive/2014/02/11/a-tour-of-the-lightswitch-html-client-apis-elizabeth-maher.aspx&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;Visual Studio LightSwitch is the simplest way to build modern business applications for the enterprise.&lt;/blockquote&gt;
&lt;p&gt;If you want to know the LightSwitch HTML client API, and where you can hook your javascript code, go read it.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Dynamic action return with Web API 2.1 - StrathWeb]]></description><link>https://bfcamara.com/post/75794462852/dynamic-action-return-with-web-api-21-strathweb</link><guid isPermaLink="false">https://bfcamara.com/post/75794462852/dynamic-action-return-with-web-api-21-strathweb</guid><pubDate>Thu, 06 Feb 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://www.strathweb.com/2014/02/dynamic-action-return-web-api-2-1/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://www.strathweb.com/2014/02/dynamic-action-return-web-api-2-1/&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;Dynamically returning IHttpActionResult, HttpResponseMessage or any other custom type from Web API actions&lt;/blockquote&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Unit Testing with Microsoft Fakes (Channel 9)]]></description><link>https://bfcamara.com/post/75794734876/unit-testing-with-microsoft-fakes-channel-9</link><guid isPermaLink="false">https://bfcamara.com/post/75794734876/unit-testing-with-microsoft-fakes-channel-9</guid><pubDate>Thu, 06 Feb 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Unit-Testing-with-Microsoft-Fakes&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Unit-Testing-with-Microsoft-Fakes&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;&lt;em&gt;In this episode, Robert is joined by Carsten Duellmann and Ricardo Wickel, who show us how to improve our unit test using Microsoft Fakes. Fakes help you isolate the code you are testing by replacing&lt;/em&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;span&gt;Currently ,&amp;nbsp;&lt;/span&gt;I&apos;m using Microsoft Fakes, and I have to tell that I&apos;m very happy with it, in special with Shims, which allows me to replace some code by my own implementation and isolate the code I&apos;m testing.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Flatten json object to send within an Azure Hub Notification Template]]></title><description><![CDATA[Flatten json object to send within an Azure Hub Notification Template]]></description><link>https://bfcamara.com/post/75172803617/flatten-json-object-to-send-within-an-azure-hub</link><guid isPermaLink="false">https://bfcamara.com/post/75172803617/flatten-json-object-to-send-within-an-azure-hub</guid><pubDate>Fri, 31 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Have you ever needed to flatten your json to a bunch of properties? If yes, continue to read&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;When we need to send a notification to an &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/windowsazure/jj927170.aspx&quot; target=&quot;_blank&quot;&gt;Azure Notification Hub &lt;/a&gt;, we can choose from sending a native notification to Windows, Windows Phone, Apple or Google,&amp;nbsp;or alternatively, &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/windowsazure/dn530748.aspx&quot; target=&quot;_blank&quot;&gt;use the agnostic method which uses templates&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Currently, I am using the template approach, and here &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/windowsazure/dn369286.aspx&quot; target=&quot;_blank&quot;&gt;is the method signature&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;public Task&amp;lt;NotificationOutcome&amp;gt; SendTemplateNotificationAsync(IDictionary&amp;lt;string, string&amp;gt; properties);&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;So, basically we are only allowed to send key value properties.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Let&apos;s say that I have a string representing a json object, and I want to send it using this method.&amp;nbsp;&lt;/span&gt;To do this, &lt;strong&gt;I need to flatten my json (which can have nested objects and arrays inside it) and get a dictionary&amp;nbsp;with all the keys.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Here is an example of json object&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Bruno&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token property&quot;&gt;&quot;surName&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Camara&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token property&quot;&gt;&quot;address&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token property&quot;&gt;&quot;street&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;My Street&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;token property&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;53&lt;/span&gt;
		&lt;span class=&quot;token property&quot;&gt;&quot;zipCode&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2840-344&quot;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token property&quot;&gt;&quot;familyMembers&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Filipa&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; relation&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;wife&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Dekas&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; relation&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;son&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Pipo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; relation&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;son&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;		
	&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;	
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I want to transform this in a dictionary with the following set of key:value&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre&gt;name:Bruno
surName:Camara
address.street:My Street
address.number:53
address.zipCode:2840-344
familyMembers[0].name: Filipa
familyMembers[0].relation: wife
familyMembers[1].name: Dekas
familyMembers[1].relation: son
familyMembers[2].name: Pipo
familyMembers[2].relation: son
&lt;/pre&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Using the library &lt;a href=&quot;http://james.newtonking.com/json&quot; target=&quot;_blank&quot;&gt;Json.NET&lt;/a&gt; with Linq, it&apos;s something that we can do it relatively easy&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;csharp&quot;&gt;&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;Dictionary&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;GetNotificationPropertiesFromMessageContent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; messageContent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token class-name&quot;&gt;JObject&lt;/span&gt; jobject &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; JObject&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;messageContent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; jobject&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Descendants&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;j &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; j&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Children&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Aggregate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;Dictionary&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; jtoken&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
				props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;jtoken&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; jtoken&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; props&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Basically we are querying for all nodes that are leafs, and in that case we add its path and value to the dictionary.&lt;/p&gt;
&lt;p&gt;Here is a console application&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;280&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./162290621c30bdbd9d23d7a9f9c69beabb0e58d872ff6eb06c502e227d8967da.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 55.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAABI0lEQVQoz52T627DIAyFsU1KEmhIAl3Xy9JE2/u/4pnw0mqaNK3Lj08YCx84ljEhBBRS5/E+veFjWXCbZ+RxQA4B3nu0bfs0xlvBUu0wCCNVFU7OIVQViBlkDMx/EWZksbhaC28M2m/wFkHDhB0LTtZiT6REIgQiyBbBmhmeRQVqY1SksMluofQqimARQWZGz4wjMxoiHJgxMutlZa2fEiWCZdZiT4Su9HSNX0V0f8cS/S1YWbvN2q+WRTSoLWGMUecu54ycEtI4ajwMA/q+x7juU0qa03MrMUaQOuAvGyk4XNIeL0PAbbridDxgniaczxe9pK5r/QClsOs6tE2DpmkeA+2cu48Na2DtDqGxGPYOsYuPVxVKAZFBCF7zKY2Qte4nn/FJ6mZUwZ6cAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/4aad4577437dd707636716ac6ddcb501/8ac56/583bff6b2b0ad15f7f20c9b33413cc64497af043922e395c8a497975f8007f55.webp 240w,
/static/4aad4577437dd707636716ac6ddcb501/d3be9/583bff6b2b0ad15f7f20c9b33413cc64497af043922e395c8a497975f8007f55.webp 480w,
/static/4aad4577437dd707636716ac6ddcb501/b0a15/583bff6b2b0ad15f7f20c9b33413cc64497af043922e395c8a497975f8007f55.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/4aad4577437dd707636716ac6ddcb501/8ff5a/583bff6b2b0ad15f7f20c9b33413cc64497af043922e395c8a497975f8007f55.png 240w,
/static/4aad4577437dd707636716ac6ddcb501/e85cb/583bff6b2b0ad15f7f20c9b33413cc64497af043922e395c8a497975f8007f55.png 480w,
/static/4aad4577437dd707636716ac6ddcb501/0b533/583bff6b2b0ad15f7f20c9b33413cc64497af043922e395c8a497975f8007f55.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/4aad4577437dd707636716ac6ddcb501/0b533/583bff6b2b0ad15f7f20c9b33413cc64497af043922e395c8a497975f8007f55.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;And here is the result of running it&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;292&quot; data-orig-width=&quot;382&quot; data-orig-src=&quot;./761ec9da70865833a26f9ec3e4a1541bd99852830e421162450567490dee2979.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 382px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 76.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB1ElEQVQ4y61Ty27iQBA0QsCJ8BR+G2Nsj4E12IB5CLGLdrUhJEQ55P+/paLqFbmAkJD2ULI9nq6qrp7R3j8+UWx+Is1WWBQ7QaRSNNsGuroLw/KhW748TXsgMGwfpjMQWIQbCGwvgPbn9wFRFCLPMySJgus6UCqGbZl4eqpD07THcHo5QqkEWZYhGY3Q6/UwmfxAmqYYDocwTUvW+v2+wPP6UlgqlW5Cez+/SXGSJAjDUIpHoxFmsxkMw0BRFGi326jVamg2m6jX69+ENx2+vp4wmUyENAgCNBoNIeO3Ugqmaco6SVutlgjebfl8fhNHURRhOp0ijmMhHAwGWC6XcF0X4/FYIuEaxSlK8tsOTy9CQtLdbofVaoU8z+E4jrTr+760TjFmyFiYLTuwLOu69ePxWVoj4Xq9xnw+F4ckJIlt29B1Xf6TjP8uImy/UqlcZ8jNHMp2uxVXJGURCbrdrji7uGXrNEChm4M5Pv9FrJScxc1mg8Vi8e2CUdAFB0NB5kxxOvY873aOl6Ew7P1+L06Y4cXVv7PnyYD4TjE6rFarKJfL14SHwy/ZyKC5+dI+XbCQWfHI0DHBSXc6HdnP9SvCKBw+fr3ugff27sl/mDCO/ivhF8aoev+fu+qfAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/9dc27f4f951d9c7a8a3ac12d653ac21b/8ac56/692442f7cf143edabf3993c26559c8c69b5b72bed9a234d7198a6ad3ad2a139f.webp 240w,
/static/9dc27f4f951d9c7a8a3ac12d653ac21b/c5024/692442f7cf143edabf3993c26559c8c69b5b72bed9a234d7198a6ad3ad2a139f.webp 382w&quot; sizes=&quot;(max-width: 382px) 100vw, 382px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/9dc27f4f951d9c7a8a3ac12d653ac21b/8ff5a/692442f7cf143edabf3993c26559c8c69b5b72bed9a234d7198a6ad3ad2a139f.png 240w,
/static/9dc27f4f951d9c7a8a3ac12d653ac21b/77edc/692442f7cf143edabf3993c26559c8c69b5b72bed9a234d7198a6ad3ad2a139f.png 382w&quot; sizes=&quot;(max-width: 382px) 100vw, 382px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/9dc27f4f951d9c7a8a3ac12d653ac21b/77edc/692442f7cf143edabf3993c26559c8c69b5b72bed9a234d7198a6ad3ad2a139f.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I hope it helps.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Windows Azure: Web Sites Always On Support]]></description><link>https://bfcamara.com/post/73559159580/windows-azure-web-sites-always-on-support</link><guid isPermaLink="false">https://bfcamara.com/post/73559159580/windows-azure-web-sites-always-on-support</guid><pubDate>Fri, 17 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://weblogs.asp.net/scottgu/archive/2014/01/16/windows-azure-staging-publishing-support-for-web-sites-monitoring-improvements-hyper-v-recovery-manager-ga-and-pci-compliance.aspx&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://weblogs.asp.net/scottgu/archive/2014/01/16/windows-azure-staging-publishing-support-for-web-sites-monitoring-improvements-hyper-v-recovery-manager-ga-and-pci-compliance.aspx&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;
&lt;p&gt;&lt;em&gt;One of the other useful Web Site features that we are introducing today is a feature we call &amp;ldquo;Always On&amp;rdquo;.&amp;nbsp; When Always On is enabled on a site, Windows Azure will automatically ping your Web Site regularly to ensure that the&lt;strong&gt; Web Site is always active and in a warm/running state&lt;/strong&gt;.&amp;nbsp; This is useful to ensure that a site is always responsive (and that the app domain or worker process has not paged out due to lack of external HTTP requests).&amp;nbsp;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;It also useful as a way to keep a Web Site active for scenarios where you want to run background code&lt;/strong&gt; within it irrespective of whether it is actively processing external HTTP customer requests.&amp;nbsp; We have another new feature &lt;strong&gt;we are enabling this week called &amp;ldquo;Web Jobs&amp;rdquo; that makes it really easy to now write this background code and run it within a Web Site&lt;/strong&gt;. I&amp;rsquo;ll blog more about this feature and how to use it in the next few days.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Great news (from &lt;a href=&quot;http://weblogs.asp.net/scottgu&quot; target=&quot;_blank&quot;&gt;Scott Guthrie&apos;s blog&lt;/a&gt;). Until now, my typical approach has been to use &lt;a href=&quot;http://www.quartz-scheduler.net/&quot; target=&quot;_blank&quot;&gt;Quartz.Net&lt;/a&gt; to have background jobs, and use a service to ping the web site continuously, using for example &lt;a href=&quot;https://www.setcronjob.com/&quot; target=&quot;_blank&quot;&gt;SetCronJob&lt;/a&gt;. From now on, Web Sites have built-in support for Always On, and very soon will have Web Jobs. Well done Azure.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Running Angular Tests in VS Test Explorer with Chutzpah]]></title><description><![CDATA[Running Angular Tests in VS Test Explorer with Chutzpah]]></description><link>https://bfcamara.com/post/73198752368/running-angular-tests-in-vs-test-explorer-with</link><guid isPermaLink="false">https://bfcamara.com/post/73198752368/running-angular-tests-in-vs-test-explorer-with</guid><pubDate>Mon, 13 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span&gt;The ecosystem around Angular is typically following the &lt;a href=&quot;http://yeoman.io/&quot;&gt;Yeoman &lt;/a&gt;workflow. This workflow is based on three tools:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Yo - scaffolding tool&lt;/li&gt;
&lt;li&gt;Grunt - taskrunner, used to build and test a web app&lt;/li&gt;
&lt;li&gt;Bower - dependency management system&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;I have nothing against this workflow, but since I am a .Net developer, I am used to another tools which reside inside Visual Studio. And I believe that the majority of .Net developers has some reluctance to install node on their machines, which is a requirement installation for all of that tools. We, .Net developers, are accustomed to:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;use Project templates to scaffold and bootstrap the app, or Project Item templates with T4 templates to scaffold some specific items&lt;/li&gt;
&lt;li&gt;MSBuild as the taskrunner. For running tests we are used to do it inside Visual Studio using the Test Explorer&lt;/li&gt;
&lt;li&gt;Nuget as our dependency management system&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;I’m passionate about Angular. But &amp;nbsp;I’m passionate about Visual Studio either. &amp;nbsp;So, regarding to angular tests, I would like to run them using Test Explorer, instead of grunt. Suppose that I have this angular app inside Visual Studio. &amp;nbsp;It is a very simple app, created from template Empty ASP.NET application, with a Add Unit Tests checkbox checked.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;265&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./ae02d456ca727816e279bb7b3ef46b7b027f226ab187583182c3a0a7d4a1a1c3.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 52.916666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAACO0lEQVQoz3WRS2sTURiG5x8IVVAjCM2tnVsymc4kmcxMZibXya1NL7SL4qLFtlCjlWoRCqILQVq0VKGoWYm/ShdKwZW/4pFMTKlSFy/vd87hPN/7nSNIooQ4K6HIMqqiRP6vZGl85joOnucRBD6VoBLJ93y8sofruNSCCkK4vEdrZR873MWo7GCFD3A6D/HmH1NdekJt+Snh2jO664esbr9ifXDEvUfHbOyfsHXwjt3DMwbPP7L3csjB688IteYijdYyc/mAjO6hGT45MyBn+hhWnaC5RLXRp1LvYzkNTKtKudKmUu9RCxcp2DVst47thZS8EKHZbNPtLOA6HsWCTclysCyXomHgruzRGhwTnHylcfaT6ukPGu+/45+eox+d452e47/5hvb2F9m1FwSWgZAvWARBjWq1gabNoagaiqKhazmC/gZmf0Bm8wPa1jDS3PaQzP0h0ubYc1ufkLe/oHd3WF1cQMjlDEoll1FS0ywgyxkkScUwipQKee7GbpK4c4N4bGqs21MkYlMkY2NPxK4zfesaGWmWTm8JQdcNRtB+f4VyOSCb1SMZRgHbdoknUqRnJFKRxMiTaZFUWvyzN16LkhrdE3TdjFIZZpFWq0u9HpLPW5hmEdt2mJ6Ok0qlL5RMppiZmb2oJy6KMqqqjYGKksVxPOq1Jr5fjRroep5isUQ8nvgLmEgkUdVMBP0vcFS02z067R6TBqNnGH3SCHA53QQ6qa8EynI2GrXbnY/eYZTwKuBl6P9G/g3UiHgE4FfOPwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/a2ee27c8ad0fb570c71e9c9b52806600/8ac56/d5f810f42a14c20ab8eaaae157fdb0c74aa09ff16ab859a0a85ad57f2da3e97b.webp 240w,
/static/a2ee27c8ad0fb570c71e9c9b52806600/d3be9/d5f810f42a14c20ab8eaaae157fdb0c74aa09ff16ab859a0a85ad57f2da3e97b.webp 480w,
/static/a2ee27c8ad0fb570c71e9c9b52806600/b0a15/d5f810f42a14c20ab8eaaae157fdb0c74aa09ff16ab859a0a85ad57f2da3e97b.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/a2ee27c8ad0fb570c71e9c9b52806600/8ff5a/d5f810f42a14c20ab8eaaae157fdb0c74aa09ff16ab859a0a85ad57f2da3e97b.png 240w,
/static/a2ee27c8ad0fb570c71e9c9b52806600/e85cb/d5f810f42a14c20ab8eaaae157fdb0c74aa09ff16ab859a0a85ad57f2da3e97b.png 480w,
/static/a2ee27c8ad0fb570c71e9c9b52806600/0b533/d5f810f42a14c20ab8eaaae157fdb0c74aa09ff16ab859a0a85ad57f2da3e97b.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/a2ee27c8ad0fb570c71e9c9b52806600/0b533/d5f810f42a14c20ab8eaaae157fdb0c74aa09ff16ab859a0a85ad57f2da3e97b.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;515&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./faeff56a47d15ba377c182a47c0339ab4f656766bcf79b7ced2df61e3c563c0f.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 102.91666666666669%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAYAAABG1c6oAAAACXBIWXMAAAsTAAALEwEAmpwYAAADmUlEQVQ4y6WU22tcVRSHzz8TnXQmpCAttbXUF6FVvPug0gctVK1XMOKFgq3gQys+iFjRRjGGeqlJazOTTDL3yeRcZ845M2fO3JKYNAmYZCZSCARJmsx8ck4zdZI0edANH3utvVk/fnsv9hba2jy0e7y0t7fiw+vtcOfmmsfTsrevA5+vA593J8KRw0d44dRZnn/1IifPXODFM5/x0luf88zLn/JK1xe8/sFXvPnRJbrOfcu75y7Tdb6b0+9f4uQ7X3Lqva85/eE3vHa2mzc+/p63P/kB4fjxE/ze108oECTkHyJwbYBYNE5qTEYUHSQURUVTNWRZQVU1FDXNmLMnKUiyiqSoqOkMGSOL4Gn3Eey5jOi/SqS/l3hfL9lYENOUyGcVKkWTrC5i6GNUCgb5rEomnaRc0CnbOiU7465b+hhS3I9w8IEDDP7Yja7LxMUkBUtjeWYGJZNmobqIM/K2TbFScuP5+QXktEIDqNcbLo0GTJQtklE/wqGjjxDo+Y6cIRGPBMlnRKqVEtM3Z6guVjdF5qlVa268tFSjUq6wtnbbzRuOGjBZthkJJhDaDp0gfPVX/szn0OMhlipF/p5fYHJmilvLt+4WNQuduV6vU3fylvU/xm10dQzB8+BjJJJx/qrVMA2T22trbGxsoKoqtVpti4vm3Byt+dSEjW1KCN7Og8SiIebmZslZFvMLizTqdarVKsvLy/d02EqroGVICD6vj1hkmNXVVVZWVlhfX9/hYquv3R3mHcEnHn+SZDy8ZXO7g+1u9hS8/+jTRGJRGvWNPY+2K9sF7zv27A7B/8K/Dh96imgkxP8dUxOFO03xHH6U0HCA8WKWkm0yXsxRLphu7OC8gNnpCtOTxT1xnmAhpyJ4jj3HUDDAaGKYoUA/0bCf1GiYkaHrJKJDxEJ+5FQYyxDdI1m74IilpRjCvgMPEx64RiEVQQzeQAkHyCVCGEqCgpVG10bR5LhbULQ09607FDdpxo6onIogdHTuJ/xTD/LPvSR/u0Ky7wrpX3qw1VHyOdUVcoosU8EyZSxDvjvnNrE2SUtxBF/HfiLBG2jJELHB64yG/IiRQTJyElURURUJTRHvoEoYuuZyc3qSuZkp5manmZqskDdlSnkNwefrJBIKULQz6OkUpi6SNSTypoKd1cibqvsH2jnNxbkGB+efdBo5XnKaqbuChayyKTgywHjRcEWcI9pZ5R7IblGT1oY4uZ11rkfhHw01esORFlrrAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/842f3151578300b6afd8c0f048795b59/8ac56/74e1cd8da0497ca4ca887d1e447b49653118a3b151493f4b91ab568d78fe78dc.webp 240w,
/static/842f3151578300b6afd8c0f048795b59/d3be9/74e1cd8da0497ca4ca887d1e447b49653118a3b151493f4b91ab568d78fe78dc.webp 480w,
/static/842f3151578300b6afd8c0f048795b59/b0a15/74e1cd8da0497ca4ca887d1e447b49653118a3b151493f4b91ab568d78fe78dc.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/842f3151578300b6afd8c0f048795b59/8ff5a/74e1cd8da0497ca4ca887d1e447b49653118a3b151493f4b91ab568d78fe78dc.png 240w,
/static/842f3151578300b6afd8c0f048795b59/e85cb/74e1cd8da0497ca4ca887d1e447b49653118a3b151493f4b91ab568d78fe78dc.png 480w,
/static/842f3151578300b6afd8c0f048795b59/0b533/74e1cd8da0497ca4ca887d1e447b49653118a3b151493f4b91ab568d78fe78dc.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/842f3151578300b6afd8c0f048795b59/0b533/74e1cd8da0497ca4ca887d1e447b49653118a3b151493f4b91ab568d78fe78dc.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;After that, I&apos;ve added the nuget packages Angular Core and Twitter Bootstrap 3.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;123&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./9cda167584cbf2a8825cb5895298eec3b0164d03317f3ad6d5bcce193126e42e.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 24.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsTAAALEwEAmpwYAAABXElEQVQY0z3MTU/TAACA4f0bS9vp2rJCPwaUrl3XlYlt94HIXHHGjANRyIxDDSEhiCSLZ030sqN3Lhz5Bxw0gQR+hRxIyGvcEg9P3tubM60SYRBSrVRwl13qK/VJXWcJVVGQRQlZknkoT+Ul6T9ZFJFmZiZEQUB8IJCzbYda0qed7bHx8iNPX7yn2R3SyvZodgeknV3a2YCo9ZrH6zskzwek2TuavQ886+/T3T5k880Rr96esDUckbNLS/hBTDlI8YIEezFENz1008fxYmpPOoRJhlVOsPwWpeo6taRLtLqGU4lZcFcIogZpe5N60iFXLOr4XgXTsFEKGqpapKjp5JVZGr0v9EcXpD/vicd/8L7fMv/1jo0f1xyMz2kfn2LMm8wZNo7772FNh4Zh4TjlSTVNR84XkAQBtfcN/fMN9slv9ONLZj9NqYe/UI+umBueEdUiSv4qirFM/pHGX70JxVud/8fYAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/39703dcab5bff5ab1e6d364be68d691c/8ac56/bf8fc33dec62bc9bc7786444a477dcfc59aab97d76f67977875086fb01a5e97e.webp 240w,
/static/39703dcab5bff5ab1e6d364be68d691c/d3be9/bf8fc33dec62bc9bc7786444a477dcfc59aab97d76f67977875086fb01a5e97e.webp 480w,
/static/39703dcab5bff5ab1e6d364be68d691c/b0a15/bf8fc33dec62bc9bc7786444a477dcfc59aab97d76f67977875086fb01a5e97e.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/39703dcab5bff5ab1e6d364be68d691c/8ff5a/bf8fc33dec62bc9bc7786444a477dcfc59aab97d76f67977875086fb01a5e97e.png 240w,
/static/39703dcab5bff5ab1e6d364be68d691c/e85cb/bf8fc33dec62bc9bc7786444a477dcfc59aab97d76f67977875086fb01a5e97e.png 480w,
/static/39703dcab5bff5ab1e6d364be68d691c/0b533/bf8fc33dec62bc9bc7786444a477dcfc59aab97d76f67977875086fb01a5e97e.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/39703dcab5bff5ab1e6d364be68d691c/0b533/bf8fc33dec62bc9bc7786444a477dcfc59aab97d76f67977875086fb01a5e97e.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;169&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./698d3358e9f0c6daf69fea0965e61af16a9f5ca9d4b882cee905ea519fb98c38.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 33.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAAsTAAALEwEAmpwYAAABw0lEQVQozy2PQW/ScByG+1FMxMOk7R+6UqAtFNpSaFlpATcHcTLnegDNpomHMSSYGY2JBy/e3cEsuxidid/CT2LiV/AxqR6ew/PL+77JT3IclyiK6XR69KNBju/3aNgOiiKQZRVVEZRECaGWUFWRu1BF7vlNESj/c5IfThgfLJkcrXiQrdmbnbF7uGTyeMU0e8lsvmGSrUln59zPNkznFzx8+obD07ccPX9H9uI98+UHTjcfc6ReL6bTTemGQ9peH6PWzqnWXfxuQhCmNN0IVbMxTI96I8i9anlUTY+a5RH0UpLhPm4nRvJcH6fpopUrCFVD0yroei1/JR3sEAYuwzjErmrUNIW6LqgZOncKBbSSoNONMN0+ZctH02tI9bqF0/Lw/QDLauaDxbsyRWFg2Amt8YLk+Bzz3gl6skBPnhDvHhDGI9xoxE6cMt6b4gURFcNEsu0G7XbAcLiL7wWI0jby1haKM2b8+ifdyz/EX6B19Q/zM2TXv3j29Tfp6oqo4xEPRthWE33bQGo2HBzHwzQbKEqJoixQijKy4WKe3OCe3ZBc/CBcf2Pw6juVxSW3H33i1vE19f0l5YpFwYwpVPy8+xe+uQqkW1nsAAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/ca168faa39b5ecbcc222d3c011ca0369/8ac56/100089fda4f5800a63758749dc0f61a0e8e198e1bbe67d8d9cb572fd01d82a80.webp 240w,
/static/ca168faa39b5ecbcc222d3c011ca0369/d3be9/100089fda4f5800a63758749dc0f61a0e8e198e1bbe67d8d9cb572fd01d82a80.webp 480w,
/static/ca168faa39b5ecbcc222d3c011ca0369/b0a15/100089fda4f5800a63758749dc0f61a0e8e198e1bbe67d8d9cb572fd01d82a80.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/ca168faa39b5ecbcc222d3c011ca0369/8ff5a/100089fda4f5800a63758749dc0f61a0e8e198e1bbe67d8d9cb572fd01d82a80.png 240w,
/static/ca168faa39b5ecbcc222d3c011ca0369/e85cb/100089fda4f5800a63758749dc0f61a0e8e198e1bbe67d8d9cb572fd01d82a80.png 480w,
/static/ca168faa39b5ecbcc222d3c011ca0369/0b533/100089fda4f5800a63758749dc0f61a0e8e198e1bbe67d8d9cb572fd01d82a80.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/ca168faa39b5ecbcc222d3c011ca0369/0b533/100089fda4f5800a63758749dc0f61a0e8e198e1bbe67d8d9cb572fd01d82a80.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Then, I&apos;ve created an Index.html &amp;nbsp;and an app.js file&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;516&quot; data-orig-width=&quot;400&quot; data-orig-src=&quot;./5806c68dd2fd13f76ce224743a854910ae362b8e9dbd4a528e616e692465c6d6.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 400px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 129.16666666666669%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAaCAYAAAC3g3x9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAEHklEQVRIx62USY/jRBiG8wuGOxKQxXGcxUs27xWvsZ2kt3QnvTEDDBpxQIgD/196UFVPWt3QzYnDK1tV9lPvt1VrMrExTed/U0sCpcZjS2k0MpVO7/IpPzx99285TEzn+fuWbc+x7RnT6YLFwiMIBZ4X4roBQRAzn7sKaFlTJdOcPr8ryT3TZrn0ieOEljF2COKMNK8VqKo2ZGnBKskoy5ooFM9A+XTsmTKg1qQcF3Pq47ohQgJbrRa6PlBupG3p1LQc0rQgigRhJFitMtI05/Jyz8XFnrreIkSi1pL1OaK8YGTO0fvGE9B1fZpmx3zuEYYC348VcLXKCQKhQgnDFUmSE4sU349YLgOVjrkrWAQZtrOkKKonYJ7n3Nwcmc09FbIMXYKlgiAiilYqAplXefhstnyVQ9uaquhkihQwy56AhjFiu90RBjF1s8H3fIIwUgcmMqdFQZ7llOuasijVuvxXHpSmmdp7dng43Cqg63mc3Z1Trit2u3OuLi/ZX99wc3Pg7vaOjx8/cX//wH5/rdYuzi+wbYfhcMRkYj4B0zTl+vqApumYpsnMm5EkCet1RVM3XF5ekaUpruuyWCyVZrO5kuM4qqi9nqakgGdnZ3z+/Cvft7vo8iTTwYti4iQlK9bk6zV+FPFdu0On032lbreHpvXp93UlBSzLkvv7R4wf2sz7Ot54TLlw2AhBHQkK16NwXeyeRl860TS0rzo5e+Uwywvu9zfUE4t84bF2Ay4il/skZC8EkekQ2zO20znCchjK+X9nFFvffPhAs93xcHXNYeGzFSW7KFPPL+GUX+qGv778zuP5NUd/xZXI8UWBiAviN6QcFkXJ8XDLXDdIplOSucuf1ysem4zzvOLx7IzIsggnJuZwpHIlC/GWvvZhxuF4x7ftLj1jiDa2+HEfsNvmiKJCH4/4vqcptXsaXa2vCvGWntomy3k43BJ2ehTDEcXY4o9qwUO04NILWY9HBO0OiT4g7ev4fZ2erKqmP1f3VZVFlvPbzZF4OMKcTLBHY+o0YlPk1LJtVglJGDIeGFgDg2Y0RpeRvGiXV8Aky/l4OJJLB8aQpK+zT0oespKfq4qfqppPZcH50mVnO+TDIf2BQf8F8AR/nmWZw3ZXQx8YaH1dFSrLS/KipNlsEatEvXu+T/trM7/UCfoMPB7v6LS7aiblpRBHAiFWZGlOHK9omoahYajmHQwMpVNl33R4um0W7pL62JAkKXXVUNeNmueqatSIbjZbdXGU5Zo4FmrfXbpqBF8BpUO5OBqNMS0LIYRyJh1WVa1cv+y/U+7edahC7vQwjKG6jsIgIssKymKt9kUsVLjv9d/bOez0VA6nzoypPyXJUzbNVoWVpZlyL6H/bJX/dCiTLX/URwMs28Zdeur+m88XjMfvA099+Dc8Zz+JgRWmHQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/a7f3271863caaa9cf85cccf03fe7c263/8ac56/3579eed8fcd0c0920af05c6c0811540bc2391a31b577afb11a5f173160a689ef.webp 240w,
/static/a7f3271863caaa9cf85cccf03fe7c263/7f61c/3579eed8fcd0c0920af05c6c0811540bc2391a31b577afb11a5f173160a689ef.webp 400w&quot; sizes=&quot;(max-width: 400px) 100vw, 400px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/a7f3271863caaa9cf85cccf03fe7c263/8ff5a/3579eed8fcd0c0920af05c6c0811540bc2391a31b577afb11a5f173160a689ef.png 240w,
/static/a7f3271863caaa9cf85cccf03fe7c263/e17e5/3579eed8fcd0c0920af05c6c0811540bc2391a31b577afb11a5f173160a689ef.png 400w&quot; sizes=&quot;(max-width: 400px) 100vw, 400px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/a7f3271863caaa9cf85cccf03fe7c263/e17e5/3579eed8fcd0c0920af05c6c0811540bc2391a31b577afb11a5f173160a689ef.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Here is the HTML to show a table with a list of tasks&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;540&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./46edad98ddd2ae4ce4c0b8bc31b780ab96644781496f0436e130481c98efe633.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 107.91666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAWCAYAAADAQbwGAAAACXBIWXMAAAsTAAALEwEAmpwYAAADbUlEQVQ4y52TyW7jRhRFORTnmRRFihQ1WfIgUZLRbQR2w7LkoXuRRT4giyyctO1MQIAgyCq7IEC++gSm3Ym77ThGFhdFVpEH991XT/ru1z+5/Ol33v/8B5vTt5xtTjk9e8fFxeccHa1Zrc7ZXx6wPv+Cr779jS+//oXV8RmHRysWy9cslgcP9Brp+x9+RJIE1WDAq52c5W6PeV3Tm/RQLBXN1ZFNBdXWMGIHI3EQvobt28iy0kiSVRRVRVUF0tX7b5AkiU4nZdqPyNMY33MRtsDwDTRPxwotVEeg+RriftUtDcu00YTAEAqyJDUc6fr6unkwbQdd15kOQka9nMV8n+2dAcNRyXQ2pltljIYVZZnT71UMhyO290YMRxnbWxFx5N05vLkHllXFZ3WPxd6QoijpVh3ilkenaJN1EtpFSNoJSFIXz3eJogjHNQkTDz/y8Hwf3/f/cZhmKcMiYDzoMJ7sUvU7tHKLssrp9tq0MpfBoEV/WNJqtQjCgDhOCFyb0HcJXANZlpGur64aoO36CKGyVQbUe2Pmsyn1Yo9pPWY0jalGEVnuE8cxnufhOA5BEOBYBq5j4ljawwxVwihuNhRFJYttJlXM7nhAGIZ4oYbt6Hc//Jc+AIMo+ujAMjWGRYhrGwihoWk6hqa+FCjjuN6TH6SRw3Rni/Fkm1E3xdDFC4CKjuM9BsqKoNsOWM52qeuace+lQEnG/QTouzbjKsFzzJdl96nD4L4pd5LZ7qccznJs20bTDUzHRLVkJHHrXELoCtpTmTZAWeAFwaNDQ9eoipTlvKYu5/TcgnE6oOwmdLs+hqn/G1B7lOGH2ey0XI4P9tlXX7GQ5rzxVuwv9pj0Ws9lqDzZlNB3aEUu7SQmEQmRFNK22iRxgG1qzwBlgesHH5U6KGKmw9umWP+jKbJoHApVpWiHlO2ATmKjKMpd+bcz+jAOWUZV5Ef7D0oWmJbV3LvZqEU/92hnHdLcp106pB2HoheQZi5Z2yVLY4rEJgmcx8Cbm5sGeHtttsqQUREQOILodoYDkyg1cQMNyzYIPYssNDD1Z0bw8vISSZjkRclyUpCnEbKiIYRAqBpC1RFCb2ZZ1w003cQwTEzTelLS+fk7jo9PWK9PWW/OWa3WzfvZ2UWjk5MNm80ZR4dvqOvF35rNFtSzu/Wh/gLwUR18DL+fxQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/98dea8d35b13ee0bdd43ecd3bde6fea1/8ac56/2c5df73bc7f9e04fb4957ceaac30ed70ea8970b438d1156ac53f8de15fcb041a.webp 240w,
/static/98dea8d35b13ee0bdd43ecd3bde6fea1/d3be9/2c5df73bc7f9e04fb4957ceaac30ed70ea8970b438d1156ac53f8de15fcb041a.webp 480w,
/static/98dea8d35b13ee0bdd43ecd3bde6fea1/b0a15/2c5df73bc7f9e04fb4957ceaac30ed70ea8970b438d1156ac53f8de15fcb041a.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/98dea8d35b13ee0bdd43ecd3bde6fea1/8ff5a/2c5df73bc7f9e04fb4957ceaac30ed70ea8970b438d1156ac53f8de15fcb041a.png 240w,
/static/98dea8d35b13ee0bdd43ecd3bde6fea1/e85cb/2c5df73bc7f9e04fb4957ceaac30ed70ea8970b438d1156ac53f8de15fcb041a.png 480w,
/static/98dea8d35b13ee0bdd43ecd3bde6fea1/0b533/2c5df73bc7f9e04fb4957ceaac30ed70ea8970b438d1156ac53f8de15fcb041a.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/98dea8d35b13ee0bdd43ecd3bde6fea1/0b533/2c5df73bc7f9e04fb4957ceaac30ed70ea8970b438d1156ac53f8de15fcb041a.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;And here is the js code, which includes a controller MainCtrl responsible to return the tasks to the view, using a service dataService which will encapsulate the call to the backend (for now it returns an array hardcoded).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;358&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./58f68778f56b1784ada6e8a06b6cdc63ceeb92ae32ba16490515833242c43cda.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 71.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAACBklEQVQ4y6WTS2/TQBSFx48Zv+2Z+v2I67SQpgWxRkJCgg0Iseien5AUiT3//UN2Smgj6KIsjka6ls/c79w7YvfjJx++fuPjp1s+f7nl7bv3vHr9hs32hs3VNZurG86nSy4uN7zcXDOspiclvt/tEUJgWwJfCtJMEsXeUnuW9rs9lvJxpSJQDlprjDE0dUtdt5RlSZx6aKMJwxDLsrBt+58S+/1s6BFFEavViu12y2oc6FclbXeGOdNEYYTv+wRB8Bc9rovdbocbRCjPQynFeprYXgy0RUhtPHQaIaV8gGWdYFpYp8h2mCCVOhalLVhPa4oypz7X5HVM3Z6RmYhuqCkKTdloyjyhb2uywCUOFLbt/DaMH3XhuC7r9Zq2q2jGjH4y1K2haWrGqaVqY5ouZxx6xjIlT0Nsx33Y4WyojghKySXPqi5IjSSvfDITc3nxgjgJKBqfvDCM40gduxQ6wbLsP4ZOlC7I85TmHF33cNs8UcsSCEss5zLFe4rDt5P8joZxhivlMjHHcZYf5/PZe+gkeslg3rm27ej7gbLKiTMXL3DwfEmYOLjSItEeqfbwQ0lRlDRNQxxFJ4ZhjONKYmVTZSGrvqfruiWjYRiWPGf1fb9QHJDFcZln9MdrEyX4QYCnFLnRS6fzi9HG0DYNRZEvtaqqlgfwNPL+DuG4pFmGf3/7/+gXAyJL88O9TtoAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/d89c35b847988756045129dd8c610253/8ac56/3be12f5c5d007195718351ac46d0d3449bbde8925edfdc1d78bba9764f737682.webp 240w,
/static/d89c35b847988756045129dd8c610253/d3be9/3be12f5c5d007195718351ac46d0d3449bbde8925edfdc1d78bba9764f737682.webp 480w,
/static/d89c35b847988756045129dd8c610253/b0a15/3be12f5c5d007195718351ac46d0d3449bbde8925edfdc1d78bba9764f737682.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/d89c35b847988756045129dd8c610253/8ff5a/3be12f5c5d007195718351ac46d0d3449bbde8925edfdc1d78bba9764f737682.png 240w,
/static/d89c35b847988756045129dd8c610253/e85cb/3be12f5c5d007195718351ac46d0d3449bbde8925edfdc1d78bba9764f737682.png 480w,
/static/d89c35b847988756045129dd8c610253/0b533/3be12f5c5d007195718351ac46d0d3449bbde8925edfdc1d78bba9764f737682.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/d89c35b847988756045129dd8c610253/0b533/3be12f5c5d007195718351ac46d0d3449bbde8925edfdc1d78bba9764f737682.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Hit F5 and here is the result&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;329&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./250d611b1715d4b14010ac61cb15d47131e8c12cfbd0b1677a0b81bcfbabba6e.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 65.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAABn0lEQVQ4y32Sy07bQBSG/aoUtV30RUAqYtFX6Bp1gRC7CrGISMWmLojUSCQRRY499lw9ji/jv5qJbMYk5Ei/NDo6851rcHY1x/nVDD9+znB5HeH7xV98+XaPz6d3e/Xp9A8+noT48PU3Do5vcXg8xcHRLwRKUGTJC1iWIIv/QbIMlAlIpSFk8a4Yl0jSHE/PKzxET3icx7gNIwTrdYW6aWE6oGkNqqqGMa0T0O3RtpFcIlgulwjDENObKRaLJaIowmQyQRQ9wpjNx67rPMHTxtfHrQhHYB9t26IsyyGgaRrn80G97fIZY16BWmsURYH3rP9Ylhp5no9gSimn3lZEILAwQlJwziGEcJXZjL4sQEoJQsjIxzlz/0zntWyBcRxDSAlbbR/8Op9NOxaYUzpqkVEKLsSwIgcstXaZ++p6yFugTUwp3Upii+j8Cq3DBmZZhrqud2x1E2zjGGNbM1xXlTdDbu9wjSRJXLa+nV3AQimkhAznYs12xblA07RjYJqmw6bfwoYta+0A/uaVkpBKuVGN7tA7kr2n4793+ezZ/Actk+MzKsIdQwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/941d052e58a938f66c9e551b0ed112aa/8ac56/24148788906d3b5e2b2941aafcfcccafb698c66ba9c71106795aff61d0cf4055.webp 240w,
/static/941d052e58a938f66c9e551b0ed112aa/d3be9/24148788906d3b5e2b2941aafcfcccafb698c66ba9c71106795aff61d0cf4055.webp 480w,
/static/941d052e58a938f66c9e551b0ed112aa/b0a15/24148788906d3b5e2b2941aafcfcccafb698c66ba9c71106795aff61d0cf4055.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/941d052e58a938f66c9e551b0ed112aa/8ff5a/24148788906d3b5e2b2941aafcfcccafb698c66ba9c71106795aff61d0cf4055.png 240w,
/static/941d052e58a938f66c9e551b0ed112aa/e85cb/24148788906d3b5e2b2941aafcfcccafb698c66ba9c71106795aff61d0cf4055.png 480w,
/static/941d052e58a938f66c9e551b0ed112aa/0b533/24148788906d3b5e2b2941aafcfcccafb698c66ba9c71106795aff61d0cf4055.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/941d052e58a938f66c9e551b0ed112aa/0b533/24148788906d3b5e2b2941aafcfcccafb698c66ba9c71106795aff61d0cf4055.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Next, in my test project , I’ve added the packages Angular Core and &lt;a href=&quot;http://pivotal.github.io/jasmine/&quot;&gt;Jasmine&lt;/a&gt; (the test framework).&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;172&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./6ae86e9985bf29136105589a9b906246308943f9862a05aebfa064631b88c286.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 34.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAAsTAAALEwEAmpwYAAABxklEQVQoz1WOuW7TAABA/RlUShquSDl8xEcOJ43tOpdzOHHsuGmipE1DGpAiFUGFCitCQurOtSAmBCx8Bl/CyMj8UNk6vOEtT08o1vrUGyEVy6ds+1QcH73mUbYGGAd98qUOitlDOxhQdEZU3JBqa0KtPcHqTXH9Oc1gyWAcs7d3ByGIN3SHS9zOEYedI3rBKdHsCeHsMd7ohF60xo83BNMtg+iMwWTNeLphtb1ksXnG7OyC+fopp+cXFIslBE01UGQVTdWRpQI1s8zY79K0q7Rsk16jjm3qlAyN+3dT6AUFu+FhVB10VSObyZF+mCaTybO/n0JwnAa1moWiaORyImq9hxPv6K6uaJ28wppf4Sxesni0I54tcb2AaHJMfxhSrdYpFiuIUoFCQSeRSCCMRhGWdYgkqeQyWazdJ46//iX6Cf538L6B+QXiz785//GHzvYtQ6+F2/TQjTKyrCKKyv+hZDKJoGklcnkZSdbIpx+gL9/Qvv6Fv7smevGB8eV7/OcfqWzfkQpeY3ozlJJF2nDJyjqiKN8O3ogk3VBAzOaRKzbllo/frON3GvSbNmG/zdhz0LP3MHQDN1xhtsbkZR1JVG4F/wFEIwChxPmkjQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/87939531630ab46ec336cf509d11e722/8ac56/b4be010687c328bcaa756094e3c5b938d819291f24205af75a40f984970fbc3e.webp 240w,
/static/87939531630ab46ec336cf509d11e722/d3be9/b4be010687c328bcaa756094e3c5b938d819291f24205af75a40f984970fbc3e.webp 480w,
/static/87939531630ab46ec336cf509d11e722/b0a15/b4be010687c328bcaa756094e3c5b938d819291f24205af75a40f984970fbc3e.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/87939531630ab46ec336cf509d11e722/8ff5a/b4be010687c328bcaa756094e3c5b938d819291f24205af75a40f984970fbc3e.png 240w,
/static/87939531630ab46ec336cf509d11e722/e85cb/b4be010687c328bcaa756094e3c5b938d819291f24205af75a40f984970fbc3e.png 480w,
/static/87939531630ab46ec336cf509d11e722/0b533/b4be010687c328bcaa756094e3c5b938d819291f24205af75a40f984970fbc3e.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/87939531630ab46ec336cf509d11e722/0b533/b4be010687c328bcaa756094e3c5b938d819291f24205af75a40f984970fbc3e.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Then I’ve added my test, which is a normal angular controller test, written in jasmine, asserting that during the initialization of the MainCtrl the scope.tasks is set.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;537&quot; data-orig-width=&quot;432&quot; data-orig-src=&quot;./b21824cdc4e527787bf25d25ff683e4326402d282dc464df3c8a10a1d6fc8d7d.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 432px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 124.16666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAZCAIAAAC+dZmEAAAACXBIWXMAAAsTAAALEwEAmpwYAAADx0lEQVQ4y42Sy24jRRSG2wkZL3gCLtLYfe+qvlT1vd23qu7qix3bsZ22nYmGONLMBrEiE7FigwRixZvwBsygSAM7HgoZEyAzQpnSr6PafDrn/8/hEHIRci3LMQykekQOmOKXSsCUgKn30h58SjUotZDBkHHPLr4o2YSQyvcj6ZufnZ/+UL9/C354q//4+8e3b/qvfn1y8/rk61/6N6/7r97sdXv35Pbuk2/vBt/9xgEAZVl2HDcIIhDVFl3o2SyZP7eKRXJ2BbNZsX5JuhfJYodZ5zYb5/Tanu7i82vRr7l+v9/r9RByKtbaFg5cz3c8VpSRH+ZpGnlBSSgrGEmzOIwiP4hiGqcsT0k2irmjoyOO4xirdrtrxw0JqfK8SvNiFGd+mMQpddzQDxKEPd2wDdMxLdu0HGz7i2X3NxzHyXJ1DjToBE591lBSns7ms+l0OjtbLpbL5fl2u51N54vFqqkbAKEoSqqqcb1e7wB33UYQJIQxcjFjFWP12fysHY9d10MII4RN0zIMS4e6LCuiKOm68S+8Xm8Hg6FhmADoOSkIoVXVlGUJABwOeZ4XBEE8SJJkUZQg1P8Lb4ZDXtcNG6MJDWjJMLYBgJqmiaIsSQ/0Ltx1m+FQUFUNQhhY2nKE/SC0bVuWlXfI/4U1DQJNm+R2jPWmbSkh0v49Bq/X2+GAN03kYuurS5qRIkszDQBR/EB4yBum5SDzy4uc5GQUjXhekCRZlpRH4X1gAOqmAdfTlNCiYhVCWJGVQ8KPeOZ5URRESQVBxkhOKC3KkjmOAwD8oMBkWdE0MG7H+z3XDSEkzfIsywRBPJj/p74/toAQjqJRlhNCCkqLth2HQSBK+2NUFFWWlUN9ACdJcn7eQWC4oVdMyzwjbds2Tdu246ZpJ5NJySpWsjhOqrrGCPG8AOHD83w64HWEDIxoWSZZzuomI1TWAC9KgqyI8r7nQe95Xm+lp0NfN7CmlUnWEjomdEypbxiQF3RB1AVRud/5e567TSHJDDutg29W+aZkl3VdIpRoINFACmAKYAHAobMkyfuxj4+PD/Cm28y8UZjXeUo3mTdfXawvrs5WF6vusp4sophGKesSmiVFnBTJX+I+/+xTjuNGo7jr1hOgN4Y1w/aLIr9i9cvpfFe3u2b8nFWVYTUmbkwEgAGAAaGJscudnHzEcRyEBqXVQNEHwOYBVp1Ys0PbC+I48f1wNIotCxmGaTs+xrZlWoqiQnDvWVFAmuTQzbVsCUOmRa0STSwnYqwtirptZ2XZpik9PV2MJ/OmmXjeyLaDPwFhbi1h8MscgQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/44b43a994350fd66fa679e319d3dc135/8ac56/cd0713106ccfe8acdb19747a6d76578a39136b9238d354e982bf950aa3e56c08.webp 240w,
/static/44b43a994350fd66fa679e319d3dc135/0bafe/cd0713106ccfe8acdb19747a6d76578a39136b9238d354e982bf950aa3e56c08.webp 432w&quot; sizes=&quot;(max-width: 432px) 100vw, 432px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/44b43a994350fd66fa679e319d3dc135/8ff5a/cd0713106ccfe8acdb19747a6d76578a39136b9238d354e982bf950aa3e56c08.png 240w,
/static/44b43a994350fd66fa679e319d3dc135/0e0c3/cd0713106ccfe8acdb19747a6d76578a39136b9238d354e982bf950aa3e56c08.png 432w&quot; sizes=&quot;(max-width: 432px) 100vw, 432px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/44b43a994350fd66fa679e319d3dc135/0e0c3/cd0713106ccfe8acdb19747a6d76578a39136b9238d354e982bf950aa3e56c08.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;364&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./91d7fe404373e1bc869d82bf23d1221b060dd6a95e6ecace3517b258f45e9470.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 72.91666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsTAAALEwEAmpwYAAACDklEQVQ4y6WTa2vUQBiFc9tMksltMplsko1t9ta77m6FShFEKYhYKFjED4L0//+KRzZbKEWLxX448MIwZ855zxnr6+0dX77d8f32Jz8+X/Hr5pqbq0+cnp6xWW1Yr9YDjo+OOTo8Zr3aMJvOn4QVhAF5YJGFNqpIcVwby7L+H74IGI1cslySZBEicHHc3aHtPGD7kOvYeI6N67rY9hMP+5FECEFtDO24Ytxo6omm22toJiXdfkW3ZwhCj0S45KFLLCM8b/R3wjBJh0EIn27SMp3OqVRKlYWoLCUMJY7tPN+yiORusG1ypej7KVpLkniE67h/XLD/RRilGf5oNOxFRpK2bTFbhXnEYvGKy8t3XLy9YH+vp65rjDEopWjbCfW4pigUQgS4nofneVhRkiF8nyDYhjMaFK7frDhYzvjw8T3r89ecnM1ZHHZorZjPFphKD3utxiXdpMOojDKP0brEEnHySPLW9vn5hs1mzXJ5MGC26FieTOgXFSdnB/R9T9e1NE09BLpdg2NbOI6DJeQDoQjEINsX/mA9TVOqcUVlxjRNi6lK4jiiLEvyPCdJkp3NR6HI+D5lQRSFLyv1UJt7y77vDz+lqjOKMqGsUrRJKEyKVimtilFxiJTy6VLvFO4IIylRhaKuK8pSY4xGlwVaF0O6Y1MSCv8ZPZQxgRBs//SL7W4h84IsTR+Ka7+M8DciuFXvBJznDgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/18f976335e32214c4244c976f43b2211/8ac56/5558596197a3110da806341a6c75cdca980a7f2b8a1fb3cca6b93ea345a8b3e7.webp 240w,
/static/18f976335e32214c4244c976f43b2211/d3be9/5558596197a3110da806341a6c75cdca980a7f2b8a1fb3cca6b93ea345a8b3e7.webp 480w,
/static/18f976335e32214c4244c976f43b2211/b0a15/5558596197a3110da806341a6c75cdca980a7f2b8a1fb3cca6b93ea345a8b3e7.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/18f976335e32214c4244c976f43b2211/8ff5a/5558596197a3110da806341a6c75cdca980a7f2b8a1fb3cca6b93ea345a8b3e7.png 240w,
/static/18f976335e32214c4244c976f43b2211/e85cb/5558596197a3110da806341a6c75cdca980a7f2b8a1fb3cca6b93ea345a8b3e7.png 480w,
/static/18f976335e32214c4244c976f43b2211/0b533/5558596197a3110da806341a6c75cdca980a7f2b8a1fb3cca6b93ea345a8b3e7.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/18f976335e32214c4244c976f43b2211/0b533/5558596197a3110da806341a6c75cdca980a7f2b8a1fb3cca6b93ea345a8b3e7.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;To run the tests in the browser, I’ve added an html file and use the jasmine runner itself to run the tests.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;500&quot; data-orig-width=&quot;356&quot; data-orig-src=&quot;./88d53e4601536575135ca83ad6da820099c538bf2899d231adafc32efbc2a67e.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 356px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 140.41666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAcCAYAAABh2p9gAAAACXBIWXMAAAsTAAALEwEAmpwYAAAE8UlEQVRIx5WV2Y8cVxWHKxL/AQ+GkHg8XUvXfruq9669a+set5eMZzzOjE16bBmxCCWgJFJwlFg8gIREBIEgIRYRglj+FJ4IJIoU4JnHIMHw/KGqmXHGiUjMw6dT97T6V7977rmnJOG4GMMUubiFPN9HzhsOHtBpmD+ck8/kmtiSHyCWt5CCgY+6/Q2sn/0D8cZfOf/a+2g/fB/nJ3/n8997D+ne2zz26jtI9/7UPrfx5T8f515+G+mVd5BefZfPvPIXnDf+hhSFEbrt4ydb9IISNyiJFtsMkiWT4grTahsnqMivHhBdvE52ZZ9J9RTWtGBaXaVf7SHKGwTb+zhhjVRVS1xH0O/18FyB57iU85xgMmUyHJGGEX3R42Jdt/kqz6nmOUO/Tx5HzKKcMNtisbUiGA2RkiRnOJqRzSvStCBJC7KsJE1LwjBr12lWMQsS4iRnOo0YDKd4/hjRG7bR609wxYBZkCJFUYbnDej1+gyHYzyvTxgmjEYT+v0h4/HsQd73Bwjh4bo9bNvFcQS2LXBsgWk6DIeTY0HH6bGxcQHf9+l2dfI8ZzYLyLKcqlqQJjGdjowsNygtivJRVDqdDtLu7l77xuYPnudjWjZRnLVii3pBkZdUVY3jOK2QqmqfiHT79p3WYSMoRI+eEFwqRoRxTBin2LZDr+eh63rr4lMF1+v1A0HHcRGuSzK2uZxOqZIItauj68YDsU8Tldbrw1bwtA7NtjqKxiXnAqHnsLW6TJbN0R5B7CHBpqB+f4BlWXzzixlZGhEmTR1rhCvaHfxfDk8PxTJNvrIXU+UJaTpva6o+ortjwcP1hw79fuvw6wcJeRqQzUsGvs/mibtHcnh48y7OyZaapjUMg7u7CVkSUpQL4ihC07otjyIqPfulF+j5PnLnw0PpRyVxOqeYzwmDkMViiWGYnD+/gaJ8sqh0+84dXNdDUbvIioZumJTLFWGUtA7rxRZBEBGlOcvlRbq6iaLpqP8D6ZnmUEyLzcc/i62rdFWNPByTzEaUyYwinlAlAWPPxrM01I3H2fzCOTpPfI7OE+da5CfPoZwgrW8dIJKnMG98h+n+S2Tba/Kv/Zj0yz9g8dxPyb/6Opee/wXR3e8jdr5F78Z9Bvv36T99TLN2rt/H3D1GWj+9g7d7j/lbkL/2R1Yvfpf650fc/P2/2Pn1B+y8+U923vyAg9/9m1t/+A97vz1i5zdHXHvriNWvjtr18pdHiNeP8H90dHz1mlm2qdn4kxhdjCi3rjKKCrJqRbW6RlpuoRgum11BR/84si5QTYFqiNPGFnQubOAJgWkYhGFMEsdURU6WJuTzDMvQUTqbqIqMKnc+hnJCK9icctO8vtfHtmyuLSPmaUJZVCRRzGQ8xTIsFFlBa9pGUdvYdIXStkv3TGOvDzGdHmNZZqc/oLJtvr2Xsh9NuZFk7E4nxIpKaVothWFSNM+6Qd7V6ajHL3hIsGsLCl1n1tUxVI1pXLOcF1xdLLlc1WxfuszFvGBVVlxZLFjVNa7aZWWYqGdG2xmHgoGqUTVNbZrc9Cz2goDbyy2eKUrW9ZLDuuJ6GFE7LoVlU+gGqWkhN1fyrODptNmUFS6oGpqus0pnTIKQrKpJi4JpGJEWFfOqare42aB129iIKWeu4kMDtvmxmc7TIGY2nZGmGXVVEwUhwSykzHOM00/BCcpHavhftYeuV4TpOLgAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/8909396fdce6b03c662165084e39d0bd/8ac56/b44d7a78bdefb104c4862d5a496611fad4668cfc4ca45a7884b5927869a82fb5.webp 240w,
/static/8909396fdce6b03c662165084e39d0bd/64477/b44d7a78bdefb104c4862d5a496611fad4668cfc4ca45a7884b5927869a82fb5.webp 356w&quot; sizes=&quot;(max-width: 356px) 100vw, 356px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/8909396fdce6b03c662165084e39d0bd/8ff5a/b44d7a78bdefb104c4862d5a496611fad4668cfc4ca45a7884b5927869a82fb5.png 240w,
/static/8909396fdce6b03c662165084e39d0bd/50ac3/b44d7a78bdefb104c4862d5a496611fad4668cfc4ca45a7884b5927869a82fb5.png 356w&quot; sizes=&quot;(max-width: 356px) 100vw, 356px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/8909396fdce6b03c662165084e39d0bd/50ac3/b44d7a78bdefb104c4862d5a496611fad4668cfc4ca45a7884b5927869a82fb5.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;404&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./dcc2c15d9afde4ff2ade70ad66c07d86ffc639511332b816ebb01d3a48d95489.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 80.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAAsTAAALEwEAmpwYAAACDElEQVQ4y5VSy27bMBAUJUp8S7IkUg/KlpPUTX+g6KVA0EuPPfUUJ22v/f8PmIK04xZB4ziHAZfEYHZ2h8nvXz9x9+kjvn+9w7cvn/H+3Q7LZsFmPWPt15jG6QgPHzB5zNPh/B+S+/0DkiQBYxTeaXjvMYwWw9SiaxQEy0HSBBlNkJAkcs9ifxSUgmMZK/SuQ91KuElHtM7A9TXmsYLRHISkrwg+PMZCcIa10+i7BlWjYEeF3musrEDnDEZXo6slsuwgSF5yu3/8cRJcBhMdBkE3KQyzQe9LDKOBdRqrRkCZAkIwVIqhyLOXHKZgrIBbScyuhrUVqkZCagqpOQpKQdP09f39dUiQZYduK82xXZaYtO0s/DRhGAZYayOH0uzEPSsYiOHBdi1ubz9gt9vharuFHxxurkKDdRSu6xpaaxBCzgiS0JnGB60NXFOhtx2urq/Rdh36tsboOszzjDzPLxiZpCdBYwy6tkHbtqiNQltKlFWJvKDIcwrGWBQN/FCHM9yf6mT/eAiFHvdCaY5xnLDZbND3DlopCMFRsAyM5XECpRQ4FyjLElLKeA914J1Gzo8OJaNojICzFs710elF6T4fOSw5uBOcQ0oRRw+dQwDppV/m31CaSsM2Bkqwtzl6jvvwsUmGrQ8hCBSMHfbF8yhOyJsFH+I/vFkGuLaCUhpKCSgloXVYPo8JXoo/nGJx+YiDflsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/1c9abeaf8eb67b64749935914324acf7/8ac56/9c48698fced615814a9a23b2e11a1e3961f42c014778d716d628987f14adad69.webp 240w,
/static/1c9abeaf8eb67b64749935914324acf7/d3be9/9c48698fced615814a9a23b2e11a1e3961f42c014778d716d628987f14adad69.webp 480w,
/static/1c9abeaf8eb67b64749935914324acf7/b0a15/9c48698fced615814a9a23b2e11a1e3961f42c014778d716d628987f14adad69.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/1c9abeaf8eb67b64749935914324acf7/8ff5a/9c48698fced615814a9a23b2e11a1e3961f42c014778d716d628987f14adad69.png 240w,
/static/1c9abeaf8eb67b64749935914324acf7/e85cb/9c48698fced615814a9a23b2e11a1e3961f42c014778d716d628987f14adad69.png 480w,
/static/1c9abeaf8eb67b64749935914324acf7/0b533/9c48698fced615814a9a23b2e11a1e3961f42c014778d716d628987f14adad69.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/1c9abeaf8eb67b64749935914324acf7/0b533/9c48698fced615814a9a23b2e11a1e3961f42c014778d716d628987f14adad69.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;And here is the result when opening this html file in the browser&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;334&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./fd70cc056bd1962dd883b35030dc1a2ea97150db5b74b72860290d286135e425.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB90lEQVQ4y62QbU/TYBSG+6s1IIn/wgCawPxs4KMbSCbqttIWNowO3XtfGOvG2vW9e2kv03WRmJgY0fPkyrnPc57cOecRPl0bVK5aXFz3+dIZ8eZ9l51X12zvN9jer7O1V+dZpveu2N7L652XjfXd84Ov7Bw0ebp7ydZunScvFITY93AnU0J7hj+1CW2b0LI22SawLKJM23kO1j1rneeuiz9zsEwTz3bo9PoI89kC82bMuHVPNIoJRzHBMMTVPHwjAIcHXPC0AFt1sPozpm0Lb+gzbk6IJyH63T2CFmucdE44V885/XbKWeeMcr/M6fd3fBh+RPRFqnYV0RURnRqiIyL5ErVZjapVRfIkKlaFtt9CNyYIaqRS0kqUh2Wq0yqSc7F+dOFKyL6MEivIoYwcySiRghwpKPHlupYDictML2QGqx66PkEwYxPZkKm1akgDCbEjUrmpUOuKtBdteqse3VX3V5YPupf0aPpNNE9FM8YIo8WIov2WwucChcZrCo0Ch/XDNUd3R5RWJYrzIsXFb5gXKS1LHDvH1L0rDP0eIVgG3Ma3DLwBA3fDRqu+ih7rfyT7Nntp5ROS8t9CNUyENE3JSNLkr0k3J9M/DZMkN3wMSZLkpPmaqm4i/MuKaTblZrosjOEYYeZFOF78OPyczMMPFzTbBj8AewrBH+MHdD8AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/8f4961a01e4490c61daf1e36ba986b19/8ac56/5a7dedc60ab929801280bcfc076e5629e24a6dd22622a5d7e962c410f548a4fa.webp 240w,
/static/8f4961a01e4490c61daf1e36ba986b19/d3be9/5a7dedc60ab929801280bcfc076e5629e24a6dd22622a5d7e962c410f548a4fa.webp 480w,
/static/8f4961a01e4490c61daf1e36ba986b19/b0a15/5a7dedc60ab929801280bcfc076e5629e24a6dd22622a5d7e962c410f548a4fa.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/8f4961a01e4490c61daf1e36ba986b19/8ff5a/5a7dedc60ab929801280bcfc076e5629e24a6dd22622a5d7e962c410f548a4fa.png 240w,
/static/8f4961a01e4490c61daf1e36ba986b19/e85cb/5a7dedc60ab929801280bcfc076e5629e24a6dd22622a5d7e962c410f548a4fa.png 480w,
/static/8f4961a01e4490c61daf1e36ba986b19/0b533/5a7dedc60ab929801280bcfc076e5629e24a6dd22622a5d7e962c410f548a4fa.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/8f4961a01e4490c61daf1e36ba986b19/0b533/5a7dedc60ab929801280bcfc076e5629e24a6dd22622a5d7e962c410f548a4fa.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;But my main goal is to run tests using the test explorer, instead of running in the browser.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span id=&quot;docs-internal-guid-62fa1205-8b67-ebaa-c809-32ae64c5bc6c&quot;&gt;Introducing Chutzpa Adapter for Test Explorer&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span id=&quot;docs-internal-guid-62fa1205-8b67-8990-ca78-9d130ccf373e&quot;&gt;&lt;a href=&quot;http://chutzpah.codeplex.com/&quot; target=&quot;_blank&quot;&gt;Chutzpa&lt;/a&gt; ia a javascript test runner which supports QUnit, Jasmine, and Mocha frameworks, and provides a VS Test Adapter. Let’s install it in VS, choosing menu option Tools -&amp;gt; Extensions and Updates&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;398&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./b0a0d03abd3fca6b4bcd09ca2c2fbe7d2c2ecc47f2bf6790fdee9b3cecf39ab8.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 79.58333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAAAsTAAALEwEAmpwYAAACm0lEQVQ4y31U/VPaQBC9zvSXIopKIXyFEDVflxxJLrmEAApSQanY/v9/zevsaRjb0f7w5sLs7du3b/dg1XyJ9WqDsqiwXN6hqhZYLG5RVUsIkUCp2RsqpGkOKRWKooJMc8Sx1LEsK96+SzAKbrdP4DyClBmEmCLPS02u8gKbH1ssF7e4vVsjTaQmXK3uIWWu7+33z1gslgiCCLvtDuzh4RGr1QZ5ruD5PqbTBEkiwXmoC1xdXaPTMWAYPfT7A41u18BwONLFp9MYtm3ruO+HYFORQogUPufgUQjfCyClBA8jJEmK2WwG13E1wWhk/nXWBQaDEQaDIXyPg41tA+akg2vHRl4oiGiK+XyOOE5QFIVWUScSCSXWoN/v0W5/B2sb39C6/IqeaSEIUyRxgrKsoJRClinEcYwsyxFF4kOSugipbjQaYOwLA2MMl7YHc/Mb3HWR5UoTkK9KFfokpXXyR4R0NptNsOFwiPNWC+a1g57DISKBNJUIwwi2faWHQqDvV+/Mo4evrb+eljVBs3kKxsMQlmVhYk0wGY8hprEmpOnVRHT5X2VESvHJxD7e0wodx0W38x3jsaV3MQi4nm5ZlMiVQlnOIFN5VFXDNMd6xcgaun9z46DROAHzPA+B72FkWuj1+ojjVO8fqVTawxJCCN0akdag1utp9/tDXUArFCIC58GxLapIA0iSRPtIRepF/h+oyMlJE+ysdYaLyza63Z4GqaPFpulSu7RGtJOjd4v8EcgyTTi2LHQvTpHFEdb3G6xWa+z3P/H0tMdu94iXl184HA6alNR/BoqTUua4LsLAQxSF2lx69PTYn58PeoWofUrwPB+u630KGi4NlPkBBw3G6Br6T4ASyTvOua5I/tHDJy8/a7eOtVrn+AMdvM3DhW/vlAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/24d22e94ceaa33c4da7e63d7ee394ff2/8ac56/adc28b3bc1f335d1761cd4f4dd02261644d49ac1ece82e841f08f40062e32a5e.webp 240w,
/static/24d22e94ceaa33c4da7e63d7ee394ff2/d3be9/adc28b3bc1f335d1761cd4f4dd02261644d49ac1ece82e841f08f40062e32a5e.webp 480w,
/static/24d22e94ceaa33c4da7e63d7ee394ff2/b0a15/adc28b3bc1f335d1761cd4f4dd02261644d49ac1ece82e841f08f40062e32a5e.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/24d22e94ceaa33c4da7e63d7ee394ff2/8ff5a/adc28b3bc1f335d1761cd4f4dd02261644d49ac1ece82e841f08f40062e32a5e.png 240w,
/static/24d22e94ceaa33c4da7e63d7ee394ff2/e85cb/adc28b3bc1f335d1761cd4f4dd02261644d49ac1ece82e841f08f40062e32a5e.png 480w,
/static/24d22e94ceaa33c4da7e63d7ee394ff2/0b533/adc28b3bc1f335d1761cd4f4dd02261644d49ac1ece82e841f08f40062e32a5e.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/24d22e94ceaa33c4da7e63d7ee394ff2/0b533/adc28b3bc1f335d1761cd4f4dd02261644d49ac1ece82e841f08f40062e32a5e.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Then, search for Chutzpah, and install extension Chutzpah Test Adapter for the Test Explorer.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;233&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./1c12050a1b5251d0ad635de4060df13b5a745e3a966583e50992dff99b1db887.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 46.666666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsTAAALEwEAmpwYAAACNElEQVQoz3WPS08TURhAZ4U/AqP0AbWUzrTTd3n0QZ/TdtpCwZaCVBObhhp8pAoocWFManBFQmJIBE1KMTEukIVUd2xcAgk73OkPOWaGyM6bnNxvcXPu+YT8bBOlWCeWqTEWX2A8uUg8X0cpNUkU6iSKdVLTDdKlBrnKAwrVZUq1xyw0X1J/+oa7j15zv9WmsbJBc+UVQmg8RNAfxOP24JJduJwyDtHBzPQM5dkypamSPhfUAnm1QCaVxR8IIMkyft8YdrsTm03EYrFiGrQi+PyjpNM5PJ4AthEJUZQRJTel0hzV6iLlygKVyh2q8zWWlposLz+kVqtRnZ9n9dkTGvduUyzmcbm8OCQZwe32kU6rBIPj+k8jIxKGAQPxeAJFUUil0iSTKbLZDL1eh/PzH5ycfOP09IizsyP+/P7J5y/vuWmw6JVCODxJNBJDFJ26TJJkynMVFCVDNpvTyWSyeL0+YrEIipIkGg0Rj0fZ2dmm2/3I9vY7Njbesrr6HEFLFe2OqzpJclKeTJDN5FDVPLmciqqqhCbCBAKjBINj2Gx2blmG6XS69Pdfp6/vGi6XTKezhyCKDl1kt1/eWunURIRIJEooFL5CK/R6vQQCQSRJwmod5vj4mPX1FxweHtJutzk4+IqgraiJ/km10htGEwMDBgwGo442m0zmK4xGE5LkYH//E61WC+2sra3R633XhM4r2WWlyNCQhcHBof9iNpv1d7u7H9ja2uLi4hebm5vs7XX5CzV8WukRQQ/fAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/1d0b6961a13f160a9422a182cdea8224/8ac56/8d173c7fec1bd706fd06f41012219e0be9dde5bf2a7b89e3662d72b738ee93c5.webp 240w,
/static/1d0b6961a13f160a9422a182cdea8224/d3be9/8d173c7fec1bd706fd06f41012219e0be9dde5bf2a7b89e3662d72b738ee93c5.webp 480w,
/static/1d0b6961a13f160a9422a182cdea8224/b0a15/8d173c7fec1bd706fd06f41012219e0be9dde5bf2a7b89e3662d72b738ee93c5.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/1d0b6961a13f160a9422a182cdea8224/8ff5a/8d173c7fec1bd706fd06f41012219e0be9dde5bf2a7b89e3662d72b738ee93c5.png 240w,
/static/1d0b6961a13f160a9422a182cdea8224/e85cb/8d173c7fec1bd706fd06f41012219e0be9dde5bf2a7b89e3662d72b738ee93c5.png 480w,
/static/1d0b6961a13f160a9422a182cdea8224/0b533/8d173c7fec1bd706fd06f41012219e0be9dde5bf2a7b89e3662d72b738ee93c5.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/1d0b6961a13f160a9422a182cdea8224/0b533/8d173c7fec1bd706fd06f41012219e0be9dde5bf2a7b89e3662d72b738ee93c5.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;After that, restart Visual Studio , and check the Test Explorer Window.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;229&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./800a9ee8d3f4b636c3709517caa3745633e94132d169957bc93e939fe981be30.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 45.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB0ElEQVQoz23QS28SARiF4UmL7FtK4kLL3IeZgblxmWtxCrXtcAl04cak2OjCKBYT/ReuaqMuTIw/9TWAocS4eHJOvsVZfIKXnlOfLjCnC6yrW46H7zBmC5SrT0izzxwP369vu6TJB5TpEnG8QBov0GdLjItXuH4HIZvdYN7+wvv4E/3tdx6//kH15huV6zuOVub3/1WZf6Uyv6d6fUd9+Zvmmy+YtosQhQlJnHGapbRdh0GW0As7xIFHHPh/89++kQQ+Xc/leZ5zevKMw4NDhH7eZzyZYKZD7GyEmRSY8TlWcrllZmOseNULzHSElRaY2QQrOsNpOjQdF88P2NvbR0iSE4ygx1M7omZ4PLG6KKqO5nSptc6QnBTRz5GdGM2wkHUTWVupb8gKiqKiKBqlUgkhzwc0/JC01yfOerSTnHYQoOomtbqHqNapaTaSbiNLMpIooakqmqptaPpWuVxGaPst4sEFoxcvGRWXDIuCohgx6PcJO22SZPXjiCgMieOUMIwwDAN1O6ahqps8qh4gRN0IvenTaEU0bBvHcXFdj06nu/5LELQJghb+um9S1x8Gd3N/v4SQpj1kUUSRZWRFXf9kRZLkbW483HZHdnup9Ig/BT4jf/w/aVIAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/c18e425283fa34853868e45655e7a9d1/8ac56/9b5def50faf7c9cbca16020b9a8571bfb2aad3d1054e2e675cc8807fa8e0b0ed.webp 240w,
/static/c18e425283fa34853868e45655e7a9d1/d3be9/9b5def50faf7c9cbca16020b9a8571bfb2aad3d1054e2e675cc8807fa8e0b0ed.webp 480w,
/static/c18e425283fa34853868e45655e7a9d1/b0a15/9b5def50faf7c9cbca16020b9a8571bfb2aad3d1054e2e675cc8807fa8e0b0ed.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/c18e425283fa34853868e45655e7a9d1/8ff5a/9b5def50faf7c9cbca16020b9a8571bfb2aad3d1054e2e675cc8807fa8e0b0ed.png 240w,
/static/c18e425283fa34853868e45655e7a9d1/e85cb/9b5def50faf7c9cbca16020b9a8571bfb2aad3d1054e2e675cc8807fa8e0b0ed.png 480w,
/static/c18e425283fa34853868e45655e7a9d1/0b533/9b5def50faf7c9cbca16020b9a8571bfb2aad3d1054e2e675cc8807fa8e0b0ed.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/c18e425283fa34853868e45655e7a9d1/0b533/9b5def50faf7c9cbca16020b9a8571bfb2aad3d1054e2e675cc8807fa8e0b0ed.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Ok, so now we have our tests in Test Explorer. Let&apos;s try to run them.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;510&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./cf705ef2662ecb8aaa76c7e08f725c95b97e8dfc2db34171cb401001af710688.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 102.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEc0lEQVQ4y3WU2W4aVxjHeYVE8QIDZoZZ2AY8doxZZwYYwIDB2IwXMMSuk9pxoiyOLxInbdRVTZsU9wl61dRS36A3lfpmv4pxLLUXvfjp/y1HR99ydHzOWpfEwTcsHf+APv4CcfAWaf8rhO3X+N0LAu7rT1z8D6/x91+ROPyWu6cf8OUzOTpJnV0jTSsi0YtpbOtxumqEjnKDREeR/+XfxCJ0lQjtiIibjDMwDHxmqcyg1SC7WiWxaJNatDzVUwX0RRM9XUI3yuiL1jU3tlEmuVRFTxcxIjLpiMJKNIbPMm1imTKhzBpiOouwVEVMZYilDMTcOqFsm/BKnYVsG/muhRLXkeLp/xCJxonEEsixJL56bY1keonUkkEmFcXQYyzGJNTgDOGgH3GKMOupJMwizd/yUPy3UAI3ehs5cBtp/ja+1WweM1/ixZe/svXT3wze/8XGd3/ivPwD6+w3is8/Ujr7ndLZR8wXv1M8uyJ/dkX68RWpR9foj65YfnLl5XyFgkkqkaK99ZTs/Q+Ujn4kd/Qe5+EE5/QS6+SS8sMbnVA+ucQ6nqCPJyTHl+jjSxKjCcbhBPtkgq9arROLJwiFAkSEWeTQPHJwDkmYQwzMIH1CDNzx8tPYNK+GZpGFOyjCHdTQDEpwxhuJr1S0sSybfn+b4f4Yd3ePzf42B4f32R/dY29vyNamy2A4ZntngOvusD86oO/ustXfoeLUiCgaWjSOqsWuK9RUjaSeotFosLySI7xcQ1ptIWbWkFYaSMsVlHgKVVFR1SiKqnmoWvTaV1SP6PTZlKwqVcNgPZuhYFpUK1Vy2RyFQsGzbdum5jgellmiWqlgmSaVsk3ZsjCLBWKahiwrlMtVfPV6k5iqcnclx+bOkG7PZa21wcaWS7uzSbvbx2lt0Or0aPdcOpt9Ntw9Ou6AxuaArdEJ5WYPTYtSr6/hKxYtoopMOJXD33yCWH9AqH6C0H6GsH7mEWg+JdA5J9B6TqB9RmD9nHCxTzjfRSz2UfJtZDVGvdbAl8+baIqCll4l2jlFsEYEzCHB0i7B8pigPWSh6BIquSwU+59wETMNFhYt0lmTTr3s3VGbVuhUG6iqhq6nvHmJkkwmkyFm9ggbNtKSRXi6oNUmoqctwrmux0K+R9jcJlLcREosU6/V8dVqTWKaihQ3mLcPCNpjxOqYBeczBOdzgs4RwcoBQv0hQu2YoHMfoX56bU/jtQeIyxVkRbueYSaTI6qqyHEDsbhFMNsj1TpEct8w33yG0HiEf/0cf/s5/vYZ/u4r/BsX3iz93Qv8nXPC049Dkpgu2JdMptEUFTmxTMjeJ2TuIdoDFir3CFr7XmxaVXDqV48IlUfemZA98vxpfDpXKbF03bKeMtCmFcZSiNk2C8sOi+UeSvMYwb5H0HngtRhoPkFonHob96+/8FqeVjltWU4sIUfk65a9C+UI0qLJ3NZb/O1zgttvmR9NmO+8RFh7zMzoF2a3v2d29x3zm2+8c3P9r5ndecfM8GdmhhPChknDcfgHvpevIJnozVMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/278f4fd3eecd4da76e4972784ae52867/8ac56/bbab05ddb61e8767239fd9f22d7f428c79f7e2108a6299ff1c84b899d5484214.webp 240w,
/static/278f4fd3eecd4da76e4972784ae52867/d3be9/bbab05ddb61e8767239fd9f22d7f428c79f7e2108a6299ff1c84b899d5484214.webp 480w,
/static/278f4fd3eecd4da76e4972784ae52867/b0a15/bbab05ddb61e8767239fd9f22d7f428c79f7e2108a6299ff1c84b899d5484214.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/278f4fd3eecd4da76e4972784ae52867/8ff5a/bbab05ddb61e8767239fd9f22d7f428c79f7e2108a6299ff1c84b899d5484214.png 240w,
/static/278f4fd3eecd4da76e4972784ae52867/e85cb/bbab05ddb61e8767239fd9f22d7f428c79f7e2108a6299ff1c84b899d5484214.png 480w,
/static/278f4fd3eecd4da76e4972784ae52867/0b533/bbab05ddb61e8767239fd9f22d7f428c79f7e2108a6299ff1c84b899d5484214.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/278f4fd3eecd4da76e4972784ae52867/0b533/bbab05ddb61e8767239fd9f22d7f428c79f7e2108a6299ff1c84b899d5484214.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;As you can see, the tests are failing, because Chutzpah is not using the html file to run the tests, hence it is missing some refrences. To fix this, we have to add some comment document references to our test js file&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;382&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./ec38f1c0ed46d5921356069ca3589b2401f023f7e36a699c46c219920e47bc2b.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 76.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsTAAALEwEAmpwYAAACVklEQVQ4y4WTSY/bRhBGm0tvbFIUl6ZEzogajUSOFctAAsSAD7k7pyCWl5OP/v9/4RmklPEg8WQOH1BkVb+urcW3j2d+Pz7w57u3/PHbr5yGgdeHA6fDwOlw4M0w8mYc+eV+z9D3bNdrNt5ze1XfNAxtS+MbVr5B/PX+PUIIgigmSTOybIFLU5IkIXGOZVGQL5ezssXFJ5VCaU0sJSIQLOJoZsz6ej5jw5jBF9zlljtf0qSOpVIUWlMac5E2j9+VsVTWUk221mRK/QD+fT7PhksseW5Ylg5t4h8BTxUIAnGRCIKfx3y4Ao2x1FXF2lf4VUHTFbSbBr/Kue0bqlWGkiG5DkhNjLH2GeCnzwgRkaaOxFru+g3j+EDfrdi2NY331LWfL5RSEUs191BKiZp6qRRa60ddgQHOJcSxpPZ+BnZtQV1YrDEYY4jjeD4wDcsYjbX2apsZPvkniQ8fP82pKiUf0/be0zU1Te7Y9hv2hwPDMNI0DVVVkmUZy2KJ9zV5ns9Z/qtkgX7ycwp69erIze0Nx+OR2pd0fUnpE8qqZN2uKaqUolrM67TIUlI9tS39OXBynE4nTqfXjMPAw8PIMO7Yjx27oWN3v2XdtnRdRzZB/pn8nOHnLwgRoq8lT72Zmh+EEUVR4hJHnk+LXVDVNYmzOOcuPucug/jvlAOkjGfQIs9QOiSSAWEkiGJBEApCIYiFQD59Fc+vTYiSkjAMqeqC3X7DZtux3d2y6VtuNi37u55t63HWEEXxS0CB0XouYVqd5zMI/j+7GXhdm+mVTGW/eOAFfQfGAF7nBEV8/wAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/f44a521f91423c0928a6e89846746b68/8ac56/8a25bfc4759f3b03b34e23051b73967d166e0490b8292b7e70e3ffb2fe9e0c9d.webp 240w,
/static/f44a521f91423c0928a6e89846746b68/d3be9/8a25bfc4759f3b03b34e23051b73967d166e0490b8292b7e70e3ffb2fe9e0c9d.webp 480w,
/static/f44a521f91423c0928a6e89846746b68/b0a15/8a25bfc4759f3b03b34e23051b73967d166e0490b8292b7e70e3ffb2fe9e0c9d.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/f44a521f91423c0928a6e89846746b68/8ff5a/8a25bfc4759f3b03b34e23051b73967d166e0490b8292b7e70e3ffb2fe9e0c9d.png 240w,
/static/f44a521f91423c0928a6e89846746b68/e85cb/8a25bfc4759f3b03b34e23051b73967d166e0490b8292b7e70e3ffb2fe9e0c9d.png 480w,
/static/f44a521f91423c0928a6e89846746b68/0b533/8a25bfc4759f3b03b34e23051b73967d166e0490b8292b7e70e3ffb2fe9e0c9d.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/f44a521f91423c0928a6e89846746b68/0b533/8a25bfc4759f3b03b34e23051b73967d166e0490b8292b7e70e3ffb2fe9e0c9d.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s run again our tests.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;316&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./1fba4752b88bee680713be7bccc2b24fb8515728dce2b126be3586b953232b1f.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 63.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAACiUlEQVQ4y32QTXPbVBSGFTNlMm2AxvE0XUBsfVi6khxZ/pJsy5ZsWVZlx46DEwpMu+2u7YIlDL+D3wFlhg3DX3sY3TQtWdDFM690zp3nnnsU9dd/aP78F7Wf/uTw9R88evuOh59A9t+84+jN75z98jdnr37DsV0c18N1PZTk6nsmeUF/njMqLmknGd50QTvOaN/l3fcdcYY7yZhdPWe62lGtVjk+rnJycoIy2kU00xB7EeDmI0TaQywG2PMyA+x0gCjJhvK/zLLmRCbezMWfelJYq9V4evoUpRMVfONGNM5j6k6I4Q5Qu0safkqjk6H6KbobojkBmhPeYvcwtCaGbmEa1gfh6ekTFPV8SMvvI/wA+9xHmDp1t0/d6VK3POpOD13XURtn6FrjPaqsabpGo6GiKMpHLq4v+PHFC272N1zvvyNNl4SDkDAYMgxHMsMwIgjHdLsBbb+P7/dpt7uE4Rjf71KpVKTs4OAApTcLSBYZi8Uz5vMlq9WG1XrLMl9TFBuW+YqiuCDP11JcykpxpzMgTXMmk+T+hMK0EZZACBvbtrGFQFiWxDJNWbfe9x3HxXEchBDouoGm6fLJR1894MvaA744PkRJ5wv2+xt2uytWl9fsn79kd/0D6+235Kst28srVsWazWbL5mLLcpkznU6lsNm0sB1Bz+vQrsZ8flhBsVxBPI0ZDkfofow+yLCCDBEucII5bsuTk7luS9Jqncs0TYtm00Q3DB4fVXl88PXtk7tJnySekT8rmCVTplFEOp8zHg6ZJQlxnDAeR3Kq/2Z5iWE05aT3dqipBlE0kYeCIGQQhHieR0PV5I7+j1ImJ9QNKpXPPgrLhqpqkrvDt/sxP8l9YeWD8F90O5dLfLixsQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/567f4a55b2e04ac71bcf84c9bc065337/8ac56/fec5b6e42f925850c6466bde26159670f643288812ae7e5a96cf756945e0cfc3.webp 240w,
/static/567f4a55b2e04ac71bcf84c9bc065337/d3be9/fec5b6e42f925850c6466bde26159670f643288812ae7e5a96cf756945e0cfc3.webp 480w,
/static/567f4a55b2e04ac71bcf84c9bc065337/b0a15/fec5b6e42f925850c6466bde26159670f643288812ae7e5a96cf756945e0cfc3.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/567f4a55b2e04ac71bcf84c9bc065337/8ff5a/fec5b6e42f925850c6466bde26159670f643288812ae7e5a96cf756945e0cfc3.png 240w,
/static/567f4a55b2e04ac71bcf84c9bc065337/e85cb/fec5b6e42f925850c6466bde26159670f643288812ae7e5a96cf756945e0cfc3.png 480w,
/static/567f4a55b2e04ac71bcf84c9bc065337/0b533/fec5b6e42f925850c6466bde26159670f643288812ae7e5a96cf756945e0cfc3.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/567f4a55b2e04ac71bcf84c9bc065337/0b533/fec5b6e42f925850c6466bde26159670f643288812ae7e5a96cf756945e0cfc3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Voilá. Now I can run my angular tests in Test Explorer.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[D3 on  Angular]]></description><link>https://bfcamara.com/post/72962664364/d3-on-angular</link><guid isPermaLink="false">https://bfcamara.com/post/72962664364/d3-on-angular</guid><pubDate>Sat, 11 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://www.ng-newsletter.com/posts/d3-on-angular.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://www.ng-newsletter.com/posts/d3-on-angular.html&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Combining the power of D3 and Angular can be challenging and confusing. We constantly get asked how to integrate the two in our classes. In this post, we aim to clear the confusion and bring you the best documentation on how to integrate AngularJS and D3.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A great post explaining how to integrate D3 with Angular.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Implementing custom password policy using ASP.NET Identity - .NET Web Development and Tools Blog - Site Home - MSDN Blogs]]></description><link>https://bfcamara.com/post/72543323448/implementing-custom-password-policy-using-aspnet</link><guid isPermaLink="false">https://bfcamara.com/post/72543323448/implementing-custom-password-policy-using-aspnet</guid><pubDate>Tue, 07 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://blogs.msdn.com/b/webdev/archive/2014/01/06/implementing-custom-password-policy-using-asp-net-identity.aspx&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://blogs.msdn.com/b/webdev/archive/2014/01/06/implementing-custom-password-policy-using-asp-net-identity.aspx&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;&lt;em&gt;&lt;span&gt;To provide a more secure user experience for the application, you might want to customize the password complexity policy. This might include minimum password length, mandatory special characters in the password, disallowing recently used passwords,&amp;nbsp;&lt;/span&gt;&lt;a&gt;etc&lt;/a&gt;&lt;span&gt;. More information on password policy can be found&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Password_policy&quot;&gt;here&lt;/a&gt;&lt;span&gt;. By default ASP.NET Identity enforces a minimum password length of 6 characters. This article provides a simple walkthrough that shows how to add a few more password policies to an application.&lt;/span&gt;&lt;/em&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Worth reading to understand how extensible is the new ASP.NET Identity System.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[The real use of money is to buy freedom | Paras Chopra's Blog]]></description><link>https://bfcamara.com/post/71508444018/the-real-use-of-money-is-to-buy-freedom-paras</link><guid isPermaLink="false">https://bfcamara.com/post/71508444018/the-real-use-of-money-is-to-buy-freedom-paras</guid><pubDate>Sun, 29 Dec 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://paraschopra.com/blog/personal/money-buys-freedom.htm&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://paraschopra.com/blog/personal/money-buys-freedom.htm&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;&lt;strong&gt;A life spent mostly hoarding money and possessions is a wasted life&lt;/strong&gt;&lt;/blockquote&gt;
&lt;p&gt;Great blog post. Worth reading.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Announcing preview of Microsoft.AspNet.Identity 2.0.0-alpha1 - .NET Web Development and Tools Blog - Site Home - MSDN Blogs]]></description><link>https://bfcamara.com/post/70779342118/announcing-preview-of-microsoftaspnetidentity</link><guid isPermaLink="false">https://bfcamara.com/post/70779342118/announcing-preview-of-microsoftaspnetidentity</guid><pubDate>Sun, 22 Dec 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://blogs.msdn.com/b/webdev/archive/2013/12/20/announcing-preview-of-microsoft-aspnet-identity-2-0-0-alpha1.aspx&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://blogs.msdn.com/b/webdev/archive/2013/12/20/announcing-preview-of-microsoft-aspnet-identity-2-0-0-alpha1.aspx&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;.NET Web Development and Tools Blog&lt;/blockquote&gt;
&lt;p&gt;Do you remember my previous post&amp;nbsp;&lt;a href=&quot;http://www.bfcamara.com/post/68977237610/asp-net-identity-1-0-where-the-hell-is-the-recover&quot;&gt;ASP.NET Identity 1.0: where the hell is the recover password feature?&lt;/a&gt;&amp;nbsp;Well, the .Net Web Development and Tools group just announced a preview of Microsoft.AspNet.Identity 2.0.0-alpha. In this new release it is already included Account Confirmation and Reset Password. Well done!&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[The story behind _references.js]]></description><link>https://bfcamara.com/post/70430674077/the-story-behind-referencesjs</link><guid isPermaLink="false">https://bfcamara.com/post/70430674077/the-story-behind-referencesjs</guid><pubDate>Wed, 18 Dec 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://madskristensen.net/post/the-story-behind-_referencesjs&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://madskristensen.net/post/the-story-behind-_referencesjs&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;The _references.js file controls a key part of the JavaScript Intellisense in Visual Studio for web projects and can mean the difference between awesome Intellisense and none at all.&lt;/blockquote&gt;
&lt;p&gt;Worth reading to help to understand that _references.js fle under the scripts folder in Visual Studio.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Entity Framework: Resetting your migrations to an initial migration]]></title><description><![CDATA[Entity Framework: Resetting your migrations to an initial migration]]></description><link>https://bfcamara.com/post/69880211351/entity-framework-resetting-your-migrations-to-an</link><guid isPermaLink="false">https://bfcamara.com/post/69880211351/entity-framework-resetting-your-migrations-to-an</guid><pubDate>Fri, 13 Dec 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;When using Entity Framework Migrations, probably, &lt;strong&gt;we are going to have too many migrations, even before we have an &lt;/strong&gt;&lt;strong&gt;initial release&amp;nbsp;&lt;/strong&gt;of what we are building (I&apos;m not using Automatic Migrations). &lt;a href=&quot;http://www.bfcamara.com/post/68169174771/entity-framework-database-first-vs-code-first&quot;&gt;In one of my previous posts I mentioned this problem around Migrations&lt;/a&gt;.Let me show you an example of what I&apos;m talking about.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;516&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./06990a4b2d108b9743c1d020d7641843840ecfb197b4f4ac669f5e3a6132886b.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 103.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAIAAADJt1n/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAC7UlEQVQ4y22TyY7cNhRF6xMyZ5NOqaUqqTSrJFIiqYF8nDS0t/mEBEbQi8DIIn8TO3AM7/KLgUp2V3dSwl0JOLj33fe4w8W5+OlN/Mc/0Zv3h98+fPX6r+8fP3z36/uvX7/75vHjt48fv/zl7Rc//19/Fr//vfOPAaZA+dh3Q98LxjprJ60tI6wdrNBLVeIsK/P8hbK8zAq82ztOy/ryXDHKeMu6lte4ybIijtMoWpUkeZYVq9Kr0iQnDd35ftAQtnfu8yxjPQGtOefnskQI47omhJzPped5rusdDsfn8rzDLghOlLaOcx9FSYRwRWoQUgiQUiqlp2kyxiqpu64LTqfD4Xg8+pt8P9glSdq2veM4cZymdV0zIjgILjgHzrkxVmvDuciz/Dm56eq8wqSpWypBSaUBQAgY7WiNNdoQQk+n0PeD/8KEfIqdYIxpw7kYhgFAci6UVIIDACitGWuD4CVcVahp6JMz6ZhSBkBKkFqbVw+vpmmxxk7jLEFihH3/GRyGESFsgz87bzOLLbbSWilNCA2C043Yn2feYhPOYRg4COACrB2V0m3bRVHs+8GmK+w4boXq+3v3Eps0l8JAgJJaKTNP8zQtUkpCaJ4Xrut53uGp9t3d3f58Rq7rXQpDmDbbqgQHPghrRq3Ws0EVRtV6NwihJE03/gl24yhNm3pzVuugWim1LA/WjMbaaZqXebbj1DQkiuIbzmldY0q23QiQAHK0ozZ26/+SwmRp5nmHm7ExJg0fhBCi6/qBc6ONUkbrFS7LKo7jIDhdC7vGjtOUknXPUhtjpVRam2VerLXz/LD+AVlV6Cb8yRmR+nLV620LAdZYpTWA3BaGEIqi+GbbaUaI0Ipz0fX99rbmaZmmWWstQTUNrRAOw/AlXFSus4/DKGswHbq+H/p+UFKqS/JL9UYIwLjGuC7L6nLh67e7++HHArF9Rv1ze2r6dhiU0lJqQhjGDaMdpS2lbdcNjHVVhbOsiKI0DJMwTP4FLyALHD1oAZ4AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/cc0786dfa43710d1bc63d9bed3eb6532/8ac56/ebc74bba8a3bfc6aed784ae15763d289befa7fa007964a807b793e7e7fa3275f.webp 240w,
/static/cc0786dfa43710d1bc63d9bed3eb6532/d3be9/ebc74bba8a3bfc6aed784ae15763d289befa7fa007964a807b793e7e7fa3275f.webp 480w,
/static/cc0786dfa43710d1bc63d9bed3eb6532/b0a15/ebc74bba8a3bfc6aed784ae15763d289befa7fa007964a807b793e7e7fa3275f.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/cc0786dfa43710d1bc63d9bed3eb6532/8ff5a/ebc74bba8a3bfc6aed784ae15763d289befa7fa007964a807b793e7e7fa3275f.png 240w,
/static/cc0786dfa43710d1bc63d9bed3eb6532/e85cb/ebc74bba8a3bfc6aed784ae15763d289befa7fa007964a807b793e7e7fa3275f.png 480w,
/static/cc0786dfa43710d1bc63d9bed3eb6532/0b533/ebc74bba8a3bfc6aed784ae15763d289befa7fa007964a807b793e7e7fa3275f.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/cc0786dfa43710d1bc63d9bed3eb6532/0b533/ebc74bba8a3bfc6aed784ae15763d289befa7fa007964a807b793e7e7fa3275f.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;This is the current list of migrations generated so far for a project I am involved. It&apos;s a product that is currently in Beta, and we already have deployed it in a testing environment, where we and our beta testers are performing tests.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;530&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./7ed34168df6f0158b8917071b3bf44876c111817080adb4de3610515cdd2d4d7.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 105.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAIAAADJt1n/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAD1ElEQVQ4yyWS627bNhiGdQEDht1Fiu3HUGxJu6QHFNi/YVfW3cbQbUCRIofVTWLHTpyjZUr8eJZIUZJPjd0sluQ2bdJkoE2QlACS+N7veV/vj5cvv/n2u99+f7i6/OOvTx49/Gl5ZWXl+eOfv19eXXr6Ymnt+dLa8wdP3P7DyuqLtZVnvyw/frSy9PTFg9VnHkLd89O2f35IghOGzwRDgnYl9RntMhYwFlCKCJlP8Dl0mJs+EEQo8g72d/559effr/7aWH+98+7tYat+2GoctQ+OD5vtVqPdahw29+o7W+3WbtA5Quft7nk77B4ftXab9bfewf67ja3d9Y29zX+bbzbrr9/sbL5t1fZO9pr+SYe3zygGGSkpBCdA3IdzwXmWWgKhd3SwKwXjjFFCOOMEAw5DKUQxnd7Px2w2E0JQSn0fUUqA0DDEw8GAktA7PqxLwaWQSiljdBzHOo7TNC2K4vbm5vb2piwLHceJMZGKrE2MMTZJLt6PlGBOthLcaK2kdJoYj5TiTge5uLi4u7sri2L+UgEm7o5TzkbDYaSEd9puUABGWRiEgKHb8TEGjEPOxWAwmFVVVZYEgFKKUDBvjlJC+r1eGPhes16LI5VnmY4jm1ijdZIk/V7v8/X13d3Xr19vZ1WZWpva1GidZam1Nk3tZHyRmNg7aLyjgBllBADmtFAXJcZcXl7efLm5v78vy0IwRgD7nS4hAISEYdjv5Y72wX6NMyKFa1gpJTiXgltrJ5PJdHpVlUVRXOk40nEsuNALolqPRgPOwGvsbkdSGG0iN+JIRZFyS0rJGEutrcpy3k4smDDaPY6jaHzx3ujIVaaAAxSgbpcA+J1OgIIgCCmhgHGW5lVZUucv+B2fknlzGPd7eYh8r9WoRUomxiRGm7nRNjFaa2vtp08f7+/vqrLMUptnqY51nmUO3QKYjpxszgilFDAwygkAQgEAHvT7k/Hk8+cvZVkoITljqIucBHfTnTKCXWVOyYI258LtjHHGlZKj0agsy7IopBBKSkqoihRjXEk1HPQJBF59ZytScjQc5lkaR47qIoyDQf/yw4fpdFoWRe7sTZRU1iax1sbo8cLnxu42wSFnnBEgGAKEwjDEYUgAUmvH4/GHyVgIAQDnZx2McYhxEAS9PAtRx2s2apGUNrEOlXUJs9b99/JeVVWLhCUmyfNMa5PPI5Zl6WT8XsfKq22vMwpGG8aYiw8QwDCPP7v672qRMCkFowQhxJhjCwCDQZ9T8ILuaWqTXp67miZJtO73+x9nVVUW1/N4z2ZVnmdZlhpjsizNUmfWZDK2Rv8Pa8QJpYXdbTwAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/1352ec092308d11126e79ded69a8b54e/8ac56/fe5240b6542914a6a7dfe0475ba32f3b011f76c7995e69a8ba292116a750c699.webp 240w,
/static/1352ec092308d11126e79ded69a8b54e/d3be9/fe5240b6542914a6a7dfe0475ba32f3b011f76c7995e69a8ba292116a750c699.webp 480w,
/static/1352ec092308d11126e79ded69a8b54e/b0a15/fe5240b6542914a6a7dfe0475ba32f3b011f76c7995e69a8ba292116a750c699.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/1352ec092308d11126e79ded69a8b54e/8ff5a/fe5240b6542914a6a7dfe0475ba32f3b011f76c7995e69a8ba292116a750c699.png 240w,
/static/1352ec092308d11126e79ded69a8b54e/e85cb/fe5240b6542914a6a7dfe0475ba32f3b011f76c7995e69a8ba292116a750c699.png 480w,
/static/1352ec092308d11126e79ded69a8b54e/0b533/fe5240b6542914a6a7dfe0475ba32f3b011f76c7995e69a8ba292116a750c699.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/1352ec092308d11126e79ded69a8b54e/0b533/fe5240b6542914a6a7dfe0475ba32f3b011f76c7995e69a8ba292116a750c699.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I don&apos;t want to go into the details of this table, and particularly, how it&apos;s used internally by EF, but assume that it is the table that EF uses to know what migrations need to be applied when exists some changes in model.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;We are currently at the point where we need to release and prepare a fresh and clean installation in a new environment, but I don&apos;t want to have this myriad of migrations, because, in fact, this is my first release&lt;/strong&gt; and I don&apos;t care about the migrations, and how I got this current model, at least in terms of migrations registration. Of course that I do care about knowing how we got the current model version, and for that we have everything registered in source control.&lt;/p&gt;
&lt;p&gt;What I really want is:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;&lt;strong&gt;to exclude all current migrations from the VS project&amp;nbsp;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;to generate again an initial create migration with the current model definition&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;to have, in my new installation, just one entry in table __MigrationHistory&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;do not compromise an ugrade to the current test environment&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1 - Exclude all migrations&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is a no brain step. &lt;strong&gt;Exclude all the migrations from the VS project&lt;/strong&gt;. You just need to have some caution if you have some custom code in migrations, such as for example custom indexes creation. In this case, you need to identify these extra actions which will be used again later.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2 - Generate an Initial Create Migration with all the model definition&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now that we have no migrations in our VS project, we can generate a new migration with all the model definition. First, &lt;strong&gt;we need to create an empty database and change the connectionstring in the web.config to use this new empty database.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Then, in Package Manager Console, we &lt;strong&gt;generate a new migration called InitialCreate&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;167&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./33d27fca240b1728b28fb6cfe0c8a42264cc032b44685cf69b5a9b0e72c1b77a.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 33.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAAsTAAALEwEAmpwYAAABT0lEQVQY022K3UvCUADFL6VYyLxG6Zzsul3vdu9Qm1oEqUQUfqH5kayH3hUZ5WNQ74K6oXNK+u/GWIQPwY8f5xwOwLkrEDgBgRAInoLjUDAMlYyOCIMxAdMMyehxIRk7P5NULUUYj+Sjk7D39NFfP2hnTDpmvDbk68NEYyT3JlLnTepOpO672DLFtonaptjyjNqm0BwnGiO+7p3Bw2O3Wn2u14xSpXlbbt7dP5XKjZxeYdoNUa9lnMfpAiYFTPKKUlTUoiTrEtbltC5jHWy3grNO7vfJ3U50Xf57l3QcwXXjsxlnLSK2BS0LTqfQWkDbhosF9BbbG+dzCNx1dOVwmw23XP5i29xqGXGc6HoNXTe63cLPr4teL2UYqN9HLwYyDDQYeAbZ7KWisEMI8QNNpykhjBCKMUNIE0XNtx8Q0gAhqqrSPxSFHlZ/oZQy9g8/epRdni0/yyQAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/75eb8b006c35fb400c0d149748477642/8ac56/f4717680a4d93917032572b4756b2285c413bfa588adce85b198ff594c1d9f7c.webp 240w,
/static/75eb8b006c35fb400c0d149748477642/d3be9/f4717680a4d93917032572b4756b2285c413bfa588adce85b198ff594c1d9f7c.webp 480w,
/static/75eb8b006c35fb400c0d149748477642/b0a15/f4717680a4d93917032572b4756b2285c413bfa588adce85b198ff594c1d9f7c.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/75eb8b006c35fb400c0d149748477642/8ff5a/f4717680a4d93917032572b4756b2285c413bfa588adce85b198ff594c1d9f7c.png 240w,
/static/75eb8b006c35fb400c0d149748477642/e85cb/f4717680a4d93917032572b4756b2285c413bfa588adce85b198ff594c1d9f7c.png 480w,
/static/75eb8b006c35fb400c0d149748477642/0b533/f4717680a4d93917032572b4756b2285c413bfa588adce85b198ff594c1d9f7c.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/75eb8b006c35fb400c0d149748477642/0b533/f4717680a4d93917032572b4756b2285c413bfa588adce85b198ff594c1d9f7c.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;We should &lt;strong&gt;check that the migration generated has all the model definition&lt;/strong&gt;. You can add to it extra indexes that eventually you had add previously.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;281&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./58391c80914eb86b0910c81d69fa1e1db96fa550b21853c3fbffed93f4665269.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 56.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABYElEQVQoz4WPi47bIBBFMQ8zAwwmfmTttH5AbGeTKunu//9c5URt09WuenQ1Eogj5jKhARB5xkhzrTjeoxXXkjtUZLZYVLkSTUCyORnFecYeCI2AqJUsnbYq8yCdFnSfhVU7bwIBGaWkqAMULvc2F39lMNZaxpiSsnY5yAxlZvMtLudlVRtj2FcI4wCAMSbFBhGVZVVXtSP68DJ7mr9l5zXoP0el8v3Lbpiab99D2ZiixFAhefzqZ4InebuR0hpwWrD/Ipx/rP0M5xwRndsatW273790Xec9eRCEed00bdcROSbsP2vfa229PNHp9JpSWpd1Wdai8OM4zsd0OZ/TcW48Tg0xYemjfAcQ03G+nM/LsoRQeE9xiut6muc5xriz+hDgIcMnMmA/jD8ul5RSCOHQHfq+TynFGKcY60D9PjAZKvhMNmjmeXl/+3mc53EYbtdbTGma4vV2jUO/Dm2cxl804RtopMNspgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/1b6c01082677401867c55e569b612bbb/8ac56/3cc12cd8beb0c2a2bf57917cd1943988d146554913001dc697c19a7d91fc0eeb.webp 240w,
/static/1b6c01082677401867c55e569b612bbb/d3be9/3cc12cd8beb0c2a2bf57917cd1943988d146554913001dc697c19a7d91fc0eeb.webp 480w,
/static/1b6c01082677401867c55e569b612bbb/b0a15/3cc12cd8beb0c2a2bf57917cd1943988d146554913001dc697c19a7d91fc0eeb.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/1b6c01082677401867c55e569b612bbb/8ff5a/3cc12cd8beb0c2a2bf57917cd1943988d146554913001dc697c19a7d91fc0eeb.png 240w,
/static/1b6c01082677401867c55e569b612bbb/e85cb/3cc12cd8beb0c2a2bf57917cd1943988d146554913001dc697c19a7d91fc0eeb.png 480w,
/static/1b6c01082677401867c55e569b612bbb/0b533/3cc12cd8beb0c2a2bf57917cd1943988d146554913001dc697c19a7d91fc0eeb.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/1b6c01082677401867c55e569b612bbb/0b533/3cc12cd8beb0c2a2bf57917cd1943988d146554913001dc697c19a7d91fc0eeb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3 - Just one entry in the __MigrationHistory&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s try to &lt;strong&gt;update the database running the Update-Database in PM, against the empty database&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;367&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./b20e1df8f7ce29ae6e56bf31a905d5a0837e52c633f248fa534da1e83593d8dc.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 73.33333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAACNklEQVQoz21S227UMBTMD1BekBAIqWWJnW0uvh3b8a6d7DXZZC+lZbelb0jAI++sKsEv8MvISRFtVWlkHUvnzJwZO3A//px9/nV6uAtvf7/b372+PL65Or79dHx1eXeyO77cHU+2x5Odx4vtzycIzGpfHb7Orr5U19/mh++i2rPFXre3urlR9UE3N3p1repr3dwk5TZ9jGCslTN6WrhiZOaFK4yWnM4Ka0AkET5HH/DgDL3vcfq/HngEjAkhgHPBGCeUcy7SjAghkySLk3Q4PEcoiqIhxsMoGiKEEY4wHiIUhSEKJpNJWZR27ExujBnNZ3MhoHDlpJxora11zpVlVxfltFouR+PRZDq11m22F4G1zjpnRmNrXZ7nSunRfe25iqIsirIsS2utMca3OtcrZRkNdhcX2+1mvdk0dTOfLRbL5cfLq7ZdW2sXy6pt1nVdte26rld1tWpX7apumnbNGQ/DMGCMM8YBZH8KAUKAlEpJJUESQpMkxd5nhDDGKPK2ERoMPnjPCGFCiABgjHfJeS7OAUByLuIk7bqfwnMhHCAUEUJ1bgCkBAVCUso4F5z7V6CU9bIYR/dpP4AfzjLi91Ra65xSxhiXUgkhlNRCQO/Lv1mIwhA9MwwgldIg/apSql62D6IjgjhJ0ozgx+L/lEFKqQBACNEVsoe/KgWgKKFxnPRWn1HuNlfUO+7ylp4wy0iSpnGchOF9wk+HCaF5F5hSWintv2hntXfehe//LGM8juPwwfBfFre2YP1kYT8AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/d8076eb1a867639fe15216bbc0417420/8ac56/c3a1e596d8dc4684405eeadfbf1978ec22c681b795479bfddd9186bb1d6d48c0.webp 240w,
/static/d8076eb1a867639fe15216bbc0417420/d3be9/c3a1e596d8dc4684405eeadfbf1978ec22c681b795479bfddd9186bb1d6d48c0.webp 480w,
/static/d8076eb1a867639fe15216bbc0417420/b0a15/c3a1e596d8dc4684405eeadfbf1978ec22c681b795479bfddd9186bb1d6d48c0.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/d8076eb1a867639fe15216bbc0417420/8ff5a/c3a1e596d8dc4684405eeadfbf1978ec22c681b795479bfddd9186bb1d6d48c0.png 240w,
/static/d8076eb1a867639fe15216bbc0417420/e85cb/c3a1e596d8dc4684405eeadfbf1978ec22c681b795479bfddd9186bb1d6d48c0.png 480w,
/static/d8076eb1a867639fe15216bbc0417420/0b533/c3a1e596d8dc4684405eeadfbf1978ec22c681b795479bfddd9186bb1d6d48c0.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/d8076eb1a867639fe15216bbc0417420/0b533/c3a1e596d8dc4684405eeadfbf1978ec22c681b795479bfddd9186bb1d6d48c0.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Then &lt;strong&gt;check the __MigrationHistory table&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;148&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./b7289d0dc167d3771cc9289a764f217a4cfd8ddb24bef1a38eee2a7e12323e03.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 29.583333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAAsTAAALEwEAmpwYAAABVUlEQVQY00XHy1KCYAAFYN7HMf0R/wFE1PYttGlhNS3ctugVWvYmzeRYmWbIRUXNK4iggChecJqp3kGgURd9c+bMOYjcfbvK4Nnz2MP92U0a3l3HbrPEZYbIXRC5NIzDQBALgiQRpiGgoiAOQwk8REawBB6FIaTdHZIkHTgB6UwKougpGaVhBIRRFKBJPELhWJgg0FQSpWlAUSAWQ2k6TJJYnIY4jjTElm3pmjI0tLE9n85n0/Vq5qzM7cZyNnNnbTlLw1lMHVs/ZmsbX2vLsQ1naSIcy7wXn57zj6WX/EepINYYqSdKPbFZZyqlQo0ry4PWaNiW+0150BpLn50mV6289jv1Ya+BiHW+JQrlUlHgWYHnBJ7jOZatMiNJmmiqqir6RNMn2sKaGfrENI3V0h6PJFVRptoY+f759X3f8zzf913X3bnu7mD/DzzPc1332Pvh//sD1nrqLzTRhYsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/077e93319b598365c233888ed548e183/8ac56/e896d3268320c46eadbcb9c25552d7937647047fdc1757f42c1ede81a682ae16.webp 240w,
/static/077e93319b598365c233888ed548e183/d3be9/e896d3268320c46eadbcb9c25552d7937647047fdc1757f42c1ede81a682ae16.webp 480w,
/static/077e93319b598365c233888ed548e183/b0a15/e896d3268320c46eadbcb9c25552d7937647047fdc1757f42c1ede81a682ae16.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/077e93319b598365c233888ed548e183/8ff5a/e896d3268320c46eadbcb9c25552d7937647047fdc1757f42c1ede81a682ae16.png 240w,
/static/077e93319b598365c233888ed548e183/e85cb/e896d3268320c46eadbcb9c25552d7937647047fdc1757f42c1ede81a682ae16.png 480w,
/static/077e93319b598365c233888ed548e183/0b533/e896d3268320c46eadbcb9c25552d7937647047fdc1757f42c1ede81a682ae16.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/077e93319b598365c233888ed548e183/0b533/e896d3268320c46eadbcb9c25552d7937647047fdc1757f42c1ede81a682ae16.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;It&apos;s ok. &lt;strong&gt;Just One entry in __MigrationHistory as we wish&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4 - Do not compromise an upgrade to the current test environment&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now, the interesting part. What happens if you try to &lt;strong&gt;update the database against the database that we are using so far, in which all migrations are registered&lt;/strong&gt; in? Let&apos;s change Web.config to reuse again the correct connection string and try to upgrade database to see what happens&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;282&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./8975664e83cf0aabb1501485a566d12292673a0a642150d92def2a7edb560c83.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 56.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABrklEQVQoz52PXYvTQBSG81PcJjOTJk1mkvlIMp9NJpmm6YLo+n2xd1svlKrg6t+XtrCICIKHh8O5eJ8Db9TIvnlzcvc/urcnevdpe/+TvPr6bH6Il2O8P97MD6v9kX543Nx9qd99x6+/ZS8+1+8f85en5PAxssaNTntjbuedN3o/Ds/3Yd4agQvbisnq0cg6T8sUCrzhZV5lSOANyVAOVpFSlomGi05pq7RtOtlKbVwvWklqZlxvXJ9tMK5oAtObGMQJOm+AEphGRruiKCmlGBNKGS4xITUmJMvysizJ5UBonabrJAHJeQAAMEnAahVHzvb94EMIWqlhO9Z13XUyTGEYPKW070c/jJxzqZSUWisjpd46x7jw4y5SylDGpZQYEyFaRllV1ZxxjCtcYsZ427RCNBWpmqaTnWqaVvCmxJhULKprbqyz1vkx+GE0xkzTZK0Rog272fXD6L3WGgAIAIQQXQEAxjE4y4fbw7wsU5imKfhhmsJuWRYp1XqdZVmeZXmarq/ypTa41gYARoTQ0fs8LyBECCGIUnQBQvQUfUr/QVQU+PeX/xT+Iv8fvwCUPYQAOlS8fgAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/c5df83a310c0d7ed0914bcfe326fc6df/8ac56/ef4e934da692d9a2d59854149795b9571516cd085b1027ee3d28b920f1d9ffeb.webp 240w,
/static/c5df83a310c0d7ed0914bcfe326fc6df/d3be9/ef4e934da692d9a2d59854149795b9571516cd085b1027ee3d28b920f1d9ffeb.webp 480w,
/static/c5df83a310c0d7ed0914bcfe326fc6df/b0a15/ef4e934da692d9a2d59854149795b9571516cd085b1027ee3d28b920f1d9ffeb.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/c5df83a310c0d7ed0914bcfe326fc6df/8ff5a/ef4e934da692d9a2d59854149795b9571516cd085b1027ee3d28b920f1d9ffeb.png 240w,
/static/c5df83a310c0d7ed0914bcfe326fc6df/e85cb/ef4e934da692d9a2d59854149795b9571516cd085b1027ee3d28b920f1d9ffeb.png 480w,
/static/c5df83a310c0d7ed0914bcfe326fc6df/0b533/ef4e934da692d9a2d59854149795b9571516cd085b1027ee3d28b920f1d9ffeb.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/c5df83a310c0d7ed0914bcfe326fc6df/0b533/ef4e934da692d9a2d59854149795b9571516cd085b1027ee3d28b920f1d9ffeb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Ok. It seems that there is no pending changes, which is true, since I didn&apos;t any change to my model. But I want to &lt;strong&gt;be sure that the changes from now on are applied correctly&lt;/strong&gt;. So, let&apos;s do a minor change to check how the upgrade behaves.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;222&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./4800329601e1a535c8bd65dacbdec82b37b764c4bb34f17da8087139dcb86385.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 44.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAAsTAAALEwEAmpwYAAABbElEQVQoz5XNy3KbMACFYYHuEhKgC7oVgQ2OXbt2MulMFun7v1en8XTVVf/9OR9ALndTxgj1HK2Gagajwr6nS5I1iEPWx6xq6Pai96IJbgFomqYBz7CNwnrUtlwITlpFWoYaBkEnhJRCMUQx7CgkBIN/wzby0WLYAgAkY/fVbKk7J7kWP+fpXvUadfWqFucGFkaWwpRTRujrC42eDwZDCAAQlD5WcwjiXPpzYKclv79ettmekp4df6zDeUtmHIyxsIVfskvc/JU5fxzt96puL+vnx9uvz49Sl7ql66O+3L7Na5ic/ePBBuKnbCM3DsGWAqBhUyUKtN2tOHlZB5b7/hjCnsueSlDdQZPAySyx77r2ORbGjb0+CLlYc892s/1m+4tT98Py83p9PZ1+HLcthlsyRzdeprHGOEsZlALIBGEcxThLGRnNnHiKPcWJoaK60vdF66RUFDwLOlESGfGcO4Q4QoDERfjACAH/328fYR/2KiGl1AAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/65f19077062af78aa25d05e9c0003668/8ac56/6771d16bfa1542b51b3fc7fb57d4a833d0700df08931212f20dd60c97317ef07.webp 240w,
/static/65f19077062af78aa25d05e9c0003668/d3be9/6771d16bfa1542b51b3fc7fb57d4a833d0700df08931212f20dd60c97317ef07.webp 480w,
/static/65f19077062af78aa25d05e9c0003668/b0a15/6771d16bfa1542b51b3fc7fb57d4a833d0700df08931212f20dd60c97317ef07.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/65f19077062af78aa25d05e9c0003668/8ff5a/6771d16bfa1542b51b3fc7fb57d4a833d0700df08931212f20dd60c97317ef07.png 240w,
/static/65f19077062af78aa25d05e9c0003668/e85cb/6771d16bfa1542b51b3fc7fb57d4a833d0700df08931212f20dd60c97317ef07.png 480w,
/static/65f19077062af78aa25d05e9c0003668/0b533/6771d16bfa1542b51b3fc7fb57d4a833d0700df08931212f20dd60c97317ef07.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/65f19077062af78aa25d05e9c0003668/0b533/6771d16bfa1542b51b3fc7fb57d4a833d0700df08931212f20dd60c97317ef07.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Basically we are adding a new column &apos;NewProperty&apos; to an existing table. Let&apos;s create the migration&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;171&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./0c3f01ad0930bd253ccc5a8d3029fd9838b408c2e2c0d84b9b7d8fb70ae814ce.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 34.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAAsTAAALEwEAmpwYAAABeUlEQVQY013H3UrCYADG8UFsnpqK8303kdicUkZfmKaWpuXHNIMiaNPILXci0S0sZpGuBRGZ9nEDdSa45VLBSwsrIoIff54HCdTa82cvs7VO4PSZkDr2SstxfO+otJxCCxfbrmoHVB/xkzaQnpziw1+4+IBsbmWT22x8M53OFROp7HIwGo1vhSPxtVgykcoFw+uhSHwlFFuLJecXVwMLwb+Q7VQyz2aLO2yxUGAz6Z0Cy+YyuwX2YH8vz2YTG7GVpQWGpmhqxuelfAzl81L+r3ppClEUqKq4fI5rN0DTQFN1XV3ZGw2npgGljqvXUNNclxe2RtOuKNP1uk1VbfK5TZan726tyNsrphtTuo4Oh+h4jH6YqK5jgwFqmqhhoKZpMd4tvR42Gv0YDrF+H+t2LddNK1KrBQTBLQhAFKEownIZlMpAEMHRESiVAMfBigB5HnDc5PI8kCRYLoHDQ4JhGISmFz2eOYLwfyPJid/xb5OkH8JJ3W4/TTOfq0F8lyd6euIAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/546989c2a94f3b9e91ac369932c4f0af/8ac56/af0fd15e667e1f842e7a379c40419f577015a6f0b7e03c76cdcc73cb65a6c586.webp 240w,
/static/546989c2a94f3b9e91ac369932c4f0af/d3be9/af0fd15e667e1f842e7a379c40419f577015a6f0b7e03c76cdcc73cb65a6c586.webp 480w,
/static/546989c2a94f3b9e91ac369932c4f0af/b0a15/af0fd15e667e1f842e7a379c40419f577015a6f0b7e03c76cdcc73cb65a6c586.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/546989c2a94f3b9e91ac369932c4f0af/8ff5a/af0fd15e667e1f842e7a379c40419f577015a6f0b7e03c76cdcc73cb65a6c586.png 240w,
/static/546989c2a94f3b9e91ac369932c4f0af/e85cb/af0fd15e667e1f842e7a379c40419f577015a6f0b7e03c76cdcc73cb65a6c586.png 480w,
/static/546989c2a94f3b9e91ac369932c4f0af/0b533/af0fd15e667e1f842e7a379c40419f577015a6f0b7e03c76cdcc73cb65a6c586.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/546989c2a94f3b9e91ac369932c4f0af/0b533/af0fd15e667e1f842e7a379c40419f577015a6f0b7e03c76cdcc73cb65a6c586.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;And check the generated migration&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;173&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./220eedf6297d2e05dd789391c970e66d21ae4639fb13a3573202f322cf27fb89.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 34.583333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA3UlEQVQY042Q60rFQAyEd3PPbpu99NBWUfD9n1J6qqDgD4cQJmE+CEnh3A2bU3NaDbfQ972+bD7DZrOPcz1HEYKUUsrpVr6VUmLmcA6FSikkrwKP0Yr7HYacAb6hP2Uq2xxvry/HvrUu81Fj+NLkLjFemsbQJcRMzWzOeRxHLeWCEVFE3N1MmYEFRYkF6fKAmJ8GmQER7rCaEeIFR+FVoVBaOFfOs7UxZvqnWLj3fp7nfuzRLa4jLYatXds0L1JX6ds11uq/SFVFQkRkZiICzHfhV4cM18+QnnuAn/An4z0KhiAOZ9YAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/51d8dde462b537d2458a0497f5c8420c/8ac56/77052debfd887286b7d86e2f854dd6dc94c8416b9fdc4afaa3f5a4742081aa6b.webp 240w,
/static/51d8dde462b537d2458a0497f5c8420c/d3be9/77052debfd887286b7d86e2f854dd6dc94c8416b9fdc4afaa3f5a4742081aa6b.webp 480w,
/static/51d8dde462b537d2458a0497f5c8420c/b0a15/77052debfd887286b7d86e2f854dd6dc94c8416b9fdc4afaa3f5a4742081aa6b.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/51d8dde462b537d2458a0497f5c8420c/8ff5a/77052debfd887286b7d86e2f854dd6dc94c8416b9fdc4afaa3f5a4742081aa6b.png 240w,
/static/51d8dde462b537d2458a0497f5c8420c/e85cb/77052debfd887286b7d86e2f854dd6dc94c8416b9fdc4afaa3f5a4742081aa6b.png 480w,
/static/51d8dde462b537d2458a0497f5c8420c/0b533/77052debfd887286b7d86e2f854dd6dc94c8416b9fdc4afaa3f5a4742081aa6b.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/51d8dde462b537d2458a0497f5c8420c/0b533/77052debfd887286b7d86e2f854dd6dc94c8416b9fdc4afaa3f5a4742081aa6b.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;So far so good. Now let&apos;s check what is the result to upgrade the database, running the Upgrade-Database command, but now I will use the&lt;strong&gt; -Script option to generate the script instead of running the upgrade&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;150&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./be10fbf97415326a6a65edb00429e94d1aef787ecb81b4fc6f84453f21b1f313.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 30%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAAsTAAALEwEAmpwYAAABAklEQVQY033LT0vDMAAF8H4JcSKyQ/6sbt0kSdssadLSpKlbul10E3TowZMnv8EmSodHv7KUnkQUfpf3eC+It6/05St6+rh6/oSPx5Ob/WBzOL3dn9+9D3dt56Ed7o4X9+1g83a2/SHIMuVs5Vxd2WpxvVSZZizRuuCpIIQxllDCKI0JYeNxNJlMe1E0m0azIM8L771vVlVV++XC1bVvmvVqrZUWUlbWFXnhnLPGdgPvy9JYY5M4gQAGpTGlMSnnnM/TNCWUKaU5nxNChZRSZEJIrXMpsqIolVJCZGnCMR4hhANCaBheAoAg/BMAEEKEEIYQ9w1CuDtjHAIA+/Cv0e/yGzXuTh0WzAhxAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/5041f9c1ba2e4ec156afec8b0f528c2c/8ac56/7e9e0b2fde9e04e7cf30b8c9f65da49ef78dd59aa99db974237edd0ba89c93c7.webp 240w,
/static/5041f9c1ba2e4ec156afec8b0f528c2c/d3be9/7e9e0b2fde9e04e7cf30b8c9f65da49ef78dd59aa99db974237edd0ba89c93c7.webp 480w,
/static/5041f9c1ba2e4ec156afec8b0f528c2c/b0a15/7e9e0b2fde9e04e7cf30b8c9f65da49ef78dd59aa99db974237edd0ba89c93c7.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/5041f9c1ba2e4ec156afec8b0f528c2c/8ff5a/7e9e0b2fde9e04e7cf30b8c9f65da49ef78dd59aa99db974237edd0ba89c93c7.png 240w,
/static/5041f9c1ba2e4ec156afec8b0f528c2c/e85cb/7e9e0b2fde9e04e7cf30b8c9f65da49ef78dd59aa99db974237edd0ba89c93c7.png 480w,
/static/5041f9c1ba2e4ec156afec8b0f528c2c/0b533/7e9e0b2fde9e04e7cf30b8c9f65da49ef78dd59aa99db974237edd0ba89c93c7.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/5041f9c1ba2e4ec156afec8b0f528c2c/0b533/7e9e0b2fde9e04e7cf30b8c9f65da49ef78dd59aa99db974237edd0ba89c93c7.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;And here is the script&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;73&quot; data-orig-width=&quot;500&quot; data-orig-src=&quot;./80fd62e5e91c8928a9980a898c55cc9b8af48f182e1e0b968da859e72959ac9b.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 14.583333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAIAAAAcOLh5AAAACXBIWXMAAAsTAAALEwEAmpwYAAAApUlEQVQI1x2LyQ6CMBQAe2sfVVAp62NJwyKiKArKaiAkJv7/Fxm8TWYyJIhPY9897mVZd1U/1cPcvJd2+gzL99X2t7qph/n67C9VWzZjXjTyWMj07MnUDhNCCEkEDfRtZJmZ7+W+lyGmth27GFimNIwYMUOMHDtyHakboRCmIRAdIfR11lRVAWUDwBnjlHHGNgAKpcAYBwBK+R+U1a8VAFRV2+0PP3z7FAWzKRtCAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/f91babc7e0fd3f0e3775562e8604df97/8ac56/f5f17a51fd49555133952c249cd44f4c00f0a3825ea0ec87dd371301dd1fe5be.webp 240w,
/static/f91babc7e0fd3f0e3775562e8604df97/d3be9/f5f17a51fd49555133952c249cd44f4c00f0a3825ea0ec87dd371301dd1fe5be.webp 480w,
/static/f91babc7e0fd3f0e3775562e8604df97/b0a15/f5f17a51fd49555133952c249cd44f4c00f0a3825ea0ec87dd371301dd1fe5be.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/f91babc7e0fd3f0e3775562e8604df97/8ff5a/f5f17a51fd49555133952c249cd44f4c00f0a3825ea0ec87dd371301dd1fe5be.png 240w,
/static/f91babc7e0fd3f0e3775562e8604df97/e85cb/f5f17a51fd49555133952c249cd44f4c00f0a3825ea0ec87dd371301dd1fe5be.png 480w,
/static/f91babc7e0fd3f0e3775562e8604df97/0b533/f5f17a51fd49555133952c249cd44f4c00f0a3825ea0ec87dd371301dd1fe5be.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/f91babc7e0fd3f0e3775562e8604df97/0b533/f5f17a51fd49555133952c249cd44f4c00f0a3825ea0ec87dd371301dd1fe5be.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;Ok! The change is applied and the migration is registered. Well done!&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Just one more note: f&lt;strong&gt;rom this point you can&apos;t downgrade to any migration that was excluded from the project,&lt;/strong&gt; since the class is not in assembly anymore.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Let&apos;s recap&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;With this recipe you can reset migrations, allowing to have again an initial create migration which reflect the current model, which will be applied as a single migration in a clean installation, and at the same time, do not compromise upgrades on current deployed databases, where migrations are already registered.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[ASP.NET Identity 1.0: where the hell is the recover password feature?]]></title><description><![CDATA[ASP.NET Identity 1.0: where the hell is the recover password feature?]]></description><link>https://bfcamara.com/post/68977237610/aspnet-identity-10-where-the-hell-is-the</link><guid isPermaLink="false">https://bfcamara.com/post/68977237610/aspnet-identity-10-where-the-hell-is-the</guid><pubDate>Wed, 04 Dec 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Answer&lt;/strong&gt;: it&apos;s not available! Surprised!? Yes, I am very surprised!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;For many years we&apos;ve used the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/yh26yfzy(v=vs.98).aspx&quot; target=&quot;_blank&quot;&gt;ASP.NET Membership&lt;/a&gt; (or the SimpleMembership included in Webpages). Here are the features included out-of-the box in the membership system:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Authentication&lt;/li&gt;
&lt;li&gt;User Registration&lt;/li&gt;
&lt;li&gt;Roles Management&lt;/li&gt;
&lt;li&gt;Password Management&lt;/li&gt;
&lt;li&gt;Profile Management&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;With .Net 4.5.1 we have a new identity management system called ASP.NET Identity&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;. It&apos;s normal to compare the two systems, since they have the same main goal, which is to provide an identity management system.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I don&apos;t want to go with the details of this new system, and the reasons that took Microsoft to write it. You can check a great introduction &lt;a href=&quot;http://www.asp.net/identity/overview/getting-started/introduction-to-aspnet-identity&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If you decide to use this new system (as I did in my current project) to provide a basic user management system in you application, allowing a user to have an usual username/password credentials, &lt;strong&gt;you will be very surprised (and maybe disapointed) by the fact that the password recover feature it&apos;s not included out-of-the-box&lt;/strong&gt;. Of course we can implement it by hand, but the truth is that the ancient Membership system has included this feature, so &lt;strong&gt;it seems obvious to think and expect that this new one would also include it&lt;/strong&gt;. Wrong assumptions. So, if you check the UserManager class (the main class to manage identity features), you won&apos;t find any method to generate a reset password token to be used by the application user to be allowed to reset his password.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;After some research, &lt;strong&gt;it seems that the next version of the ASP.NET Identity, version 1.1, will include the recover password feature&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Since October 2013, Microsoft decided to make available the nightly builds of the ASP.NET Identity system. You can get this nightly builds using NuGet packages available on MyGet. Check &lt;a href=&quot;http://blogs.msdn.com/b/webdev/archive/2013/10/09/asp-net-identity-nuget-packages-for-the-nightly-builds-are-available-on-myget.aspx&quot; target=&quot;_blank&quot;&gt;the steps to follow in Visual Studio to configure the MyGet feed to pull in the nightly packages for ASP.NET Identity&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;171&quot; data-orig-width=&quot;500&quot;&gt;&lt;img alt=&quot;image&quot; src=&quot;https://66.media.tumblr.com/7df31af9e25d5065d82ba5732adae314/1c64b843cc41f48c-7c/s540x810/cca0b4996a5fdac5d7c5fce70664e7a523f476c9.png&quot; data-orig-height=&quot;171&quot; data-orig-width=&quot;500&quot;&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;What I will be showing next is based on the packages with version 1.1.0-alpha1-131108 that I grabbed in beginning of November, which is a pre-release version, and maybe the things have change since then.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Checking again the UserManager class, we now have some methods/properties/interfaces related to the password recover feature&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;csharp&quot;&gt;&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ITokenProvider&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Generate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;UserToken&lt;/span&gt; token&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token return-type class-name&quot;&gt;UserToken&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Validate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; token&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UserManager&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;TUser&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; TKey&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token type-list&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;IDisposable&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TUser&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;Microsoft&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;AspNet&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Identity&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;IUser
    &lt;span class=&quot;token keyword&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TKey&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;IEquatable
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;ITokenProvider&lt;/span&gt; PasswordResetTokens &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;Task&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;GetPasswordResetTokenAsync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;TKey&lt;/span&gt; userId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;Task&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ResetPasswordAsync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;TKey&lt;/span&gt; userId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; token&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; newPassword&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After taking some time with the disassembled code, what we need is quite simple. We need an implementation of ITokenProvider and set it as the PasswordResetTokens of the UserManager instance that we are using. I am doing this at the AccountController when initializing the UserManager. Here is an example&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;csharp&quot;&gt;&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;RoutePrefix&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;api/accounts&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AccountController&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token type-list&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;ApiControllerBase&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;

        &lt;span class=&quot;token function&quot;&gt;AccountController&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
        
        UserManager&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;PasswordResetTokens &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;DataProtectorTokenProvider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Startup&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ResetPasswordDataProtectorFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After this we can:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;use the method GetPasswordResetTokenAsync to get the token to send by email to the user, allowing him to reset the password&lt;/li&gt;
&lt;li&gt;validate the token using UserManager.PasswordresetTokens.Validate. In case of success we get an instance of the class UserToken which has the property UserId&lt;/li&gt;
&lt;li&gt;and finally, we can use the ResetPasswordAsync to reset the password&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So, basically we need an implementation of an ITokenProvider. We can use whatever we want to generate and validate the token, but we can&apos;t forget that we are in the middle of a security problem, so it&apos;s obvious that we have to be carefull with our implementation. In the example above, I am using the DataProtectorTokenProvider, available in the nuget Microsoft AspNet Identity Owin (the Owin implementation for ASP.NET identity. You can read more about Owin &lt;a href=&quot;http://www.asp.net/vnext/overview/owin-and-katana&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;). This is a generic implementation, which receives an instance of IDataProtector (defined in Microsoft.Owin.Security package)&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;csharp&quot;&gt;&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;Microsoft&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Owin&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Security&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;DataProtection&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Summary:&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;//     Service used to protect and unprotect data&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IDataProtector&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Summary:&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//     Called to protect user data.&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Parameters:&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//   userData:&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//     The original data that must be protected&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Returns:&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//     A different byte array that may be unprotected or altered only by software&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//     that has access to the an identical IDataProtection service.&lt;/span&gt;
        &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Protect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt; userData&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Summary:&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//     Called to unprotect user data&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Parameters:&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//   protectedData:&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//     The byte array returned by a call to Protect on an identical IDataProtection&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//     service.&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Returns:&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//     The byte array identical to the original userData passed to Protect.&lt;/span&gt;
        &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Unprotect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt; protectedData&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the examle above, I am using the intrastructure provided by Owin Security, which uses &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms995355.aspx&quot; target=&quot;_blank&quot;&gt;Windows Data Protection API&lt;/a&gt;. In the Owin Startup class, I define the data protector factory.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;csharp&quot;&gt;&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Startup&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Func&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;IDataProtector&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; ResetPasswordDataProtectorFactory&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ConfigureAuth&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;IAppBuilder&lt;/span&gt; app&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
    
        ResetPasswordDataProtectorFactory &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;CreateDataProtector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ResetPassword&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        
        &lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;

    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The app.CreateDataProtector uses a &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.security.cryptography.dpapidataprotector(v=vs.110).aspx&quot; target=&quot;_blank&quot;&gt;DpapiDataProtector&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;As a conclusion&lt;/strong&gt;, I was very surprised by the fact Microsoft decided to not include some features in ASP.NET Identity 1.0, such as password recovery. However, I am very glad to know in advance they are working on a new version 1.1 version, which apparently will include some of the features. For now, you can take the nightly builds to get the features (on your own risk) or implement it by hand.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[EF Code-Fist Migrations: How to set the Migrations folder]]></title><description><![CDATA[EF Code-Fist Migrations: How to set the Migrations folder]]></description><link>https://bfcamara.com/post/68462303638/ef-code-fist-migrations-how-to-set-the-migrations</link><guid isPermaLink="false">https://bfcamara.com/post/68462303638/ef-code-fist-migrations-how-to-set-the-migrations</guid><pubDate>Fri, 29 Nov 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In my &lt;a href=&quot;http://www.bfcamara.com/post/68169174771/entity-framework-database-first-vs-code-first&quot; target=&quot;_blank&quot;&gt;previous post&lt;/a&gt;, I confessed that I am currently using Code-First Migrations. If you are using Code-First migrations in your project, at some point in time &lt;strong&gt;you&apos;ve had to enable Migrations, running on the Package Manager (PM) Console the Enable-Migrations command&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt; Enable-Migrations &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Are you curious what this command does? Basically, it looks for the current project to find a DbContext, and &lt;strong&gt;generates a new class with the name Configuration, which is placed under the folder with the name Migrations in your root&lt;/strong&gt;, with the following code&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;Myapp&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Entity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Entity&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Migrations&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Linq&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Configuration&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token type-list&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;DbMigrationsConfiguration&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Configuration&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            AutomaticMigrationsEnabled &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Seed&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MyDbContext&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;//  This method will be called after migrating to the latest version.&lt;/span&gt;

            &lt;span class=&quot;token comment&quot;&gt;//  You can use the DbSet.AddOrUpdate() helper extension method &lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;//  to avoid creating duplicate seed data. E.g.&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;//    context.People.AddOrUpdate(&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;//      p =&gt; p.FullName,&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;//      new Person { FullName = &quot;Andrew Peters&quot; },&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;//      new Person { FullName = &quot;Brice Lambson&quot; },&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;//      new Person { FullName = &quot;Rowan Miller&quot; }&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;//    );&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Every time you want to add a new migration to your project, you have to run in PM console the Add-Migration command&lt;/p&gt;
&lt;p&gt;&lt;code&gt; Add-Migration AddColumnFirstName &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Here, AddColumnFistName it&apos;s the Migration name, and is just an example of a migration.&lt;/p&gt;
&lt;p&gt;After this command, you will have a new class 201311291316579_AddColumnFistName added to you project,&lt;strong&gt; which is placed under the folder with the name Migrations&lt;/strong&gt;. The name of the class is generated following the pattern &amp;lt;current_date_time&amp;gt;_&amp;lt;migration_name&amp;gt;.&lt;/p&gt;
&lt;p&gt;Below it&apos;s an example of the code generated for the migration&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Migrations&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Entity&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Migrations&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AddColumnFirstName&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token type-list&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;DbMigration&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Up&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;AddColumn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;dbo.Person&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;FirstName&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; c &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;gt&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        
        &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Down&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;DropColumn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;dbo.Person&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;FirstName&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;I don&apos;t like the location of the Migrations folder, which is being placed on the root of my project. Fortunately, you can set this location&lt;/strong&gt;. For example, I want to place my Migrations in the Data folder. To do this, when enabling migrations, I have to pass the MigrationsDirectory parameter to the Enable-Migrations command&lt;/p&gt;
&lt;p&gt;&lt;code&gt; Enable-Migrations -MigrationsDirectory Data\Migrations &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Besides of the new location of the Configuration class, there is one more difference in the generated code, in the Configuration constructor&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;csharp&quot;&gt;&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Configuration&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    AutomaticMigrationsEnabled &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    MigrationsDirectory &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;@&quot;Data\Migrations&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;From now on, every time I add a new migration, this will be added to the Data\Migrations folder. I like to have a clean root project folder&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Just one note: &lt;strong&gt;if you already have the Migrations folder in your root, and you wish to have a new location, I suggest to do it manually&lt;/strong&gt;, moving all the content of the current migrations folder to the new location. Do not foget to change the Configuration constructor as well, setting the MigrationsDirectory property with the new location.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Entity Framework: Database-First vs Code-First ]]></title><description><![CDATA[Entity Framework: Database-First vs Code-First]]></description><link>https://bfcamara.com/post/68169174771/entity-framework-database-first-vs-code-first</link><guid isPermaLink="false">https://bfcamara.com/post/68169174771/entity-framework-database-first-vs-code-first</guid><pubDate>Tue, 26 Nov 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;/p&gt;&lt;figure data-orig-height=&quot;76&quot; data-orig-width=&quot;200&quot;&gt;&lt;img src=&quot;https://66.media.tumblr.com/be344b102fc4d4c9420fb5431737169b/6c7d831abddfbb3a-61/s540x810/cf250efb1159c65b8443cf0448f050b8ab89646a.png&quot; data-orig-height=&quot;76&quot; data-orig-width=&quot;200&quot;&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;When working with &lt;strong&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/data/ef.aspx&quot; target=&quot;_blank&quot;&gt;Entity Framework (EF) &lt;/a&gt; &lt;a href=&quot;http://msdn.microsoft.com/en-us/data/ee712907#codefirst&quot; target=&quot;_blank&quot;&gt;Code-First&lt;/a&gt;, we define our entity model with classes and mappings in code, and the database is generated from the model&lt;/strong&gt;. When we change the model, we can evolve the database using &lt;a href=&quot;http://msdn.microsoft.com/en-us/data/jj591621&quot; target=&quot;_blank&quot;&gt;Migrations&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In the past, I&apos;ve used more the &lt;a href=&quot;http://msdn.microsoft.com/en-us/data/jj206878&quot; target=&quot;_blank&quot;&gt;Database- First approach&lt;/a&gt; (rather than the Code First). &lt;strong&gt;In the Database-First approach we start to model the database artifacts (tables, views, primary keys, foreign keys, etc.), and then we have the entity model generated from the database&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In the earlier versions, EF didn&apos;t support the &lt;strong&gt;Code-First approach&lt;/strong&gt;. Today, EF already supports this approach, and it has been improved in every new version. I decided to try this approach in my current project, and I would like to enumerate &lt;strong&gt;some advantages&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;all my application &quot;runnable&quot; artifacts are written in C#&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;no need to have a different database project&lt;/strong&gt; to accommodate the data artifacts&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;faster development workflow&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;makes me think in advance about &quot;the scripts&quot; that will run to upgrade/downgrade&lt;/strong&gt; my database to accomodate model changes. (every migration has an up and down path, where you can run sql migration statements)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;However, I also can enumerate &lt;strong&gt;some disadvantages&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;if your model is changing a lot, and you are working in a team with more than 3 elements, I believe that the team&amp;nbsp;will &lt;strong&gt;struggle easily with migrations (the migrations folder starts to grow and it get&apos;s out of control)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Some annotation attributes are missing&lt;/strong&gt;, such as the Index attribute for example. Currently, with EF 6, I cannot decorate my entity properties with an Index annotation. To create an index over a given property, I have to use the fluent API. I tend to prefer the attribute annotations approach.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;some lack of control how the database artifacts will be generated&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I believe that those more conventional/traditional developers will continue to use the well known Database-First approach. In my case, since I know both approaches, I will support my &lt;strong&gt;choice based on context/environment: team and project dimension, type of customer, etc. But now I can say that I&apos;m really confident and confortable with the Code-First approach, and certainly I will use it regularly&lt;/strong&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[The Scams of the Software Industry - CodeProject]]></description><link>https://bfcamara.com/post/68061175016/the-scams-of-the-software-industry-codeproject</link><guid isPermaLink="false">https://bfcamara.com/post/68061175016/the-scams-of-the-software-industry-codeproject</guid><pubDate>Mon, 25 Nov 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://www.codeproject.com/Articles/686808/The-Scams-of-the-Software-Industry&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://www.codeproject.com/Articles/686808/The-Scams-of-the-Software-Industry&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A great definition of what a true software architect is about:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;A true software architect can do most of the development by him or herself if required. In short, a true software architect is a hands-on developer with a vision.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;A true software architect spends about half of his / her time with the end users and stakeholders. In short, a true software architect is the glue between the end user and the developer(s).&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;A true software architect is a visionary person that can see ideas into reality. The visions that this architect has is aligned with the company&amp;rsquo;s goals and executions.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;A true software architect has sense of the business needs and can fit himself or herself in the business shoes.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;A true software architect can demo the software created before the users and stakeholders.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;A true software architect is willing to compromise when there are better solutions available that did not originally come from him or herself. In short, open to suggestions from other technical peers and willing to learn and try out new things.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;A true software architect is a master craftsman that has expertise for many technical areas and is versatile with different technologies.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;A true software architect is always exploring new ways and is willing to experiment&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;A true software architect is willing to mentor software developers&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;A true software architect has the best interest of the company in mind&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Ideally, a true software architect is many years experience in different industries because this will allow to discover commonalities across different domains and therefore create solutions that fit.&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;</content:encoded></item><item><title><![CDATA[NLog - How to include custom context variables in all your logs, that will flow across over async points]]></title><description><![CDATA[NLog - How to include custom context variables in all your logs, that will flow across over async points]]></description><link>https://bfcamara.com/post/67752957760/nlog-how-to-include-custom-context-variables-in</link><guid isPermaLink="false">https://bfcamara.com/post/67752957760/nlog-how-to-include-custom-context-variables-in</guid><pubDate>Fri, 22 Nov 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;b&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;78&quot; data-orig-width=&quot;352&quot; data-orig-src=&quot;./f0032c0313df8f4e90aa2d638c24bfb21b07990f4f99bb8364303bf4d2310678.png&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 352px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 22.083333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAyElEQVQY05XPMUoDYRRF4S9mZhJxA2qhEBXBRhAs3IFNQASjWKSIGtAVWAiioF0QxCaBNBYWbiFVthBtrKJFQLRSsP5lhkmvp7sP7nnvebuunX/1H8J35yAMWscD7GzXD+MC65jFBib8ldFt8+KndxfCSy88tU+fcVaMkwYe0UUHc7m0jAQlTCJGlOcoEw6v9o5Gl5sfn+2T99ebZirYjaNoC1Xs4x4LWMYiKvmCJUxjBWuYz4QhhPSEpEU5bU1l0+L4gRms+ge/d4YuL4hZBEcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/2a8ef430ccf2759bd7d8a7e7f905152d/8ac56/2f1a9498be5cb9500b94639d62a6166d897676d9c37b9e2992514676f561ad67.webp 240w,
/static/2a8ef430ccf2759bd7d8a7e7f905152d/edd59/2f1a9498be5cb9500b94639d62a6166d897676d9c37b9e2992514676f561ad67.webp 352w&quot; sizes=&quot;(max-width: 352px) 100vw, 352px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/2a8ef430ccf2759bd7d8a7e7f905152d/8ff5a/2f1a9498be5cb9500b94639d62a6166d897676d9c37b9e2992514676f561ad67.png 240w,
/static/2a8ef430ccf2759bd7d8a7e7f905152d/ba1c3/2f1a9498be5cb9500b94639d62a6166d897676d9c37b9e2992514676f561ad67.png 352w&quot; sizes=&quot;(max-width: 352px) 100vw, 352px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/2a8ef430ccf2759bd7d8a7e7f905152d/ba1c3/2f1a9498be5cb9500b94639d62a6166d897676d9c37b9e2992514676f561ad67.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;/b&gt;&lt;p&gt;&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update: The &lt;a href=&quot;https://github.com/NLog/NLog/wiki/MDLC-Layout-Renderer&quot;&gt;Mdlc &lt;/a&gt;feature shown in this post is now part of NLog.&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;strike&gt;&lt;b&gt;TL;DR:&lt;/b&gt;&lt;b&gt;If you need to have custom context variables that will flow across async points, you can use the &lt;a href=&quot;https://www.nuget.org/packages/NLog.Contrib/&quot;&gt;NLog.Contrib nuget package&lt;/a&gt; to have the MappedDiagnosticsLogicalContext class and the ${mdlc} layout render&lt;/b&gt;.&lt;/strike&gt;&lt;/p&gt;
&lt;p&gt;In my previous post, &lt;a href=&quot;http://www.bfcamara.com/post/66886024762/nlog-how-to-include-custom-context-variables-in-all&quot;&gt;NLog: How to include custom context variables in all your logs&lt;/a&gt;, I presented the &lt;b&gt;NLog.MappedDiagnosticsContext class and how can it be used to emit custom context variables to all of your logs. This class keeps a dictionary of strings in the thread local storage (TLS)&lt;/b&gt;. When I want to emit always a given context property, I have to add this line of code&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;NLog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MappedDiagnosticsContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;subscriptionid&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; SubscriptionId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In this case the SubscriptionId is the custom context property that I will be attaching to all my log statements. For example, if you are &lt;b&gt;in the context of Web API 2, you can set the property on a base controller&lt;/b&gt;, just like this&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;Task&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;HttpResponseMessage&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ExecuteAsync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;HttpControllerContext&lt;/span&gt; controllerContext&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CancellationToken&lt;/span&gt; cancellationToken&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; User&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Identity &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; User&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Identity&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;IsAuthenticated&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        NLog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MappedDiagnosticsContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;subscriptionid&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; CurrentSubscriptionId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
        NLog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MappedDiagnosticsContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;subscriptionid&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    Logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Begin Request {1} {0}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; controllerContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;RequestUri&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;PathAndQuery&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; controllerContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Method&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ExecuteAsync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;controllerContext&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cancellationToken&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We are overriding the ExecuteAsync method, which is the method that is invoked to start processing the request, and set the subscriptionid property for logging purposes. &lt;b&gt;From this point, all logs will include this new property&lt;/b&gt;. My NLog target is defined in configuration as this&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;target&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;xsi:&lt;/span&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;File&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;fileName&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;${basedir}/App_Data/Logs/App.log&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;${longdate} [T:${threadid}] [L:${uppercase:${level}}] [S:${mdc:item=subscriptionid}] ${message} ${exception:format=tostring}&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; 
    &lt;span class=&quot;token attr-name&quot;&gt;archiveFileName&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;${basedir}/App_Data/Logs/Archive/App_${shortdate}.log&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;archiveEvery&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;Day&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;maxArchiveFiles&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;30&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;                
    &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The magic happens using &lt;b&gt;the &lt;a href=&quot;https://github.com/nlog/NLog/wiki/Mdc-Layout-Renderer&quot;&gt;layout render ${mdc}&lt;/a&gt; ${mdc:item=subscriptionid}, which expands the property subscriptionid in the log statement&lt;/b&gt;. This is great, since to have the subscriptionid emitted in log files, I don&apos;t have to specify the subscriptionid property in all my Logger invocations. Layout renders are macros, and you can know more about layout renders &lt;a href=&quot;https://github.com/nlog/NLog/wiki/Layout-Renderers&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now let&apos;s imagine this code in a ASP.Net Web API 2 controller&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;HttpPut&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Route&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;{id:int}/start&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;Task&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;IHttpActionResult&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Start&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt;&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;Integration&lt;/span&gt; integration &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; Db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MyIntegrations&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;FirstOrDefaultAsync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Id &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;integration &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; 
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        Logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Warn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;The user is trying to start an integration with id={0}, which it doesn&apos;t belongs to him&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;NotFound&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;  
    
    integration&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;IsActive &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; Db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;SaveChangesAsync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    Logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Integration {0} is now active and will start to process&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What I want to notice here is, first that I am using async API, and second that I am using Entity Framework 6, which already supports async API, which means that the code in this action will eventually jump from thread to thread while processing the current request. &lt;b&gt;So, the action will start to process in a given thread, and while it is awaiting for the first database call FirstOrDefaultAsync, the thread will be released to the thread pool instead of being blocked awaiting for the database to return. When the database returns, the action will continue to run in another thread from the thread pool&lt;/b&gt;. The same process happens when invoking the method SaveChangesAsync. &lt;b&gt;The major advantage of this async paradigm, is scalability, releasing threads that are not doing any job, allowing to use them to process otherrequests. Do not think that your code will run faster by using the async API&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So, the web request will be served using different threads, and this is a problem to my main goal of having the subscriptionid in all my logs. Why? Because &lt;b&gt;the MappedDiagnosticsContext class uses the thread local storage (TLS) to keep the dictionary with the properties, and the TLS does not flow across over async points, which means that when the first database call returns, the thread that will run the continuation it will not have anymore the subscriptionid in the TLS&lt;/b&gt;. This behavior relates &lt;a href=&quot;http://blogs.msdn.com/b/pfxteam/archive/2012/06/15/executioncontext-vs-synchronizationcontext.aspx&quot;&gt;how .Net deals with ExecutionContext&lt;/a&gt;, which is not an easy subject.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;To achieve our goal &lt;b&gt;we need to store the dictionary in something that will flow across async points. One possible solution is to use the ancient &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.runtime.remoting.messaging.callcontext(v=vs.110).aspx&quot;&gt;CallContext&lt;/a&gt;&lt;/b&gt;. Let&apos;s do this in a new class that I will name MappedDiagnosticaLogicalContext&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt; &lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;NLog&lt;/span&gt; 
 &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MappedDiagnosticsLogicalContext&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; LogicalContextDictKey &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;NLog.MappedDiagnosticsLogicalContext&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;IDictionary&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; LogicalContextDict
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; dict &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; CallContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;LogicalGetData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;LogicalContextDictKey&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ConcurrentDictionary&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dict &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    dict &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;ConcurrentDictionary&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                    CallContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;LogicalSetData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;LogicalContextDictKey&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dict&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; dict&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            LogicalContextDict&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;LogicalContextDict&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;TryGetValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;out&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                s &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Empty&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
 &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can rewrite our base controller to use this class instead of the class MappedDiagnosticsContext&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;NLog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MappedDiagnosticsLogicalContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;subscriptionid&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; SubscriptionId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But we also need a custom layout render that can read and expand this items&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt; &lt;span class=&quot;token keyword&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;NLog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;LayoutRenderers&lt;/span&gt;
 &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;LayoutRenderer&lt;/span&gt;&lt;span class=&quot;token attribute-arguments&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;mdlc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MdlcLayoutRenderer&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token type-list&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;LayoutRenderer&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;RequiredParameter&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;DefaultParameter&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; Item &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;StringBuilder&lt;/span&gt; builder&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LogEventInfo&lt;/span&gt; logEvent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; msg &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; MappedDiagnosticsLogicalContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Item&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            builder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Append&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;msg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
 &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This new layout render can be used like this ${mdlc:item=subscriptionid} (mdlc means mapped diagnostics logical context). We need to change our NLog config file, replacing all ocurrences of ${mdc:} by ${mdlc:}.&lt;/p&gt;
&lt;p&gt;Finally, and &lt;b&gt;since we are using a custom layout render we have to register it, in the startup of the application&lt;/b&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;NLog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ConfigurationItemFactory&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Default&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;LayoutRenderers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;RegisterDefinition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;mdlc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token type-expression class-name&quot;&gt;MdlcLayoutRenderer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;b&gt;I made a &lt;a href=&quot;https://github.com/NLog/NLog-Contrib/pull/7&quot;&gt;pull request to NLog.Contrib project&lt;/a&gt; to incorporate this new feature, and it was already merged and incorporated it in the NuGet NLog.Contrib. So, just grab the Nuget and start using without the need to know the internals&lt;/b&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Noisli - fantastic background noise and color generator ideal for working and relaxing.]]></description><link>https://bfcamara.com/post/67051172024/noisli-fantastic-background-noise-and-color</link><guid isPermaLink="false">https://bfcamara.com/post/67051172024/noisli-fantastic-background-noise-and-color</guid><pubDate>Fri, 15 Nov 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://www.noisli.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://www.noisli.com/&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;Noisli is a fantastic background noise and color generator ideal for working and relaxing.&lt;/blockquote&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Awesome. An enjoyable idea!!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[A Guide to Web Components | CSS-Tricks]]></description><link>https://bfcamara.com/post/66863384047/a-guide-to-web-components-css-tricks</link><guid isPermaLink="false">https://bfcamara.com/post/66863384047/a-guide-to-web-components-css-tricks</guid><pubDate>Wed, 13 Nov 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://css-tricks.com/modular-future-web-components/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://css-tricks.com/modular-future-web-components/&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;The following is a guest post by Rob Dodson (@rob_dodson). Rob and I were going back and forth in CodePen support getting Polymer (a web components polyfil&lt;/blockquote&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;A very good post about Web Components. Do you know what is the Shadow DOM? Worth reading.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[NLog: How to include custom context variables in all your logs]]></title><description><![CDATA[NLog: How to include custom context variables in all your logs]]></description><link>https://bfcamara.com/post/66886024762/nlog-how-to-include-custom-context-variables-in</link><guid isPermaLink="false">https://bfcamara.com/post/66886024762/nlog-how-to-include-custom-context-variables-in</guid><pubDate>Wed, 13 Nov 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Logging is a very important aspect of every application&lt;/strong&gt;. There are a lot of logging frameworks available for the .Net platform, and I won&apos;t discuss which one is better. Many times it is a matter of taste. For example, if we are .Net developers but develop for Java as well, it makes sense to choose &lt;a href=&quot;http://logging.apache.org/log4net/&quot; target=&quot;_blank&quot;&gt;Log4Net&lt;/a&gt; since it is port of the well known &lt;a href=&quot;http://logging.apache.org/log4&quot; target=&quot;_blank&quot;&gt;Log4j&lt;/a&gt;, so you can capitalize your knowlodge in both platforms.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In the past I&apos;ve used a lot Log4Net, but nowadays, my logging framework of choice is &lt;a href=&quot;http://nlog-project.org/&quot; target=&quot;_blank&quot;&gt;NLog&lt;/a&gt;&lt;/strong&gt;. For the vast majority of scenarios there is no big difference between platforms, but since NLog was written entirely with .Net in mind, I tend to prefer NLog. Both platforms have great community support and there are a lot of configuration choices available for different scenarios (file logging, sql logging, etc.)&lt;/p&gt;
&lt;p&gt;In this post I would like to show you a not very well known feature, in which &lt;strong&gt;we can include some&amp;nbsp;custom context variables in our log statements, without the need to specify the variables every time we are emiting the log&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Here is the scenario: we are developing a SaaS web application, and we want to include in all our logs the subscription id, for all web requests&lt;/strong&gt;.The subscription id identities univocally the subscription that is issuing the web request.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;Introducing Mapped Diagnostics Context&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;From the &lt;a href=&quot;http://nlog-project.org/documentation/v2.0.1/html/T_NLog_MappedDiagnosticsContext.htm&quot; target=&quot;_blank&quot;&gt;NLog documentation&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Mapped Diagnostics Context is a thread local structure that keeps a dictionary of strings and provides methods to output them in layouts&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here is the code we have write to add a key to this dictionary&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;NLog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MappedDiagnosticsContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;subscriptionid&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; subscriptionId&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After running this line of code, the key subscriptionid is available in the thread local structure. We now need to configure our logging layout to include this key in our logs. Here is a typical configuration&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;227&quot; data-orig-width=&quot;500&quot;&gt;&lt;img alt=&quot;image&quot; src=&quot;https://66.media.tumblr.com/3fa6e7fd3cc826c171148d73764b7bc0/b3956245fd2a64c0-e8/s540x810/1be897f8d8a39205d355fbad7a15b6b6a39a7b25.png&quot; data-orig-height=&quot;227&quot; data-orig-width=&quot;500&quot;&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;To include the subscription id in the logs we&apos;ve just used &lt;strong&gt;${mdc:item=subscriptionid}&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We can now to grep/find all logs for a given &quot;suspicious&quot; subscription. Let me check some suspicious activity on subscription 25&lt;/p&gt;
&lt;pre&gt;grep &quot;[S:25]&quot; *.log 
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;When to set Mapped Diagnostics Context&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We wish to set our mapped diagnostics context keys as soon as possible. For example, if your application is an Asp.Net MVC application, you can set at the beginning of your action, or as an alternative, in an action filter.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;Is this works with async/await?&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One thing to notice about &lt;strong&gt;MappedDiagnosticsContext is that is a dictionary stored in thread local storage (TLS)&lt;/strong&gt;. This is very important to perceive, in particular if you are in a multi-thread environment. Even &lt;strong&gt;if you are using the new paradigm of async and await for asynchronous programing, which is awesome and makes extremely easy for the developer to program in asynchronous way, we have to understand that the TLS does not flow in async points&lt;/strong&gt;. This means that we will loose this information as soon as we get another thread different from the one where we set the value.&lt;/p&gt;
&lt;p&gt;So, how can we make this works with async/await, and guarante that we have always our subscription id in our logs, even if&amp;nbsp;a web request is served by multiple threads during the lifecycle of the request? Basically, &lt;strong&gt;we will have to use a different storage from the TLS, one that flows in async poinst. We can use the CallContext. In my next post I will show you how to implement this feature&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Btw, if you are using Log4net, it is already supported out of the box with &lt;a href=&quot;http://logging.apache.org/log4net/release/manual/contexts.html&quot; target=&quot;_blank&quot;&gt;contexts&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Log4Net supports different scope contexts:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Global (log4net.GlobalContext) - The global context is shared by all threads in the current AppDomain. This context is thread safe for use by multiple threads concurrently. The NLog equivalent is the &lt;strong&gt;NLog.GlobalDiagnosticsContext&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Thread (log4net.ThreadContext) - The thread context is visible only to the current managed thread. The NLog equivalent is the &lt;strong&gt;NLog.MappedDiagnosticsContext.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;LogicalTread (log4net.ThreadLogicalContext). The logical thread context is visible to a logical thread. Logical threads can jump from one managed thread to another. For more details see the .NET API System.Runtime.Remoting.Messaging.CallContext.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;I haven&apos;t figured the equivalent in NLog to the log4net.ThreadLogicalContext. So I had to implement it in my current project. Wait for the next post.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Authentication in a SPA with Angular]]></title><description><![CDATA[Authentication in a SPA with Angular]]></description><link>https://bfcamara.com/post/66001429506/authentication-in-a-spa-with-angular</link><guid isPermaLink="false">https://bfcamara.com/post/66001429506/authentication-in-a-spa-with-angular</guid><pubDate>Mon, 04 Nov 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;There is no doubt that&lt;strong&gt; Single Page Applications (SPA) is a trend that is growing more and more each day. &amp;nbsp;However, developing a SPA is harder than the traditional approach&lt;/strong&gt;, in which the pages are loaded, maybe there is&amp;nbsp;some ajax on the page with jQuery, and when you navigate away to another page a full reload occurs.&lt;/p&gt;
&lt;p&gt;When I started my journey developing SPAs, I had to &lt;strong&gt;rethink again on some aspects of the application&lt;/strong&gt;, and&amp;nbsp;check what is the best approach to solve some plumbing problems, such as &lt;strong&gt;authentication, authorization, &lt;/strong&gt;&lt;strong&gt;error handling,logging, i18n,&lt;/strong&gt; etc.&lt;/p&gt;
&lt;p&gt;Regarding authentication, I think there are two major approaches:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span&gt;consider authentication as a separate page, and we only load our SPA, when the user&amp;nbsp;&lt;/span&gt;is authenticated&lt;/li&gt;
&lt;li&gt;I have a &lt;strong&gt;pure SPA&lt;/strong&gt;, and authentication occurs inside the app, which means there is no need to reload, since the SPA is already loaded.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In both approaches I am assuming and taking as granted that&lt;strong&gt; the server always check for access-control&amp;nbsp;&lt;/strong&gt;(all access control in the client side can be overcome) and that we have an http interceptor&amp;nbsp;that checks the HTTP status response, and if we get an Unauthorized, we redirect the user to the login screen.&lt;/p&gt;
&lt;p&gt;In my current application I am working on, I opted for option 2, and I would like to show you how I implemented with Angular, which is my MV* web framework of choice.&lt;/p&gt;
&lt;p&gt;Fist of all, I have an Angular service, AuthService, which is responsible to provide helper authentication methods to the app.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;    
    &lt;span class=&quot;token string&quot;&gt;&apos;use strict&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    angular&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;app&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;authService&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;$rootScope&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Restangular&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;$rootScope&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Restangular&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; user &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;isAuthenticated&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        $rootScope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; user&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; authService &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        authService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;init&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;isAuthenticated&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; userName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isAuthenticated &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; isAuthenticated&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; userName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        authService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;isAuthenticated&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isAuthenticated&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        authService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;login&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;loginModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

            &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; loginResult &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Restangular&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;accounts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;customPOST&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;loginModel&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;login&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            loginResult&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isAuthenticated &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;loginOk&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;loginOk&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; loginModel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;userName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; loginResult&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        authService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;logout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Restangular&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;accounts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;customPOST&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;logout&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isAuthenticated &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        authService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;register&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;registerModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Restangular&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;accounts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;customPOST&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;registerModel&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;register&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        authService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;changePassword&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;changePasswordModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Restangular&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;accounts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;customPUT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;changePasswordModel&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;changePassword&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; authService&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;    &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;My fist implementation consisted of marking routes that need authentication, and detect when one of this routes are in place. The Angular route service provides an event, $routeChangeStart, every time a route changes. Here is the first implementation, that check routes with based on field allowAnonymous&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;use strict&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    angular&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;app&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;constant&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;APP_ROOT&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; angular&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;#linkAppRoot&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;href&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;$routeProvider&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;$httpProvider&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;$routeProvider&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; $httpProvider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

        $routeProvider
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;redirectTo&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/integrations&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/login&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;templateUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app/views/login.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;LoginCtrl&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;allowAnonymous&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/register&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;templateUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app/views/register.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;RegisterCtrl&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;allowAnonymous&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/integrations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;templateUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app/views/integrations.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;IntegrationsCtrl&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/integration/new&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;templateUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app/views/editIntegration.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;EditIntegrationCtrl&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/integration/:integrationId&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;templateUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app/views/editIntegration.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;EditIntegrationCtrl&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/activity&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;templateUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app/views/activity.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ActivityCtrl&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/changePassword&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;templateUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app/views/changePassword.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ChangePasswordCtrl&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;//.when(&apos;/settings&apos;, { templateUrl: &apos;app/views/settings.html&apos;, controller: &apos;SettingsCtrl&apos; })&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/externalaccounts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;templateUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app/views/externalAccounts.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ExternalAccountsCtrl&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/404&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;templateUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app/views/404.html&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;otherwise&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;redirectTo&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/404&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        $httpProvider&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;interceptors&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;processErrorHttpInterceptor&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;


    angular&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;app&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;$location&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;$rootScope&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;$log&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;authService&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;$route&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;$location&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; $rootScope&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; $log&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; authService&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; $route&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

            &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handleRouteChangeStart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;event&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; current&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;next&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;allowAnonymous &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;amp&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;amp&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;authService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isAuthenticated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    $log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;authentication required. redirect to login&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

                    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; returnUrl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; $location&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                    $log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;returnUrl=&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; returnUrl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

                    &lt;span class=&quot;token comment&quot;&gt;//TODO: BUG -&amp;amp;gt; THIS IS NOT PREVENTING THE CURRENT ROUTE&lt;/span&gt;
                    &lt;span class=&quot;token comment&quot;&gt;//This has a side effect, which is load of the controller/view configured to the route&lt;/span&gt;
                    &lt;span class=&quot;token comment&quot;&gt;//The redirect to login occurs later.&lt;/span&gt;
                    &lt;span class=&quot;token comment&quot;&gt;//Possible solutions: &lt;/span&gt;
                    &lt;span class=&quot;token comment&quot;&gt;// 1 - use $locationChangeStart (it is hard to get the route being used)&lt;/span&gt;
                    &lt;span class=&quot;token comment&quot;&gt;// 2 - Use a resolver in controller, returning a promise, and reject when needs auth&lt;/span&gt;
                    event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;preventDefault&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

                    $location&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/login&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;returnUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; returnUrl &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

            $rootScope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;$routeChangeStart&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; handleRouteChangeStart&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;However, there is a problem with this solution, since the code &lt;strong&gt;e.preventDefault() it does nothing. Basically the route is not prevented, which means that the destination controller is loaded, and eventually some API calls to the server are being done&lt;/strong&gt;. In functional terms the user is redirected to the login screen, however we can have API calls that are not necessary due the fact that the controller is instantiated.&lt;/p&gt;
&lt;p&gt;So,&lt;strong&gt; the correct approach consists to prevent the route to succeed&lt;/strong&gt;. How can we do that in Angular? Well, in Angular, we can participate in the resolving process&amp;nbsp; before the route succeeds. Here is the Angular documentation for the when() method of &lt;a href=&quot;http://docs.angularjs.org/api/ngRoute.$routeProvider&quot;&gt;$routeProvider&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;resolve&lt;/strong&gt; - {Object.&amp;lt;string, function&amp;gt;=} - An optional map of dependencies which should be injected into the controller. If any of these dependencies are promises, the router will wait for them all to be resolved or one to be rejected&lt;/em&gt; before the controller is instantiated. If all the promises are resolved successfully, the values of the resolved promises are injected and $routeChangeSuccess event is fired. If any of the promises are rejected the $routeChangeError event is fired.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So,&lt;strong&gt; if we have a promise that is rejected when the user tries to achieve a route that needs authentication and the user is not authenticated, then the route is aborted and the event $routeChangeError is fired&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Based on this fact, here is the final implementation&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;use strict&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    angular&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;app&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;constant&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;APP_ROOT&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; angular&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;#linkAppRoot&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;attr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;href&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;$routeProvider&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;$httpProvider&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;$locationProvider&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;$routeProvider&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; $httpProvider&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; $locationProvider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;checkLoggedIn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;$q&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; $log&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; authService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; deferred &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; $q&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;defer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;authService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isAuthenticated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                $log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;authentication required. redirect to login&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                deferred&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;needsAuthentication&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                deferred&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; deferred&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;promise&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        $routeProvider&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;whenAuthenticated&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; route&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            route&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;resolve &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; route&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;resolve &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            angular&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;route&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;resolve&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;isLoggedIn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;$q&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;$log&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;authService&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; checkLoggedIn&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; $routeProvider&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; route&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;


        $routeProvider
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;redirectTo&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/integrations&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/login&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;templateUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app/views/login.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;LoginCtrl&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/register&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;templateUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app/views/register.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;RegisterCtrl&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;whenAuthenticated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/integrations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;templateUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app/views/integrations.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;IntegrationsCtrl&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;whenAuthenticated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/integration/new/:integrationType&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;templateUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app/views/editIntegration.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;EditIntegrationCtrl&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;whenAuthenticated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/integration/:integrationType/:integrationId&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;templateUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app/views/editIntegration.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;EditIntegrationCtrl&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;whenAuthenticated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/activity&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;templateUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app/views/activity.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ActivityCtrl&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;whenAuthenticated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/changePassword&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;templateUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app/views/changePassword.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ChangePasswordCtrl&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;//.whenAuthenticated(&apos;/settings&apos;, { templateUrl: &apos;app/views/settings.html&apos;, controller: &apos;SettingsCtrl&apos; })&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;whenAuthenticated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/externalaccounts&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;templateUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app/views/externalAccounts.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ExternalAccountsCtrl&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/404&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;templateUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app/views/404.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;NotFoundErrorCtrl&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/apierror&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token literal-property property&quot;&gt;templateUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app/views/apierror.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;controller&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ApiErrorCtrl&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;otherwise&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;redirectTo&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/404&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        $httpProvider&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;interceptors&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;processErrorHttpInterceptor&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    angular&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;app&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;$location&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;$rootScope&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;$log&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;authService&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;$route&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;$location&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; $rootScope&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; $log&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; authService&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; $route&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

            $rootScope&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;$routeChangeError&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;ev&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; current&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; previous&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rejection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rejection &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;amp&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;amp&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; rejection&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;needsAuthentication &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; returnUrl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; $location&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                    $log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;returnUrl=&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; returnUrl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                    $location&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/login&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;returnUrl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; returnUrl &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Basically the method whenAuthenticated adds the checkLoggedIn resolver to the route resolve object, which asks to the authService if the current user is authenticated. If not, it rejects the promise, and the $routeChangeError is raised, which in turn is handled redirecting to login route.&lt;/p&gt;
&lt;p&gt;I hope it helps&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[The Art of Non-Conformity » Risk Something to Gain Something]]></description><link>https://bfcamara.com/post/65681524212/the-art-of-non-conformity-risk-something-to-gain</link><guid isPermaLink="false">https://bfcamara.com/post/65681524212/the-art-of-non-conformity-risk-something-to-gain</guid><pubDate>Fri, 01 Nov 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://chrisguillebeau.com/3x5/risk-something-to-gain-something/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://chrisguillebeau.com/3x5/risk-something-to-gain-something/&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;span&gt;&amp;ldquo;If you only do things where you know the answer in advance, your company goes away.&amp;rdquo; -Jeff Bezos&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[How To Launch A Startup Without Writing Code]]></description><link>https://bfcamara.com/post/64760129372/how-to-launch-a-startup-without-writing-code</link><guid isPermaLink="false">https://bfcamara.com/post/64760129372/how-to-launch-a-startup-without-writing-code</guid><pubDate>Tue, 22 Oct 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://onstartups.com/tabid/3339/bid/102728/How-To-Launch-A-Startup-Without-Writing-Code.aspx&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://onstartups.com/tabid/3339/bid/102728/How-To-Launch-A-Startup-Without-Writing-Code.aspx&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;A startup should be about solving a customer problem -- which does not always mean building a product from scratch.&lt;/blockquote&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[10 Reasons Web Developers Should Learn AngularJS (by Wintellect)]]></description><link>https://bfcamara.com/post/61746178705/10-reasons-web-developers-should-learn-angularjs</link><guid isPermaLink="false">https://bfcamara.com/post/61746178705/10-reasons-web-developers-should-learn-angularjs</guid><pubDate>Fri, 20 Sep 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://wintellect.com/blogs/jlikness/10-reasons-web-developers-should-learn-angularjs&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://wintellect.com/blogs/jlikness/10-reasons-web-developers-should-learn-angularjs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An excelent &lt;a href=&quot;http://wintellect.com/blogs/jlikness/10-reasons-web-developers-should-learn-angularjs&quot; target=&quot;_blank&quot;&gt;post&lt;/a&gt;&amp;nbsp;describing the the top 10 reasons why we should learn and use AngularJS. It is an extensive post, well written. Worth read. Here is the summary&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;AngularJS gives XAML developers a place to go on the web&lt;/strong&gt;: the principles reflected in AngularJS allows us to have the same advantages of the XAML frameworks (WPF, Silverlight), such as data-binding, parallel work between designers and developers, great separation of UI and the logic that fetches and processes data&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AngularJS gets rid of ritual and ceremony&lt;/strong&gt;: just plain javascript objects to participate in the data-bindng process. No need to extend from an existing object.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AngularJS handles dependencies&lt;/strong&gt;: just tell angular what you need and angular goes anf gets it for you. &lt;strong&gt;It&apos;s all about dependency injection&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AngularJS allows developers to express UI declaratively and reduce side effects&lt;/strong&gt;: The UI is well structured, and by declaring your UI and placing markup directly in HTML, you keep de presentation logic in one place and separated from the imperative logic. You can even extend HTML using angular directives.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AngularJS embraces DD...Er, Testing&lt;/strong&gt;: AngularJS helps you to write tests easy. The framework is prepared to unit testes or end-2-end tests&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AngularJS enables parallel development&lt;/strong&gt;: AngularJS defines a set of concepts (modules, controllers, services, directives, etc.) which help us to structure our application in a way that allows us to have easily multiple developers working simultaneously on different parts of the application&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AngularJS enables a Design &amp;lt;-&amp;gt; Development workflow&lt;/strong&gt;: in AngularJS it&apos;s more easy to designer add markup without completely breaking an application, due the separation between the UI and &amp;nbsp;logic.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AngularJS gives developers controls&lt;/strong&gt;: AngularJS has a concept named directives which allows to create new HTML elements and attributes. Basically it&apos;s a way to increase the browser vocabulary&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AngularJS helps developers manage client state&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AngularJS supports Singe Page Applications&lt;/strong&gt;: AngularJS provides all the necessary foundations (routing, templates, views, history, etc) to build a SPA&lt;/li&gt;
&lt;/ol&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Getting Ready for AngularJS 1.2]]></description><link>https://bfcamara.com/post/61694788777/getting-ready-for-angularjs-12</link><guid isPermaLink="false">https://bfcamara.com/post/61694788777/getting-ready-for-angularjs-12</guid><pubDate>Thu, 19 Sep 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://wildermuth.com/2013/09/18/Getting_Ready_for_AngularJS_1_2&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://wildermuth.com/2013/09/18/Getting_Ready_for_AngularJS_1_2&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[UIBox - Curated HTML, CSS, JS UI Component Library]]></description><link>https://bfcamara.com/post/60349812874/uibox-curated-html-css-js-ui-component-library</link><guid isPermaLink="false">https://bfcamara.com/post/60349812874/uibox-curated-html-css-js-ui-component-library</guid><pubDate>Thu, 05 Sep 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://www.uibox.in/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://www.uibox.in/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.uibox.in/&quot; target=&quot;_blank&quot;&gt;UIBox&lt;/a&gt; - it seems to me a very good initiative. Almost any Web UI component that we can think of has already been built by someone.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;A search on Google results in hundreds of results. All this is great!&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Except for a few problems: no demos, poor documentation, dependencies conflicts, browser support, etc.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;The UIBox initiative tries to help solving this problems. To start with, UIBox is a curated HTML, CSS, JS UI component library.&amp;nbsp;&lt;/span&gt;&lt;span&gt;There are a few requirements to a given component be present in UIBox:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;must have a working demo page&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;must be well documented&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;http://www.uibox.in/blog/the-whys-and-whats-of-uibox&quot; target=&quot;_blank&quot;&gt;check the motivations and reasons&lt;/a&gt; for the UIBox initiative.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[High Scalability - Sean Hull's 20 Biggest Bottlenecks that Reduce and Slow Down Scalability]]></description><link>https://bfcamara.com/post/59663310250/high-scalability-sean-hulls-20-biggest</link><guid isPermaLink="false">https://bfcamara.com/post/59663310250/high-scalability-sean-hulls-20-biggest</guid><pubDate>Thu, 29 Aug 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://highscalability.com/blog/2013/8/28/sean-hulls-20-biggest-bottlenecks-that-reduce-and-slow-down.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://highscalability.com/blog/2013/8/28/sean-hulls-20-biggest-bottlenecks-that-reduce-and-slow-down.html&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;This article is a lightly edited version of 20 Obstacles to Scalability by Sean Hull ( with ...&lt;/blockquote&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;A great article enumerating the biggest bottenecks thar impact scalability:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;2-phase commit&lt;/li&gt;
&lt;li&gt;Insufficient or no caching&lt;/li&gt;
&lt;li&gt;Bad Disks, Raid 5, Multitenant storage&lt;/li&gt;
&lt;li&gt;Serial processing&lt;/li&gt;
&lt;li&gt;Missing feature flags (enable/disable features)&lt;/li&gt;
&lt;li&gt;Single copy of database&lt;/li&gt;
&lt;li&gt;Using database for queuing&lt;/li&gt;
&lt;li&gt;Using database for full-text searching&lt;/li&gt;
&lt;li&gt;Object Relational Mappers (ORMs)&lt;/li&gt;
&lt;li&gt;Missing instrumentation&lt;/li&gt;
&lt;li&gt;Not using a version control system&lt;/li&gt;
&lt;li&gt;Single points of faillure&lt;/li&gt;
&lt;li&gt;Lack of browse-only mode&lt;/li&gt;
&lt;li&gt;Weak communication between team members&lt;/li&gt;
&lt;li&gt;Lack of documentation&lt;/li&gt;
&lt;li&gt;Lack of fire drills&lt;/li&gt;
&lt;li&gt;Insufficient monitoring and metrics&lt;/li&gt;
&lt;li&gt;Cowboy operations&lt;/li&gt;
&lt;li&gt;Growing technical debt&lt;/li&gt;
&lt;li&gt;Insufficiente Logging&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Leaving Agilior....]]></title><description><![CDATA[Leaving Agilior....]]></description><link>https://bfcamara.com/post/57412426451/leaving-agilior</link><guid isPermaLink="false">https://bfcamara.com/post/57412426451/leaving-agilior</guid><pubDate>Mon, 05 Aug 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;/p&gt;&lt;figure data-orig-height=&quot;225&quot; data-orig-width=&quot;225&quot;&gt;&lt;img alt=&quot;image&quot; class=&quot;floatright&quot; src=&quot;https://66.media.tumblr.com/2eda85740c00729a0edc2687ed01b755/0250b003859ce3eb-51/s540x810/62ce3b10a73aa304c1423db1da4236272205903d.jpg&quot; data-orig-height=&quot;225&quot; data-orig-width=&quot;225&quot;&gt;&lt;/figure&gt;&lt;strong&gt;Last week was my last working week at Agilior&lt;/strong&gt;. Nine and half years after I have founded Agilior, at 4 January 2004, today it ends a cycle in my life. As most of you already know, because you know me personally or have read my post &quot;&lt;a href=&quot;http://www.bfcamara.com/post/17149497531/my-first-big-mistake-as-founder&quot; target=&quot;_blank&quot;&gt;My First Big Mistake as a Founder&lt;/a&gt;&quot;, I already have not any shares of the company, and currently &amp;nbsp;I was just an employee.&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This way out was expected for some time due the fact that Agilior, in the present moment, could not give me the professional achievement that I need&lt;/strong&gt;. Hence I&apos;m feeling with a mix of feelings of happiness and nostalgy. Happiness because this way out it is something that I already wanted some time ago, but I have not had &amp;nbsp;the courage to do it. Nostalgy because I look back and &lt;strong&gt;I remember great moments that I lived at Agilior, in particular the times that I helped to grow a company&lt;/strong&gt; which started with 3 people, becoming in a company with 9 people. I&apos;ve had a great pleasure to work with these people, building software development projects.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;So, I&apos;m finishing now a stage in my life, and in this moment I&lt;strong&gt; need some time to think and reflect about what to do next, and decide what way to follow&lt;/strong&gt;. I will take off some vacations on August with total dedication to the family, and avoiding being online.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Switching off&lt;/p&gt;</content:encoded></item><item><title><![CDATA[LightSwitch and the Enterprise]]></title><description><![CDATA[LightSwitch and the Enterprise]]></description><link>https://bfcamara.com/post/55592027897/lightswitch-and-the-enterprise</link><guid isPermaLink="false">https://bfcamara.com/post/55592027897/lightswitch-and-the-enterprise</guid><pubDate>Tue, 16 Jul 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;After reading &lt;a href=&quot;http://blogs.msdn.com/b/ponderdotnet/archive/2013/07/09/lightswitch-and-the-enterprise.aspx&quot; title=&quot;LightSwitch and the Enterprise&quot; target=&quot;_blank&quot;&gt;this post about LightSwitch in the Enterprise&lt;/a&gt;, I decided to give my two cents.&lt;/p&gt;
&lt;p&gt;I started developing with LightSwitch since the first Beta version, which &lt;a href=&quot;http://www.zdnet.com/blog/microsoft/microsofts-lightswitch-building-business-apps-for-web-pcs-and-cloud/6981&quot; title=&quot;LightSwitch Launch at 2010&quot; target=&quot;_blank&quot;&gt;was lauched in 2010&lt;/a&gt;, in last days of August. At that time, I was developing with my team a web application around Governance, Risk Management, and Complicance (GRC). &lt;strong&gt;We were using a typical web stack with ASP.Net MVC, Entity Framework (I can&apos;t remember if it was Linq2Sql at that time), Html, Javascript, in particular jQuery. The truth is that our velocity was very slow, and we were constantly struggling with the user interface&lt;/strong&gt;. As soon as the first Beta 1 of LightSwitch was available to download, I decided to give it a try. Since we had the data model already designed, &lt;strong&gt;I tried to use LightSwitch to develop the majority of the screens that we had, but now using Lightswitch. The final result was awesome, since I spent no more than two days to build the screens that had been developed in a month&lt;/strong&gt;. The application was now a silverlight app running on the browser, with a different look and feel, but you know what: the product owner liked the &quot;aesthetics&quot; of this new silverlight app and we decided to move on with LightSwitch to build the first version of app (which was designed following the Minimum Viable Prodcut approach, to test the idea of the product).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Since then, I have already used Lightswitch in many other situations, developing applications that are currently running in production. I don&apos;t have doubts that Lightswitch has a corner in the enterprise applications space, allowing a development team has a boost in productivity, and seeing their development costs reduced.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I am happy to watch Microsoft investing in Lightswitch, improving, for example, the collaborative development on Lightswitch applications, which &lt;a href=&quot;http://blogs.msdn.com/b/bethmassi/archive/2013/06/27/lightswitch-in-visual-studio-2013-preview.aspx&quot; title=&quot;Visual Studio LightSwitch 2013 &quot; target=&quot;_blank&quot;&gt;was already announced to be present in Visual Studio 2013&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Even though it seems I am LightSwitch fan, I am not saying that LightSwitch is a silver bullet, and that we should forget everything we learned so far. Far from that. What I am saying, is that LightSwitch can be used in the Enterprise without any fear. I suggest to start with small applications, maybe to serve a few department users, and specially if you have a lot CRUD screens (a typical small backoffice application, perhaps). &lt;strong&gt;I think you will be surprised how fast you develop this kind of apps with Lightswitch&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I am not saying also that Lightswitch does not have any problems. As any other technology, Lightswitch can present some problems. For example, you have to know very well the technology to avoid some performance issues you can have. &lt;strong&gt;LightSwitch advocates a kind of development, and you have to know it well. When we are constantly struggling with LightSwitch to do things, perhaps it is a signal that we shouldn&apos;t be using LightSwitch&lt;/strong&gt;. There are a lot extensibility points there, but it&apos;s not comparable with the full control you have when using the tools you want (for example, Asp.Net MVC, WebApi, HTML5, CSS, jQuery, etc.).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;As a conclusion, I just want to say that Lightswitch has a space in the enterprise. Of course every organization is different, with different requirements, and above all, with different believings when regarding software development, which can produce some resistance to adopt this kind of RAD tool. Give it a try to use Lightswitch in a small CRUD line-of-business application, and in an economical point of view you will be surprised about the results.&lt;/strong&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[A directive to manage file upload in an AngularJS application]]></description><link>https://bfcamara.com/post/54339038199/a-directive-to-manage-file-upload-in-an-angularjs</link><guid isPermaLink="false">https://bfcamara.com/post/54339038199/a-directive-to-manage-file-upload-in-an-angularjs</guid><pubDate>Mon, 01 Jul 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://blog.brunoscopelliti.com/a-directive-to-manage-file-upload-in-an-angularjs-application&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://blog.brunoscopelliti.com/a-directive-to-manage-file-upload-in-an-angularjs-application&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;This week I was in the need to add the functionality of file upload to an AngularJS web application, on which I&amp;acirc;m working for a personal project. Since my project also uses jQuery, I found that the...&lt;/blockquote&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Full-Spectrum Testing with AngularJS and Karma - yearofmoo.com]]></description><link>https://bfcamara.com/post/53744858168/full-spectrum-testing-with-angularjs-and-karma</link><guid isPermaLink="false">https://bfcamara.com/post/53744858168/full-spectrum-testing-with-angularjs-and-karma</guid><pubDate>Mon, 24 Jun 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://www.yearofmoo.com/2013/01/full-spectrum-testing-with-angularjs-and-karma.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://www.yearofmoo.com/2013/01/full-spectrum-testing-with-angularjs-and-karma.html&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;Learn how to fully test your AngularJS application with Karma in every possible area using E2E, Unit and Midway testing&lt;/blockquote&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[The Hitchhiker's Guide to the Directive]]></description><link>https://bfcamara.com/post/53266582847/the-hitchhikers-guide-to-the-directive</link><guid isPermaLink="false">https://bfcamara.com/post/53266582847/the-hitchhikers-guide-to-the-directive</guid><pubDate>Tue, 18 Jun 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://amitgharat.wordpress.com/2013/06/08/the-hitchhikers-guide-to-the-directive/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://amitgharat.wordpress.com/2013/06/08/the-hitchhikers-guide-to-the-directive/&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;AngularJS Directive is what we have close to Web Components at this time and is the most crucial and difficult piece in AngularJS. I&apos;ve not found any suitable article on the web to fully understand...&lt;/blockquote&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Running a desktop app with AngularJS served from a Windows Service with Katana (OWIN)]]></title><description><![CDATA[Running a desktop app with AngularJS served from a Windows Service with Katana (OWIN)]]></description><link>https://bfcamara.com/post/52138881551/running-a-desktop-app-with-angularjs-served-from-a</link><guid isPermaLink="false">https://bfcamara.com/post/52138881551/running-a-desktop-app-with-angularjs-served-from-a</guid><pubDate>Tue, 04 Jun 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Nowadays, &lt;strong&gt;when developing desktop applications for Windows, we have many options when choosing the .Net technology&lt;/strong&gt; to use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows Prsentation Foundation (WPF) - in my opinion, this is the most consensus choide&lt;/li&gt;
&lt;li&gt;Windows Forms&lt;/li&gt;
&lt;li&gt;Silverlight&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the target is Windows 8 we can add even more choices to the pile, for example using HTML5 and Javascript, due the support of the new WinRT architecture.&lt;/p&gt;
&lt;p&gt;Recently I had to analyze a scenario where a windows service should be developed, which would be responsible to run some kind of scheduled tasks -&amp;nbsp;polling a SaaS service on the public internet, and integrate some data with on-premises systems. Additionally, a graphical tool should also be developed, to allow&amp;nbsp;to&amp;nbsp;configure some aspects of the windows service (instead of editing configuration files by hand).&lt;/p&gt;
&lt;p&gt;For the UI tool, my first approach was to choose a WPF application. But I have no experience at all with WPF, and as a developer I am more comfortable with the web stack development, which means that on the client side I would like to use Html5 and Javascript, and the UI tool would be running on the browser.&lt;/p&gt;
&lt;p&gt;Since &lt;a href=&quot;http://bfcamara.com/post/50641543547/im-in-love-with-angularjs-here-is-the&quot; target=&quot;_blank&quot;&gt;I&apos;m in love with AngularJS&lt;/a&gt;, my wish was to develop the tool using &lt;a href=&quot;http://angularjs.org/&quot; title=&quot;AngularJS&quot; target=&quot;_blank&quot;&gt;AngularJS&lt;/a&gt;. But I don&apos;t want to complicate the installation process, requiring my tool to be hosted in Internet Information Service (IIS). So, what I really want is to &lt;strong&gt;install my window service, which besides the integration logic, should also host my AngularJS application&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Well, in fact, what &lt;strong&gt;I really need is to have some kind of embedded web server&lt;/strong&gt; that supports:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Static files - (html, images, css and javascript files)&lt;/li&gt;
&lt;li&gt;AspNet Web Api - I want to use WebApi to return the data to the graphical tool&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With this goal in mind, it&apos;s time to meet &lt;a href=&quot;owin.org&quot; title=&quot;OWIN&quot; target=&quot;_blank&quot;&gt;OWIN&lt;/a&gt; (Open web Interface for .Net) specification and the &lt;a href=&quot;http://katanaproject.codeplex.com/&quot; title=&quot;Katana Project&quot; target=&quot;_blank&quot;&gt;Katana Project&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;From the OWIN site&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;em&gt;OWIN defines a standard interface between .NET web servers and web applications. The goal of the OWIN interface is to decouple server and application, encourage the development of simple modules for .NET web development, and, by being an open standard, stimulate the open source ecosystem of .NET web development tools.&lt;/em&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, basically, &lt;strong&gt;OWIN is a spec which allows components to be reused on different web servers&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The &lt;a href=&quot;http://katanaproject.codeplex.com/&quot; title=&quot;Katana Project&quot; target=&quot;_blank&quot;&gt;Katana Project&lt;/a&gt; is a collection of projects to support OWIN with various Microsoft components&lt;/strong&gt;. It is also a command line application for running self-host servers. To have a great overview of the Katana project read &lt;a href=&quot;http://www.asp.net/vnext/overview/owin-and-katana/an-overview-of-project-katana&quot; title=&quot;Overview of Katana Project&quot; target=&quot;_blank&quot;&gt;this post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ok, stop theory, and show me the&amp;nbsp;&lt;strong&gt;how can I use Katana to embed a small web server on my windows service&lt;/strong&gt;. which allows me to build an AngularJS app. Here we go!&lt;/p&gt;
&lt;p&gt;First, let&apos;s create a new Visual Studio project, choosing the type Windows Service&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAIAAABr+ngCAAAACXBIWXMAAAsTAAALEwEAmpwYAAACS0lEQVQoz33QWWsTQQDA8Xx3XwQFRTxAsPZF8EUsUq2KliJeTTXdpkeyZ5PsMfd97GwqVJJgqbY4/BlmmPk9zPTuP9m6/ej1jbuvbj54c+vxuztrH++tbz989mntRf/py/76Rv/52+HGTrz5Odv6frr5rfjws9wZgkHB32/v9OI4T5IJRhw0BADKKOMUMYK81ZJTwakUzDsTvKtms6KYIogwhMG3aVr0yrKJDo5mJaBUEiIhJHVdQ4hAA6qqZkJgQgihUunTSVmWTVmC6bTCRIxOxj3OxGiUAICVMkoZQthkVjO6EFrrtvWccyG5962UVikrpWFMOhdGo7jHqBjHaV3D1UFdo8HB8SCK96NxklVpAQ6GaTRMy4pIaThXnCvBlTF+iZmIosO9vf2qAlq7psHRYZzl03GcZ9ksy2dpNs3ykhAhhF7FF7hdYIRIFJ0cH6cYc6UshCTOCik4RogQjBFilHLGvPecX8F1DTBmxnghtJQGIZIVKaUUAIAQAgBghIUQ1rprMOdytV9iCyFO8mSBmwZC2DQNQkhK+T98kZRaKe2cs5eGc84Ye82bL7BczMoY14XQet+2f1qujbFs9dWXsRBKa6uUoUITrpkw2nrt2n9yy1Y3pdTOhThOetPJhBASQjidVaMkryA2vnPh7K+6X3VVHQ0HoKmttcaY+Xye51kPIwQhdM5RSiEAnPEQwrzrLupCODubV1U5PIiSJGkaYIw9Pz8viqLnvQ8h+MXD2hBC27bO+astrnUdAM2P3S+jk8Oj4aC/+/U3qvwvYcmU4SMAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/7a16787b15e4d2fc9e8a617ddda961f7/8ac56/ba58a9f8272b045ba727965042111286ce299a37ef9a60b722778d2b235dfeeb.webp 240w,
/static/7a16787b15e4d2fc9e8a617ddda961f7/d3be9/ba58a9f8272b045ba727965042111286ce299a37ef9a60b722778d2b235dfeeb.webp 480w,
/static/7a16787b15e4d2fc9e8a617ddda961f7/b0a15/ba58a9f8272b045ba727965042111286ce299a37ef9a60b722778d2b235dfeeb.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/7a16787b15e4d2fc9e8a617ddda961f7/8ff5a/ba58a9f8272b045ba727965042111286ce299a37ef9a60b722778d2b235dfeeb.png 240w,
/static/7a16787b15e4d2fc9e8a617ddda961f7/e85cb/ba58a9f8272b045ba727965042111286ce299a37ef9a60b722778d2b235dfeeb.png 480w,
/static/7a16787b15e4d2fc9e8a617ddda961f7/0b533/ba58a9f8272b045ba727965042111286ce299a37ef9a60b722778d2b235dfeeb.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/7a16787b15e4d2fc9e8a617ddda961f7/0b533/ba58a9f8272b045ba727965042111286ce299a37ef9a60b722778d2b235dfeeb.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Next, let&apos;s make some modifications to the project to allow us to test without having to install the windows service:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Change the project type to Console Application (Project Properties)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 54.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAACgklEQVQoz02RSW4TQRSG+1AcBAmxAbFAyhW4AAuEGBZJRCBEssQQZyDEihXFbacH91RVPQ/u2W3HTghnADrdD1UlISw+/a+mv+r9xa2Ll4tX/GXa0c6rl30red6zs2e7pOiIflYUmReleRWlWRxneRln+WyS5tOkKJO0KKu0KM/TolwmeVEmRTEdCtJjbkdwYVvOgDc88IkErqmAR7FUsIkCFh4D0gQGrSmepTF8x4DAveP4aH+Fw1IfqkirM19vdFVukonXXCyrZjEvqF5NfLPRFaGxidbMyrj5eTFrfiynjCJ2miQkTRaZfyIPwcHelyecIvEQBWYTehiIoUCWhLA8K+FsVsBynsNoOILVjR3Y7BzC67UuvFr9j7UuvFnrti/efq2P+icg8N+fcqo8AIcozcTHkKcRM1vMC6bzacrainwTQhdD4KJrHKoYTDQGQxVbrEtXjqlC76D7kCO6AEloNqFrgG/TwwToa0OPgO8g8GwN4oBAHGCgl0YevhkTlreN5dYh4yuaab+394hTJR5CFzU0A13mQZUGdBPYSAYLSeDb2o0RYmbXiuiZW+M2DkhN5w6/dR9w1Dl0jSaw9XZ00muHx4etOOy3SD1tLSS1RBcYpiHe1CK9qDUNqbWQzOZNQ2QvZC0noUlb/h26qPYdXM/KpD6rsno+TeuqiO8oY7Y2zSd14Bq156J6EpA6ZuBfaWSDIgv3uds8aAu2abBfptAPOl9UjAumU1Yv5iXLOvD+tcwimfgEhoP+CmchecdE0gesS13XxgdYH+9JpyefxhL/3ibatk20LcfUdy2sbtpE23BMfV8RBxuazK/r49FnXRltq9JgXRj2P3a23t37C58ZzGrs9OT2AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/080838c4531a32baa8f38f5b7d4266bd/8ac56/685628c1f02450defe6cd397a96a5e92ed37cc09216870e99cf05fee69737b30.webp 240w,
/static/080838c4531a32baa8f38f5b7d4266bd/d3be9/685628c1f02450defe6cd397a96a5e92ed37cc09216870e99cf05fee69737b30.webp 480w,
/static/080838c4531a32baa8f38f5b7d4266bd/b0a15/685628c1f02450defe6cd397a96a5e92ed37cc09216870e99cf05fee69737b30.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/080838c4531a32baa8f38f5b7d4266bd/8ff5a/685628c1f02450defe6cd397a96a5e92ed37cc09216870e99cf05fee69737b30.png 240w,
/static/080838c4531a32baa8f38f5b7d4266bd/e85cb/685628c1f02450defe6cd397a96a5e92ed37cc09216870e99cf05fee69737b30.png 480w,
/static/080838c4531a32baa8f38f5b7d4266bd/0b533/685628c1f02450defe6cd397a96a5e92ed37cc09216870e99cf05fee69737b30.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/080838c4531a32baa8f38f5b7d4266bd/0b533/685628c1f02450defe6cd397a96a5e92ed37cc09216870e99cf05fee69737b30.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Change the Start and Stop methods of the windows service to allow calls from a console app&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 92.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAACXBIWXMAAAsTAAALEwEAmpwYAAAC9ElEQVQ4y6VUS4scVRg9t+6t96PrXTWpfk26m5iFoy4cZBIfG12JILiSbNwJIeA2KO4SF0KC4l/I1k1WIYiCCEEQdOVfcajqOnJrqoehScaAi8N3LtQ993yvwrXK+72OzMfLzHm0iNXPqYNnVwLjryZz/nhlHj17fRU/2TTRn29eLx+/ts5/Czzn16NV9uP1ZfLLe280jyLP/AnAUwB/A7gFxzIZWIKxKxmFAbM0YZGlzJKYVZmzrgoGvkslBU1lUAgMXMMaz8A5bkGTaR6eJq5s0zTtZvN5d6VptkVR6DicXdfdAmgBdCPavXg6Cn4C/YKQqovipF8ul2yahrPZjJvNhvPZjFVVUUp50cU++hGafzA4tG1bv0RDyuGylIpKmZRKUQhxmdhOcDvyDwfBKrTaOpAsPcHYBnMXTF3BzBWc1TnX2u18pr/jIvdZliXX6zUD39+JtmP8HNqB77md73ks84xZmrLIMybxZGiCYYjBtVKKhgBtU9I0TZ0VpWHsHHaj4KcQAJVpdX4QsK4PWFU1y7JiUZTDxf9I9/kp25bZ7X+onWtXlmUNwnvjsS/YnXdZkzKyt01s9UVosfAl6yLl4dWr1F1frVY8ODi4zO1Fh+8PNYwmk+4lUrtMkKPoW2cpm7K1ldE7pjFsgK2MYQuUATq2Sc/z6DjOy8zhjUGwjp0294xej8nEAhMHjG0xxDqPuVguOZ1OLxPcjc1n0HVabzbdq0dHvHHzJk9OTvj2O+/y+PiYy8NDzufzYXM0FovFi9DqWFXVHbiuy2gSd64f9GmWM0kzJmnKKArPZs8whobolF+A3nGc7cjPVi+0RZe6ovcVel+ijwK3L8uyr6qqn06nfTyZ9Bdq9TzsuvzRIJjH4WloG61vy9YzjTb0vS5Jki6O4zbP8zYKw3asU7v3p9nhn/MaKinpej7/x9hcxMdwbPs7AA8E8BUAzb8VwBdCiLtCiAdCiIcAvgbwA4D7AO4CuA3gGwDfA/gSwD2c3T/+Fw9pg6hb5gTWAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/6c7715cd9c2bdd01b09898ce8ec0fd40/8ac56/41acc09a4c9d3528566f32f4923165f7e056aa531f7c6555273707cd50e4481b.webp 240w,
/static/6c7715cd9c2bdd01b09898ce8ec0fd40/d3be9/41acc09a4c9d3528566f32f4923165f7e056aa531f7c6555273707cd50e4481b.webp 480w,
/static/6c7715cd9c2bdd01b09898ce8ec0fd40/b0a15/41acc09a4c9d3528566f32f4923165f7e056aa531f7c6555273707cd50e4481b.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/6c7715cd9c2bdd01b09898ce8ec0fd40/8ff5a/41acc09a4c9d3528566f32f4923165f7e056aa531f7c6555273707cd50e4481b.png 240w,
/static/6c7715cd9c2bdd01b09898ce8ec0fd40/e85cb/41acc09a4c9d3528566f32f4923165f7e056aa531f7c6555273707cd50e4481b.png 480w,
/static/6c7715cd9c2bdd01b09898ce8ec0fd40/0b533/41acc09a4c9d3528566f32f4923165f7e056aa531f7c6555273707cd50e4481b.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/6c7715cd9c2bdd01b09898ce8ec0fd40/0b533/41acc09a4c9d3528566f32f4923165f7e056aa531f7c6555273707cd50e4481b.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add a conditional compilation statement #if to allow to run in Debug as a console application&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 83.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAAAsTAAALEwEAmpwYAAADAElEQVQ4y5WUu28dRRTGz9nZee37fe/u3msHxzF2UrnBfxsNDQ2iAVGC0hAEChjFCAVFYAmkCCqETApQQJRU0APZ9X5orq+tK0tBofh0zsyOfnvONw8yeXmqjTkrQv+bLlUPy0B8P0/Vyf529um8sN8R0YfE9IiIXP45EZ0Q0bdE9JiITtc6JqIviOht0nH6p5QSRisoKaClj9AYhEZBeh6I6P/olExe/uqARDRYG44mC87TRT7o0gxkaKSIBgppXOUupjRQQiMFNBJd6e818B7ZvDxTSrnBmMcWTWbRFBG2ly1m7QwsGMR0IW9DfFXV5IpZ5/dJJ9nvvu+7wbnVEtIjCCIoX8Da4EXa3AR+QrpsnuTKx3bXjl2/WC0SYvUDMBG0z7BKQPsejBQwyn3j5wE/JpPmP/q+ADOPxIwykthdlmhnNW4u57izt8TeToGbL2XYvZHi5VszxGkIZ5PHV+BxHR+RKerfhBCrlt1kkWfYudHj1u4O9g8OsH9wG2mewFcMqQWUEfAlY23T9QofOA9/2QTGgUJbBqjKDG3bYj6fIU4MtBGwoUQQylUMY4koVcgKOxmjL4EnZLLiqb8B7KsQrxxUuLO/g6OjIxweHqKsYmSlRpxppIW5AEYWvu9B+B48z7sEPiSdVz/NAotSihXQ7XSeWKRJhCzLVopig7wMYQMFbV3LHvyLs3vdw6/JJNlTKdVVhVob2CBEGEUwxqzMd8cnsCHCIMR67XVdAr+ioG7P1rt1OQnheXC3R2u9Ajq5fO31fwEfu7v8c5JmCOL4PI4TFEUxlWU1VVU91XU9NU0zVVWFppm5OKVpNrl1SZJMGxqSJEEUxXdJJvmTvUWP2337T1M3Q9t2w2KxfLZYLIe+X7h86Lp+7Lp+2NraGrquG6qqGuu6Huq6flZV9VBV9V91XaMoymPSWfGHEQJWePCf39KL6gdSQfSqDcNjIdVdIvqAmd9i5teZ+T1mfpeZ7zHzl8x8zMzvM/OD9dv3ETO/ycxvEPE7RPQZEb32L2ppXhrhpiV7AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/d3aded5ad4442e04839ed8af7dfc096e/8ac56/4b1983751332a2a74df37928dd4800fdf148ee5e7fcdb4331f9ca18fa0efe125.webp 240w,
/static/d3aded5ad4442e04839ed8af7dfc096e/d3be9/4b1983751332a2a74df37928dd4800fdf148ee5e7fcdb4331f9ca18fa0efe125.webp 480w,
/static/d3aded5ad4442e04839ed8af7dfc096e/b0a15/4b1983751332a2a74df37928dd4800fdf148ee5e7fcdb4331f9ca18fa0efe125.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/d3aded5ad4442e04839ed8af7dfc096e/8ff5a/4b1983751332a2a74df37928dd4800fdf148ee5e7fcdb4331f9ca18fa0efe125.png 240w,
/static/d3aded5ad4442e04839ed8af7dfc096e/e85cb/4b1983751332a2a74df37928dd4800fdf148ee5e7fcdb4331f9ca18fa0efe125.png 480w,
/static/d3aded5ad4442e04839ed8af7dfc096e/0b533/4b1983751332a2a74df37928dd4800fdf148ee5e7fcdb4331f9ca18fa0efe125.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/d3aded5ad4442e04839ed8af7dfc096e/0b533/4b1983751332a2a74df37928dd4800fdf148ee5e7fcdb4331f9ca18fa0efe125.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Now let&apos;s start to embed our web server. We will need some nuget packages&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The first NuGet we will need it&apos;s the Microsoft.Owin.Hosting&lt;/strong&gt;, which allow us to have a basci OWIN hosting in our application&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 60.83333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAAC10lEQVQoz3WRX2/aVhjG/S3yXVaJZEqUtaI2V4m03q/3+yi72v2ipZs6tRdVkzZTShIYSQGnGBvb2PgftsEOmNrGNqTYPNNh6jap28VP73veo/Oc5zmHuqpdn7w6veTq193ee1Y+v/yjc3PTFntczxDe1fib12et5tkFe3nDyt1mp68KitNWDF/tG35Dtyd1yw06ljut/vhOkb4/bv1APfn2yfCnX89x9LyKFyctnFZ5vLngcXbF4+VbFm+uRLytiTi5FPB7o49G10ZLHKEhjHHKjnHW8cGZESTNAffh9jfqwYOvZE2zoGnDlWm6uT0c574XFB9uu0W93syvG+28Vnufcx25uG23i3azVQwttzBMOx+Ybu560yKdJ/dxnOCiwf5CVRiGl2UNzVa3MAwbnjdBEETgeAVdQYMgmhB6BkR5CFEyIcoWOE7CebWOJstDkAbw/elqGkR4XuVfUQ8fPWIdZ4QgCPMoSvDxY7xhuVzi/n6J5XKx6UldLBZYfbqHPQ5Q6+iQdA9xNF/PZtFqNovQl8Rn1O72thgEIcJwXpAhgQgmSYo0/RIi6ox8sF0FtuMTI/8Iqsox9XBvr+n7EyKS/1uQHM6y7AtB4tZxXLRbLCRJ2QjGcboKwxiGYRxR2zs7HHGYJIsijlMQwnD+v4LEoef5YNkORLEPXbfWqqqvRiMfhmE+o7ZLpe5goEPTzELTTKiqvvmYNM3+MzK5ZDYLMR7fYeR6cJzx2nHGq8lkBss0j6lvvt7pCLwInu/liqKtFWVQeN6kSNN0TciybJ0kCVkXWZZtiOOkCMP5OoqSDfN59okkk5TBEVUqlWxNVaAPVBL778h/9Qk+/zyZkXf6XKNovunJvmXoa6Uvoyf2X1JbW1uNvd3dOYGm6enh4aF4cHCglsuPF5VKxS+XH/sMUxnSNOMyTMViGMZmaMYul8tTmqbv9vf33affPb1TVH0ly/2f/wRA5C6V4xHAgwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/b92bfecb4f16d853509f4998842c6895/8ac56/f72da0f6f629b439539a1f54f2785eeb95c16c6d54af194d050a2e83e0dd67b0.webp 240w,
/static/b92bfecb4f16d853509f4998842c6895/d3be9/f72da0f6f629b439539a1f54f2785eeb95c16c6d54af194d050a2e83e0dd67b0.webp 480w,
/static/b92bfecb4f16d853509f4998842c6895/b0a15/f72da0f6f629b439539a1f54f2785eeb95c16c6d54af194d050a2e83e0dd67b0.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/b92bfecb4f16d853509f4998842c6895/8ff5a/f72da0f6f629b439539a1f54f2785eeb95c16c6d54af194d050a2e83e0dd67b0.png 240w,
/static/b92bfecb4f16d853509f4998842c6895/e85cb/f72da0f6f629b439539a1f54f2785eeb95c16c6d54af194d050a2e83e0dd67b0.png 480w,
/static/b92bfecb4f16d853509f4998842c6895/0b533/f72da0f6f629b439539a1f54f2785eeb95c16c6d54af194d050a2e83e0dd67b0.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/b92bfecb4f16d853509f4998842c6895/0b533/f72da0f6f629b439539a1f54f2785eeb95c16c6d54af194d050a2e83e0dd67b0.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Notice that the package is a pre-release version, so we should change the option in the drop down &quot;Stable Only&quot; to &quot;Include Prerelease&quot;. To create our web application host, we just need to modify out internal start&amp;nbsp;and call the method WebApplication.Start, indating the listen url as parameter (&lt;a href=&quot;http://localhost:12345&quot;&gt;http://localhost:12345&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 69.58333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAADCElEQVQ4y42SW29UZRSG372/wz5275nOzJ6ZdmxN6UCHjvQQE/kLjUELPWDPITHGX6Cp/gTv9QdwoQlGjRix1RgEDB5SKVxwIRlDaRwrRYFoCmS+6WtmoDemIVy8WStZ+Z68610fNjbrp2u3ttZqm3+u39jYurbxx19r9e3752u3tr6/Wb9zbvv+g0t3d8zK77fvXan//eDH93/Yvrb89da37126c/Wd1fr1Xzb/vbzz0Hz6zyNevX1v510sv/3W3bFjr3J6apITx8c5dXKGM3MLXFg6xdffeJOz84ucX1ji9GuzPDExzbFjx/ny+CTHJ09y7JUTHJ+Y4szsHBeXTnFufvEsKpXDvwGgK9BwgaZjoxm4yrjKNq62DYA9Nfepe/2jFgPABVQqlXVLu/T8wMSBxygMGAUeU6HLYi5mLuUxl/aZdAYMfYfZlN+WbQvaQlAIsSuEaIjH/QoOHTy0DqkolTKwLEZRxDCVYTbJs1jsouv5hGXziYP9tAug8aT/CENDw79CKCqlm1JYTPuaxUKepVKprd7eHrqO86zAMyiXD16B1I8dApRKMwxDBkHAOI7o+x4ty2o/3qtPAX6MkeGRG7AlldZNaVvMhIqxazPlSUaOxThwmS8U2NnhMdPhMcnnqbX+P3QPuILR0dEabEGlVLPlQDsuk3yBuSRpO3zKqvs5/AR9fQfWoBxKKY3dOoqnqAF6WjAII8apNAPPpSdB7SgCrTxDAlFblhXt2ra9BzyNarV6vZVhoVBsFgsFHni+l8MvVDnQ38cXhwY4emSA1Uo/q5UBjlSrrPQfZrl8hKVSmdlsD5OkZzdJ8o1cLsdMJnsGR186ugFY9Hy/oZQynuuYOIqM72oT+crEoWPSqciEHZHp8H0TBb4JA89oLY0QlhHCNkKIh1LK1j9cxeDgYA1CtlambYGdgWbaV+0DxJ5i4Cpms9n2/BnyPI/uru4PLMf7SUr5M4CvHNdbKXZ1X+wuPfdNKpW+AOAygC8ArFrAZwA+B3ARwFkA5wB8CeBDAN8BWP4P/lxqeXhrxCgAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/9d734997f0029128528d347ce7a74125/8ac56/8546dac228afbdd2dd033cb2bc32c13e4dee6ed39b6e5e027a24bbb9111e9a52.webp 240w,
/static/9d734997f0029128528d347ce7a74125/d3be9/8546dac228afbdd2dd033cb2bc32c13e4dee6ed39b6e5e027a24bbb9111e9a52.webp 480w,
/static/9d734997f0029128528d347ce7a74125/b0a15/8546dac228afbdd2dd033cb2bc32c13e4dee6ed39b6e5e027a24bbb9111e9a52.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/9d734997f0029128528d347ce7a74125/8ff5a/8546dac228afbdd2dd033cb2bc32c13e4dee6ed39b6e5e027a24bbb9111e9a52.png 240w,
/static/9d734997f0029128528d347ce7a74125/e85cb/8546dac228afbdd2dd033cb2bc32c13e4dee6ed39b6e5e027a24bbb9111e9a52.png 480w,
/static/9d734997f0029128528d347ce7a74125/0b533/8546dac228afbdd2dd033cb2bc32c13e4dee6ed39b6e5e027a24bbb9111e9a52.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/9d734997f0029128528d347ce7a74125/0b533/8546dac228afbdd2dd033cb2bc32c13e4dee6ed39b6e5e027a24bbb9111e9a52.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The Start method is a generic method, where we have to tell what is the class responsible to do the initial startup, which in our case it is the WebStartup class. By convention, the method to be called it is named Configuration, receiving the application builder object as an argument&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 72.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAADC0lEQVQ4y42Sz28UdRjGn/nO7PzYnZ3d+bF0d6fdttNluylqPOEF/wfTurTVsAS3W3ooewAaOIhnD9wUI5GYGPVkYuLZGGNiQiixbhV0QaArbSXEWqMNCdCZPmbjFA2K8fDJ93new5P3/ebB7dXV97/t3OguX+u2252VpXZn5fI3nZWVu7/dXz2/tNU5e/HXG699sbn85qXNKzfXfl7s3tn86vqPd9vrG/e+Xtv4/fvvbq7+tLaxtbj+y1bncvvq6zj/1rmL4+MvcHJqmnOHpznXbHD+WIv1ep0zjVd4tDnD2ZkZNhsN1uuHeehQnS9Nv8zJg1Os1WocH59grXaQk5NTnJh48W0cOdL4HAABPPQNhP25TFjeW4mKxUJk23YkZDmSZSXUNDUCED5GFHM/zvgAp0+dWgYkJk0zesY3+Wx1hAcOPM/9+5/j00/tYyaToed5TCgKJSEoyzKFEH9nRwixHes30Gq1LvXSFVUNC1aCA8U+Fn2fQpJomilaVprJZJKKojDe4nF2AGzH+l00m81PIWSqhhEWMhr3pFW6dpb5QpGu59H1ctzTl6f072G77AZ+gvn5+S97Jmllwqxp0DYkZpIavWyafZ7FgYLDfM6mJOH/bHgBs83ZzyArVFNmqGsasymNRkLQ0hW6aYOOqdHUFUqQiEc8MfA9nDxxsg0IaqYV7Z6V0HWqtkE9nyJ0EAKEjD+1CiIRa+0fJ3+MM6+e6fZM2nYiv+gzl8uxEpRYDkqsjgasjlUZlAMOBcMcGB5icXCI+YES+4cG6Zf66Tjujut6267r0XGcd9A61lqEJGg6Xug6DrPZLIeLOZbyOQZ+nqOVCsfG9rE6WmUwspf+YJn9gyMcKVcYDAd0bGfHcZxt23aYTqfP4vjxE0u9f1GM5MO/iipFkpAjTdcjIUQkSYgLLiIhSZGmJiJZiEhV1ahXeEVRHvT6CeBDLCwsdHqBupVhKu5br4P475o8iQuYOzr3EYR8R01bi4osrgO4DeAqgGsAev5K/P4AoBPPu/HsVjxbBrAO4NwfbKx5S2qWuKoAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/8ddc2e1fde12fb2693b7c1bebd9fc2d2/8ac56/84c122c7ea93c9759946894afa9f50a952aade724c965378c88c734bda674f77.webp 240w,
/static/8ddc2e1fde12fb2693b7c1bebd9fc2d2/d3be9/84c122c7ea93c9759946894afa9f50a952aade724c965378c88c734bda674f77.webp 480w,
/static/8ddc2e1fde12fb2693b7c1bebd9fc2d2/b0a15/84c122c7ea93c9759946894afa9f50a952aade724c965378c88c734bda674f77.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/8ddc2e1fde12fb2693b7c1bebd9fc2d2/8ff5a/84c122c7ea93c9759946894afa9f50a952aade724c965378c88c734bda674f77.png 240w,
/static/8ddc2e1fde12fb2693b7c1bebd9fc2d2/e85cb/84c122c7ea93c9759946894afa9f50a952aade724c965378c88c734bda674f77.png 480w,
/static/8ddc2e1fde12fb2693b7c1bebd9fc2d2/0b533/84c122c7ea93c9759946894afa9f50a952aade724c965378c88c734bda674f77.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/8ddc2e1fde12fb2693b7c1bebd9fc2d2/0b533/84c122c7ea93c9759946894afa9f50a952aade724c965378c88c734bda674f77.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s try to run our application, hitting F5, to see what happens&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 60.83333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAADHUlEQVQozzVQ224bBRCd9SWO7Th2YjtF4pWqkdMGJ3LTosJH0A/iASSQKAjRiAa1qixRCSpVPPQBcVGoRCtARZAqAbt27F079t4v9tp7a+PdPWhzeRiNZs7MOWeGKJ54kMou7BHRs0Qi+ZwY5qdEIvl7Mpn8cz6V+peInhPRzxFORA2GaC/G0NMYQz8S0VMi2jvD94noE6LEXCu9mAcRYS7OIJ+KIRUnLKTnkV8qoVh+A/l8AdlkDLlcDsTMgagIomUQlUFUAMMUTvaJqE6USP6VWy6hXCofl8sX/CsX3/Svrhb9d9dX/NpqOdiqrPjvXF7xr1eKfm21GGxcXApql8p+9a2Sv5DO+vnCSlAqXnhVLBaxtLS8TRSLH2QW81jM5YJ0OoPN9Uuo3/kAO9ufYef2Lezc/hR3v/ocX2/fwr07X+D7h3U8+u4+Hj96gI8/+hD5Qj7MZNKzbHYBmUz2W4rPpZ5EhLFYzGeIcOPq2+C6LQyGAnhexPAsC4KIo8EQsqJiajkIQuC/RhPz8+mQiGZnJz8kIvqDmFhU+FGzUqngn4MWXjQ6+PughRY3hGRMMVTGENQxJN2ErI9he8fY3d09/9054WPaqNV612+8h43qZrC2dgU337+JNj8Cq3pgVQcd2QKrWFBMF9rEg+O9huO9Qgjg191fsLV1LVxfr86q1U1UKms7xPWGL0RRhyBoAc+rkCQN7EBEpzfEy24fR6KG8cSCY9twnSgcOI5zkk1zAkFQQ0FQZ4Kgon3IfUk8Lz6TZRWjkelPJlOY4wmazSaajQYGR33IogBdVaEoCgzDgOu6p4SuC8uyIUpyKEryTJIVtA87dVI17bfRaBQNzFzXDRzHDQ8HasCK42BkeaFu2oE6tgLTcgLPi3DnJKLZ6dQKBFEKeUE8FkQJrfbhN2Tb9r7neSeKp+oulLENXp+ir5iQDAvm1MHUjs48dXfucGpZiJxJshKcObxLuq7/oGmaqGlaS9e1tmEYmqIoLU3TeU3XZVXVBoaudVRV7bBcr9/psgcsyzVYrjfodNl9rteXuF7f6LIc12i+rP8PAbdxg1sEIToAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/70b0422a1dd03e88065980e9d26db82d/8ac56/f8d0e00cc52e5a7603602ad00480b6561ba3beb43aa08ae27a9ec4c37f466147.webp 240w,
/static/70b0422a1dd03e88065980e9d26db82d/d3be9/f8d0e00cc52e5a7603602ad00480b6561ba3beb43aa08ae27a9ec4c37f466147.webp 480w,
/static/70b0422a1dd03e88065980e9d26db82d/b0a15/f8d0e00cc52e5a7603602ad00480b6561ba3beb43aa08ae27a9ec4c37f466147.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/70b0422a1dd03e88065980e9d26db82d/8ff5a/f8d0e00cc52e5a7603602ad00480b6561ba3beb43aa08ae27a9ec4c37f466147.png 240w,
/static/70b0422a1dd03e88065980e9d26db82d/e85cb/f8d0e00cc52e5a7603602ad00480b6561ba3beb43aa08ae27a9ec4c37f466147.png 480w,
/static/70b0422a1dd03e88065980e9d26db82d/0b533/f8d0e00cc52e5a7603602ad00480b6561ba3beb43aa08ae27a9ec4c37f466147.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/70b0422a1dd03e88065980e9d26db82d/0b533/f8d0e00cc52e5a7603602ad00480b6561ba3beb43aa08ae27a9ec4c37f466147.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;We are getting an exception, telling us that the HTTP Listener is not found.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Could not load file or assembly &apos;Microsoft.Owin.Host.HttpListener&apos; or one of its dependencies. The system cannot find the file specified.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Until now, what we did was just adding the hosting capabilies to our application. We need to specify the OWIN component that should listen for&amp;nbsp;and serve HTTP requests. &lt;strong&gt;Let&apos;s add the Microsoft.Owin.Host.HttpListener NuGet, which is the OWIN component that uses the Microsoft Windows HTTP protocol stack&lt;/strong&gt; &lt;strong&gt;(http.sys)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 60.83333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAAC0UlEQVQoz32Qy2/TWBjF/Q+xQmIxG2igGiGIQBVC0Fm0eYBES+c/mfXshgVoRlPErjNAoagPhzShIm+/0ms7jROnafyK7ThJbR90TZFGw2gWR/eec3V/+s7HXLqcenXp8o3W1dTdrYWFW+xCKl24fiNdWLx5v/rj0uOD1OLSwe2lTDH9YG3/yrW7n69cu8P9sHivkkr/9PF6+kH99v0Mm0o/LP/24mVTFPhfmL+2S0dbb0vY2i7jA9vCbpEHWxbxoVDH1rsy9koitvdreLdfw2H1GA1JB0dOUWz2sFMbYK95ClYwwalDsOXq30y12uBqNR6tVnuuyN1Q10ehLHfDnR022tsrh7u7pfD9ezYsFCph8eNhVDgoRm1JiVqiHDalk0hQ9FDtGzPb9lBqqq+YWq2h8AIBkU+iszMTtj1Gv38GXlCgdAaQFR2KqkNWdRC5l3hBIGALh6jWWhAlEvf7w9C2XSiEvGE6arcyGllwHC+0rDFM04HrepjPZ5hOg+90Pp/hRDewXyFotPv0H2zbPad/j4/Ja0aRO/x47MMw7IjCqBzHhe/738nzfQRBAK03wFGVQ1fT0esN4uHQSICCIG4yZ0OjeAEKvwHHYxeTyeQ/odPpFFpXw6fyEbiWgF5/EBuGnQAJkZ8zmqbXPS+go0d0Ulrh/4A0p3tWOxoU5YQ2i2ll07QhidIfjChIdVnugBA1IkSBqnaTyv8E/vtO3y2LKtl5bJpOAuSF9u8M1+LLlUodzSYfcpwYSxKJLduJfd+PPM+LqVzXjS58ktn2OB6NLFo1orIsd+44PgVuMgLPyZLAJTWjCDg/jxAEc9A10DMIZvC8SeJ9f3qRfZXvB5hMZhjoOo7bIhr1+jMmm8m8zmUz8urKqpHNZq2VlVUvl8uPNjZ+5vL5R6f5/KPh+vpTaePpBv/kyZryLctlcyb1a2vrneXlZXnzz82Zpmm/fgFY4CvHJyieIwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/07769e0364c825b9c9e37cc366b90be8/8ac56/73097b777f7eb35bda84337b9fd4a33a0bceaa16963745504997af246a3c32e5.webp 240w,
/static/07769e0364c825b9c9e37cc366b90be8/d3be9/73097b777f7eb35bda84337b9fd4a33a0bceaa16963745504997af246a3c32e5.webp 480w,
/static/07769e0364c825b9c9e37cc366b90be8/b0a15/73097b777f7eb35bda84337b9fd4a33a0bceaa16963745504997af246a3c32e5.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/07769e0364c825b9c9e37cc366b90be8/8ff5a/73097b777f7eb35bda84337b9fd4a33a0bceaa16963745504997af246a3c32e5.png 240w,
/static/07769e0364c825b9c9e37cc366b90be8/e85cb/73097b777f7eb35bda84337b9fd4a33a0bceaa16963745504997af246a3c32e5.png 480w,
/static/07769e0364c825b9c9e37cc366b90be8/0b533/73097b777f7eb35bda84337b9fd4a33a0bceaa16963745504997af246a3c32e5.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/07769e0364c825b9c9e37cc366b90be8/0b533/73097b777f7eb35bda84337b9fd4a33a0bceaa16963745504997af246a3c32e5.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s hit F5 again and see what happens&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 41.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABhklEQVQoz53OOy9DcRjH8d+/9EgXCT2HHiYDK9FWXSpK1VEh8QbEZKBtIryN7gwMJAaXlKGhBpdq3aJSmojGbai4JI1oonFvHzlxSKiEGD55hufJNw9mvT7vlHctOjSxvD7uCZ5ML4QO55Yi4flAdGdlNxYMRi62/eGLRd/Gsd+/F9sIn91u757cbB2c34UCp8kd31EyshyNhzzrB6fuySU3SkrLjlrsnVRpaiFjbSuZzHYqN1hIX91MFVWNVG5oIH2NlfTVVjLW2chUL1GtxU7mpjay2NrJKnWQJEnk7O0hkc8fRq5WCOoKBQLwrM5mqRwuO8UA2Sv+JgXgqbu7S24MQysWRXieJ2VBXzBGKpXqB1mfwFhao9G8uJx98m5MDu4JwnuQMUYZ0d+lOY57cTp65eAk8gp1+wKvJeX99A9S32aGjyBjbAZCUfFmgSD857NPHMe9ulwOeY7IwVVRp7sHcM0YSwB4BBAHkFBcyjsAVwDuADwoM6HcPajV6uTgQD+Jojj6BpJT3qUnEjDxAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/cdce0e288a338b8fa757c7e92e9b8608/8ac56/03dcd8da42acf4af32e4f2c5577b047ee6ba50908577382385c16ffdfd354284.webp 240w,
/static/cdce0e288a338b8fa757c7e92e9b8608/d3be9/03dcd8da42acf4af32e4f2c5577b047ee6ba50908577382385c16ffdfd354284.webp 480w,
/static/cdce0e288a338b8fa757c7e92e9b8608/b0a15/03dcd8da42acf4af32e4f2c5577b047ee6ba50908577382385c16ffdfd354284.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/cdce0e288a338b8fa757c7e92e9b8608/8ff5a/03dcd8da42acf4af32e4f2c5577b047ee6ba50908577382385c16ffdfd354284.png 240w,
/static/cdce0e288a338b8fa757c7e92e9b8608/e85cb/03dcd8da42acf4af32e4f2c5577b047ee6ba50908577382385c16ffdfd354284.png 480w,
/static/cdce0e288a338b8fa757c7e92e9b8608/0b533/03dcd8da42acf4af32e4f2c5577b047ee6ba50908577382385c16ffdfd354284.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/cdce0e288a338b8fa757c7e92e9b8608/0b533/03dcd8da42acf4af32e4f2c5577b047ee6ba50908577382385c16ffdfd354284.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;As you can see nothing happens, and the exception disapears. &lt;strong&gt;However I want to have a quick way to check if the hosting is correct. To do this, we will add another NuGet Microsoft.Owin.Diagnostics&lt;/strong&gt;, which will allows to have a quick diagnostics&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 57.91666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAACzUlEQVQoz22Sy08bVxTGZ5ESvEXi3+IfaAE/lALdV1120TagbLKKomQRKRXtIolUKZEaUIzjjB+DsT2Ojcedh8f4FT+wsT2vy4Dv9VddAxJ5LD6d71yd+9M5517h4aMXud8fvnj9+Pm+/PjP/cTT3WjyyV+xvWev0tLLvY+13Tf5xO6bfPz5P5nU3//m069FLfX2sJZ8e2jGo/mGGC203mWNM/FD6rC8s73zsxCNy0hKZeQKJgrHdRSVBuSSATFdRLagI5NXIWUryJcMlNU6jHof9fYQmtlGrdlDrdmHRRjexRK4c+e7bUHXT6AoxqVpNlir1aW93hmNxVL04EBi0QOJ7e2LVEzINJst0fexOJNlhRZLCi0pOlW0E1pvdSmdsoujTBaLi4v3hXJZg6qabDAYYTSy5mq3++j2ztDrj+bi/lNniG5/jE53iGT6CIl0DqpRR7XWhO/TqSRlroAcYFkuG48djEY2JhMbvn8+1/k5mesmv/DP4XkEObWDnNbFcOzBtpzZLeAfwnhs867YTXc89zzvmyKEwLYdFEsKKhUd9XoL/f5w5vvTK+DduzvCNegrIL98E297x3GglCsoFo/RancxmTgzSnF53eEvgm17sG2PXkde8Bnwyw5d10WlokGWi9C0KjTNmDWbn6aimEQgENgWDN2EqhpU103oWhX8cW7DCPE+8xx4ejrko6LXO0Wn05tZlnuZSkkIBBZ/E45LChRFnRpGjWlalQ0GZ4wQwjzPo57nMcdxmOu6PGceIZT7ycRmk4kz13hsUzaDL0lHWFhY+FWolEtoNhog5AKE+HCcq7H5Li3LhWU58zPu+Q/ga7ntB6dDNE5MxN/HsLy8/EDY2tzMhUIhMRgMlVdX17T19aBy796Pma2tnz6Ew5GPkXCksPrDajUSicgbG5uptbX1/4LB0DGv4Xc2NjbFcDiUWllZ6SwtLX3/PzviIyoRLpsCAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/83377750e3b21650699d98dce38c2dee/8ac56/5051103f09e5fe807d7b638a455a24b9343d4e335178d060bbb5535eb85bb81c.webp 240w,
/static/83377750e3b21650699d98dce38c2dee/d3be9/5051103f09e5fe807d7b638a455a24b9343d4e335178d060bbb5535eb85bb81c.webp 480w,
/static/83377750e3b21650699d98dce38c2dee/b0a15/5051103f09e5fe807d7b638a455a24b9343d4e335178d060bbb5535eb85bb81c.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/83377750e3b21650699d98dce38c2dee/8ff5a/5051103f09e5fe807d7b638a455a24b9343d4e335178d060bbb5535eb85bb81c.png 240w,
/static/83377750e3b21650699d98dce38c2dee/e85cb/5051103f09e5fe807d7b638a455a24b9343d4e335178d060bbb5535eb85bb81c.png 480w,
/static/83377750e3b21650699d98dce38c2dee/0b533/5051103f09e5fe807d7b638a455a24b9343d4e335178d060bbb5535eb85bb81c.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/83377750e3b21650699d98dce38c2dee/0b533/5051103f09e5fe807d7b638a455a24b9343d4e335178d060bbb5535eb85bb81c.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Next, we need to tell to our web application to use the diagnostics capabilities, calling the method UseTestPage() during the configuration phase&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 62.083333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAACeElEQVQoz42SS08TcRTF7/yn0/90Oq8+CNhSQUNj+22kBSrpA0z8Cn4AXbkycSFqqSRCjcaVW0OCCdEQMYZEwYZSocU6jRQa40rs45ipFasx6uKXe3IWJ/eeXLKs2lqxtFsvlCqVQqmys1ksF63aQemldbx3ZbXx7upqY+/as6Nq2TrasQ4a1XK1XqvVP78vfzjYL5QqllX/VNyvHb6tfmwcbm3v3qLl5ZVaLB5HcuYiLs2mkc7MYHxiChemk0ilM0im0kimM0hlZpFMzyAxnUJsIoHx+CTOxyYRm5hCYjqJZGYW8clElrLZ3AsiAhE13QK1GVFbkqQ2l11tgYltJ+dtIvoXx72Mx5Sbz61wlwLFMFs+XcEpg8OeAb+J0aAfZ4cHIHMOQWAQmQhmIzAwdkKHMdbs+ozdo7mbc08lWYGkqC2HKEJ1cchcgmm6oekcTk4ggUCsR7/+vlXHvq6nr1N+Kf+aSU64NMNeHUx0QDVUGEET6pAKQWMQFRHMYBBUBkFhYLo9hT8F5mjh7sKaU3ZBM70t23SKAnxuBxSRYLoV+H0D8JgmDMMLWfXCwVWYugmH6PgRiL7AB3Tn9p0nDi5DVrWW3+eH1+NFIBDAuUgEkUgU0WgU4XAYw6FQl1AohNMjIxgdPYNgMIhgcLjj9w80PR4PDMNYsDd8LnIZiuFpeW3TNDE4OISxsXCXSCTSDdF1HbpudDEMG7M3jY6m6U1N06Bp2g1aWlzcYBIH1/SvDlG0z/6d9n94X046zOfvbwtMRJefnUAQhF/o6+tvPKRsdv4RY2yfiNaI6A0RbRHROhHZD79JREUi2uj5r3q60NPrfewQ0eVvkqROqx2eBWwAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/3bd026528e09c9e56cd10c915d2282f3/8ac56/8502e137aa9792fa16dd7918e7ae7978e1680622b528b5c9041fc43fa1155582.webp 240w,
/static/3bd026528e09c9e56cd10c915d2282f3/d3be9/8502e137aa9792fa16dd7918e7ae7978e1680622b528b5c9041fc43fa1155582.webp 480w,
/static/3bd026528e09c9e56cd10c915d2282f3/b0a15/8502e137aa9792fa16dd7918e7ae7978e1680622b528b5c9041fc43fa1155582.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/3bd026528e09c9e56cd10c915d2282f3/8ff5a/8502e137aa9792fa16dd7918e7ae7978e1680622b528b5c9041fc43fa1155582.png 240w,
/static/3bd026528e09c9e56cd10c915d2282f3/e85cb/8502e137aa9792fa16dd7918e7ae7978e1680622b528b5c9041fc43fa1155582.png 480w,
/static/3bd026528e09c9e56cd10c915d2282f3/0b533/8502e137aa9792fa16dd7918e7ae7978e1680622b528b5c9041fc43fa1155582.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/3bd026528e09c9e56cd10c915d2282f3/0b533/8502e137aa9792fa16dd7918e7ae7978e1680622b528b5c9041fc43fa1155582.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s hit F5 again, and open a browser and type our url on the address bar&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 70%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAADB0lEQVQ4y5WPy08TURTGL12BEGFhWRH+ADbsXBrjq4IIBSMSRURNFBdifERNjDFG12o0USMEqjWKoQlYwHc0vkF5iNCCOsh0WuZO22mhMwMtzvR+Zko1EV3gTX4533nc755LeN5/ye8X+zze8edOp/Ndc1PTu5s3HW8drS1DjtaWgdvOWx9drvZPbXfvPHW52l91ud3D7vudffc7Ox71dHd5nzx++CIQoA9CIfkbPylcJT5f4HskEoPHM4bi4mIUFBSgsLAQVusKWK1W5ObmIjMzEzk5OcjOzsayZVmpmJeXB0IIzpw5jRllDnJUwZQYaiYB/9Swps3B1d7+Iysr0yCE/CK5iMX1lD554rhxz9WRuN7swJVrTZfJhF96O6MlcKChwRxARkYGLBZLKv7G8jfmjDm/q66W5S5frpuaENJCuO++zzF1Fo2Nh5Lp4n9RX1/H8vPz9fQyDtLX2zsalEQcOdyYXLtmFbZUboK9vAR2ewnKK22oqLLBno4VlTaU2zdgc8V6lJfZULO1CvU7axghJGVosVhaSWAqMNL/eQJ7D5xKrlxtx2rbNqwr3Y6y6t3YUr8fG6vrsMa+A7bqOpTU7EZZ7V5U7NqHqtoG1Ow5CPuOfaiq3q4XFRWZG3cSTVMGHr/+gI4Hz4w290tcuObGpRtd6B/6gm+cAM8Yj2HPJEbHffB+9WOcC4DjJQx7ObwZGEL/qJdJ1K8fO3rINLxFNFUdiESDCAcDhjITRlQWEaICYtMhqDEZmhLBrBKBpsjQzDwWhjqTZjqMaFhkANPPnztrGjqJqqqeeDyORGI+GU/MQ9cNxOMJmHophy0Evbu7B6Wlm9uIqiojhqGbxeQfI6ZibCkwlkzqs7NzCMvTt4miKIO6njLUzZZpzBgzGEs98E/MHlvQRvrOvCzL8HjHWoimqULacEkbLf4B2EIejUbBTUy6STAYvCNJkkBFcZBS8T2lYi8VxVeU0l5K6SCl9JMkSV9NKKVffD7fkCAIAs/zH3me7xEEwcvzfB/Hcf0jo56LPwFaAQ6GPQwFrQAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/270b4f6b97f5cafd42695751bc8ee084/8ac56/1cec5ac84c4e06ae3f04eeb94e691014312b260c0c1491c335a481b966227a65.webp 240w,
/static/270b4f6b97f5cafd42695751bc8ee084/d3be9/1cec5ac84c4e06ae3f04eeb94e691014312b260c0c1491c335a481b966227a65.webp 480w,
/static/270b4f6b97f5cafd42695751bc8ee084/b0a15/1cec5ac84c4e06ae3f04eeb94e691014312b260c0c1491c335a481b966227a65.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/270b4f6b97f5cafd42695751bc8ee084/8ff5a/1cec5ac84c4e06ae3f04eeb94e691014312b260c0c1491c335a481b966227a65.png 240w,
/static/270b4f6b97f5cafd42695751bc8ee084/e85cb/1cec5ac84c4e06ae3f04eeb94e691014312b260c0c1491c335a481b966227a65.png 480w,
/static/270b4f6b97f5cafd42695751bc8ee084/0b533/1cec5ac84c4e06ae3f04eeb94e691014312b260c0c1491c335a481b966227a65.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/270b4f6b97f5cafd42695751bc8ee084/0b533/1cec5ac84c4e06ae3f04eeb94e691014312b260c0c1491c335a481b966227a65.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Cool! Now we have an http listener which serves always this simple test page, greeting &quot;Welcome to Katana&quot;. &lt;strong&gt;Now we need to add another NugGt, Microsoft.Owin.StaticFiles, which will allow us to serve our static files (Html, CSS, Javascript files, etc.)&lt;/strong&gt;. For some reason, this nuget is not being returned in the search result when using the window &quot;Manage NuGet Package&quot;. So, we will have to use the Package Manager Console and use the command&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Install-Package Microsoft.Owin.StaticFiles -Version 0.20-alpha-20220-88 -Pre&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 38.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB1UlEQVQozz2PTWtTQRSG7y9zI4ja1FRC01ZDW1tcCm5culXaarooUhQR/A2i1kohCYltgmgSk7nzeeZ+36TBvTT3emQGbxYP533nnJnzjvPs4NC7fmd1WLm/e7Fc3ewvrW72bqysD29Xaj/K93Zby+sPOqXqVre8sdMqb+w0lqpbnVuV2vfS2nartLZ9frf28OzazZXRoydPw19E7DtfBhHWPxN80wR83Q7xqOHjcTvCl6ccn38Y4d5HggcnFPc+Eax/FfiqGSx4cUKxfsrx8Ezju06IzaE+djzPx/5gOGeMZVLKnHNuoZTmo9E4G4/HGSHE+Mx1XYsQIldSmvOMMZ4B6Ks0naLnBe+dIIyQuDTnQiLjwuIyvtBMCDQ9BWArZQKFVOhSjlIBBmH0N4qTeZxM0KXyrRNFMVLGM3PZDCrQC4ynjFsdJylOL2eWyfTSkk6mmKQTw5V5sD8gR0XCOWU8dykzSe03zBKXskxIlRGXmoW5Am29VJB5fpDFSVrwJ0mnOCZ835nNfmMYxTZBFCcWowtMgkIX/WLGJCxSmuS+H9UdPwgbUkFLgR4o0D2poKFAN6WCCwX6XCroKtBtBfrn/2owM12poC0VfJMKeqC9EaX88T8+SQ8EQlEzwAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/51fa71d626cd2ce5316cd62ebf0d6b9f/8ac56/2ffdeedfe48935d153af82fae3c1e9dc207dbb8f60bd9aba151a43f0c59e27ad.webp 240w,
/static/51fa71d626cd2ce5316cd62ebf0d6b9f/d3be9/2ffdeedfe48935d153af82fae3c1e9dc207dbb8f60bd9aba151a43f0c59e27ad.webp 480w,
/static/51fa71d626cd2ce5316cd62ebf0d6b9f/b0a15/2ffdeedfe48935d153af82fae3c1e9dc207dbb8f60bd9aba151a43f0c59e27ad.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/51fa71d626cd2ce5316cd62ebf0d6b9f/8ff5a/2ffdeedfe48935d153af82fae3c1e9dc207dbb8f60bd9aba151a43f0c59e27ad.png 240w,
/static/51fa71d626cd2ce5316cd62ebf0d6b9f/e85cb/2ffdeedfe48935d153af82fae3c1e9dc207dbb8f60bd9aba151a43f0c59e27ad.png 480w,
/static/51fa71d626cd2ce5316cd62ebf0d6b9f/0b533/2ffdeedfe48935d153af82fae3c1e9dc207dbb8f60bd9aba151a43f0c59e27ad.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/51fa71d626cd2ce5316cd62ebf0d6b9f/0b533/2ffdeedfe48935d153af82fae3c1e9dc207dbb8f60bd9aba151a43f0c59e27ad.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now we need to configure our static files component to tell the path where the static files are. In my case I choose to create a folder webdir to be the static files container, and it will be located in the same directory&amp;nbsp;of the executing assembly&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 58.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAACf0lEQVQoz22Sz0tUURTHz73vvZl5P+5zxnlvflgz2IARBC00LYt+6owz42g/Vm1a2qI2gutAaNnfEETbqG2LEEEUMwXDRtTJdAwNIQiENum8+cZ9zsQkLT6cH5z7veece2lu8dOHmYXll1Nzi69XViszs1sHb5/P7E89m95//2J+d3Zza+djeaM6X97YmS5/qb6aX1pZWNv8tlaubL9ZrVSnpd3e+/Hu56/Duc/rX8coVxrF8MgoioU8ctksRkrDuH9vFHfvjCBfKGKoUEQuX8RAdggDgzncvD2IazduITuUR75YQmG49Lfmcv/Vp0TEQUSHKlGNEXkBolpQoRqRj9fCyVythd9EJHUmSbfDUFXVUxQNVljAToYRbNdBIQZuKuCCgxsc3GqgcHD+D3XO+VHDH6egsMEY84KaglibDidsIJFwEE8m4MYciPYoQm0RWJEwRJtAo5NW6kR01PDHKGDZYHJcxqCpCgxdh2WaMA0TlmXBMEwY5rEVQkDXdQSDQSiK8j/BcQqYAqqiyD1A1TRYwoZpWr6YPCzzjHNfgHMmp/E50aU/MmNs0hfsSCY9NxbDqWQCF7pSuNTbjf7+K+jt68P5c10YuH4Rj8YeoqenG6lUCpnMGWQyGaTTaXR2dtbT6fRRLBaD4zhPKGAJeXuteWvYDqDrbAdOp1KyAIl4HElHoCMegeu6iEajkIelb9u2jOu2bfsjM8Ye+x0yxg7lLkKhkOe4rue4Tj0SiTTxIu1O3RKi+V3qLbbpN7/NhP8ocn5N0/w9taKq6rFtxP954ZNMUMC0dnU9tMQ53yOiLSLaIKIdIvpORLtEtN6IKy2+rKk2kPllIjogogd/AAAmN5wskkwLAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/eee7e0511445d4284e3623146579dd18/8ac56/c6bc741cab3099cdf2e114b592d7af531ff75bfd77a2657ed4adfce103b310de.webp 240w,
/static/eee7e0511445d4284e3623146579dd18/d3be9/c6bc741cab3099cdf2e114b592d7af531ff75bfd77a2657ed4adfce103b310de.webp 480w,
/static/eee7e0511445d4284e3623146579dd18/b0a15/c6bc741cab3099cdf2e114b592d7af531ff75bfd77a2657ed4adfce103b310de.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/eee7e0511445d4284e3623146579dd18/8ff5a/c6bc741cab3099cdf2e114b592d7af531ff75bfd77a2657ed4adfce103b310de.png 240w,
/static/eee7e0511445d4284e3623146579dd18/e85cb/c6bc741cab3099cdf2e114b592d7af531ff75bfd77a2657ed4adfce103b310de.png 480w,
/static/eee7e0511445d4284e3623146579dd18/0b533/c6bc741cab3099cdf2e114b592d7af531ff75bfd77a2657ed4adfce103b310de.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/eee7e0511445d4284e3623146579dd18/0b533/c6bc741cab3099cdf2e114b592d7af531ff75bfd77a2657ed4adfce103b310de.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s add an Index.html file to webdir folder and try to navigate to this page in the browser (do not forget to mark this file to be added to the output directory)&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 113.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAXCAYAAAALHW+jAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFDElEQVQ4y3WUW2/URhiGDVwg0V/AHb+plxU3FarU002lCimFlgIhJ6AFqaKlB0gVVYRAgEIp4ZAWCslusodkYc/xendtr7327vp82h3bbzVOQG2hF4/GsjWP5/1mvmHabeHrVkuYa7XFsaExGI9s/dbI1J5EZv8b2NplWP3jcPTLoTW4AUf/PrS032D1T8DRZ2Frc7D1Odjat5Ft3B6I7Y8YQuI6AIyCEf6q9bCQ7+JmQcGNTQVXc11cyyu4tqFggZLvJuPippp8m8/KmM/JuJqTkzlXn1XvM8eOHb/7+Rdf4v7vS/5sukMO32bDo3fq0SeLFXLoSoW8+0uRHJzNk4OzG+GhK2XyzmwhfPvHHDk0Xw4/WGyE71/fCj9cZIOxu028dyk1zTAM85hhGIyNHQ1BRvCNQax1OzDVbuzrPdg9Oe4JzdhSZRBLizW1B6kjxaGjxwiHAPFjkICEro2+JM4ze/fu/ZMKJydniGk5aLbakBUVcleB2JEgKz30BxoM04ZuWgnBiMALhnC9AK4fxJ4fEE03UNtq3GJ27dqVpcLx8cnQcby4Uisjm8sis55BOp1GJpNBajWFTkeCJEnoSBJc14XjuNuj68ae5xHLspHfeLHA7Nv31hIVTkzMEBLGsdJT0Ww2US6XUa3VoRsGDNOE5wfwd3Bc75/ErucT3bDwbGXtK+bAgQOl/fv34+LFnyJEIWxdhdDcAlsrQxZ5kMBFPPIQBg6iofsmYow84jsW1tfz52gN1+gKZyanwvki8PGvHj69qWByScG5VIyZpxGOPopw5FGIzx6S1zjykMSH74fk7BMfT9dfzDO7d++uUOHJk6eitgGkGjaWN3ks5xq4t8ZijTWwWtexxtnIC/6biHNCQAq8jZV0/jtmz549z6jwxImJEIjhWxp4rg6uXgZXr6DN1qCILThGH/HIRTx8jRjEI4FjYmUlPU2F2ZfCKIqh6xo6soBapYJafQuK2kMwHMLz/WQT3P+wvSkeMU0bhULpAhUWtyNPhI4fguuoaEhdvKiyKBZLYFkOsqyATrBtB5b1GrFtO8S2XRSL1UtU+OSlUO5ZcaHSQr3ZRUscoNWWwLI8avUWeEGB8CZEJeb5LqlWOaRS2XEq3EgO9qmpUNd0FJ8/R5Ojq5IhSzLUXh9BMITn+f9H7Loe0TQdjUbj8qsanp45G7JCH+vZTTSbbUiSkkTtdnswd+LRWLbtwTT/HdmyHOK6PkRRukOFK8k5nDkbSnIfa2sZbGwUoKoDeF4Ax/FgGFaCqvaTn1iW++qdYVixYVjEMGxwXGuBCp9T4fTMmZAKSsUiyuUKOI5DV+4m/WvbNnzfR6vVQrVaTd7RXvY8utPbvUz7utlsXqCXQzURTp+OfH+EcqmEarWGSrkCURQh8AJM00omUzG9BHRdh+M4yeVAha7rJkJBEK7Q1qtR4dTUmYjGTKXSEDsyFKUHSZLR6cjQdTOpl6YZGAz0nSPk7rB9bGhpBKFzk3nw4FFxefkPFItloqr9qFAohCzLErpznueHnueFjuOGdBXtVjsslUoRzwuRqvYiRVGjXq8Xqao6UhSVJptjbMd/TIvcagmwX9XFQxAESd0o9JlCv9GoNLppGLAsK8E0zWQUBHGJKZfrlzKZDTadzq43m+0Cy24t1Ov1i5VK5Xyj0ZjjOO4ey7LXa7XaDyzL/iyKYobn+ZwgCKvtdntVFMWnPM+vcxx3vVqtnv8baqEOFe4GTSgAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/9da10537453d2acf721be46e4aa300df/8ac56/88bda9c57f12ff8ed27e0f29d28c726f39ced7e43526eaf20a1733c70ed6917b.webp 240w,
/static/9da10537453d2acf721be46e4aa300df/d3be9/88bda9c57f12ff8ed27e0f29d28c726f39ced7e43526eaf20a1733c70ed6917b.webp 480w,
/static/9da10537453d2acf721be46e4aa300df/b0a15/88bda9c57f12ff8ed27e0f29d28c726f39ced7e43526eaf20a1733c70ed6917b.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/9da10537453d2acf721be46e4aa300df/8ff5a/88bda9c57f12ff8ed27e0f29d28c726f39ced7e43526eaf20a1733c70ed6917b.png 240w,
/static/9da10537453d2acf721be46e4aa300df/e85cb/88bda9c57f12ff8ed27e0f29d28c726f39ced7e43526eaf20a1733c70ed6917b.png 480w,
/static/9da10537453d2acf721be46e4aa300df/0b533/88bda9c57f12ff8ed27e0f29d28c726f39ced7e43526eaf20a1733c70ed6917b.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/9da10537453d2acf721be46e4aa300df/0b533/88bda9c57f12ff8ed27e0f29d28c726f39ced7e43526eaf20a1733c70ed6917b.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 58.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAACZElEQVQoz6WSS08TcRTFT6cPpP+ZzrTOTGf6oiEqRAgEYySVFApSHwTcuNC48PERjAuNrtTEuNOVcaUfwY0Ll0JMgJUx8ZG4cgmkkEKRhjAzx8x0MAZ15eKXe+69ycm9uRcrjc2lRnNnob3rLb/6sPX20fz6u8cLja+vPzcXms3Wl5X11sfVRmt5bWP7U6vtLq5t/HjTaO4stdru943N9reVxubi2sb24ur61tL8++UaxibrrJ2b5fUb11iZvcQj05dZrN9kz6k6K2NVViZqrIxPsDZd54W5ixyfOsPq5BTrMzOBrlQnOVabDuLxoZErAEAAu1HASQB7WnfM6QLcRAROBHDRwQGkMGIPiDpAxO0Q1HZDn6uIxOI8bGTdynCRx3pzzBUKVDSZlm0za+mMxTOUJJ2Aj0YgHWqD0ZjBeDzuRSTJlSSJEUk6D0hRRuNxF4iyN6+xt6hzYGCI5XIPi+Us80WdlmVQVZPMZFTqepppNUFNiTLSmcoLt/B1LTAUKc0Z6s+zr5xhsruLqVSKQgiqqkZFTlGWZcpCZiaToa4bTMndTIkuSlL0oOHZwPBQUriWLtO2TAqhUFVVKopCIZKUZUFZUZjW/HXxN7wQX58G4gmquumMjvSxOjrIfKHEQqEQYNs2c7kcc/k8S6VSZ9JwWh9/CyGEJ4RwRZDL9eDKKS3tDg/2e0d7S55pWp5hGJ5hmJ5pmkH00XXDsyzbs+1/QtPMjv96m847/IFzQDsH9O+573Fy33D/Yv/LnG/4HMADAE8APATwAsAzAC8B3A97TwHcBnA37N0Le7cA3Alrvs+Jn4bcMz8uxxDHAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/27a0184ec1fcd55f9054fb6aaf795ee6/8ac56/8b22239eb7fd3a68934fe063eaa8c3585f8395e5841e4be2e2642ff2c3f32bc9.webp 240w,
/static/27a0184ec1fcd55f9054fb6aaf795ee6/d3be9/8b22239eb7fd3a68934fe063eaa8c3585f8395e5841e4be2e2642ff2c3f32bc9.webp 480w,
/static/27a0184ec1fcd55f9054fb6aaf795ee6/b0a15/8b22239eb7fd3a68934fe063eaa8c3585f8395e5841e4be2e2642ff2c3f32bc9.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/27a0184ec1fcd55f9054fb6aaf795ee6/8ff5a/8b22239eb7fd3a68934fe063eaa8c3585f8395e5841e4be2e2642ff2c3f32bc9.png 240w,
/static/27a0184ec1fcd55f9054fb6aaf795ee6/e85cb/8b22239eb7fd3a68934fe063eaa8c3585f8395e5841e4be2e2642ff2c3f32bc9.png 480w,
/static/27a0184ec1fcd55f9054fb6aaf795ee6/0b533/8b22239eb7fd3a68934fe063eaa8c3585f8395e5841e4be2e2642ff2c3f32bc9.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/27a0184ec1fcd55f9054fb6aaf795ee6/0b533/8b22239eb7fd3a68934fe063eaa8c3585f8395e5841e4be2e2642ff2c3f32bc9.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Hit F5 and browse to http://localhost:12345&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 61.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAAChElEQVQoz6WP30tTYRjH352J4LxJ/AciSoaWUv7IKELCy26CyLoJisK/oIt0bjN1zlLqIrxQb/QmmxUEEaZOY+TIubnpUnS61M3tnJ1z3rPmprgf53zjiEI/sIIe+PB93uf78OV5idvjcVit1mSLoXnTZGzZaG56GDEYDFGj0SiYzKaY2WzaevSodau9vS1isXREuqydbJfVGrZ2WsK9vc+5B00mrtncEW61PM41GdsGydjEZLCo6BgKCwuh0+mQl5e3DyHkr9y6eePX2RAZm7D78/Pz1UeWECJrNIys0WhkDcMoDMOoKjO/oZXV3cbG+3KBTqfOMlqtFgzDvCIjNpv3IF3W/MNVP3Lv7u3DPnegH4jH4/Z09zzD9YY7ueMny1Fdewk15y+gtLwK+tOVKCk9h5Kyyn30Z6pRWlGDsrO1qKi6iKvXGnBCX66cKtFni4uLoSsoGCFQci6nfx0DL0ZzT/tfw/xkGG09wzB3v8SQzQ7H5wWMO7x4Z3dj1OHF+PQ8PrqW8H5qFrbRKYxPz2Jmxpmtr78CQjRvyO7OzlooEsLikk9eDSxi3ufFwrwPq4EVRELrELgQeHYTqQSPVEJA8huPZJyHxEcg8mHVU9K729m6usvql20klUr5d1JJcFxMjsfj4HkeiUQCkiRBisfBcjFEWQ6KgqNKdTJ2+yT6+gb6STKZ9GUyadWQ8YdSFOUoFFmWs9vbKfCC9FYNDKb39lQjI8tyTkVRlJ/0sD8KAOloNIrllcB+YPjgwv8qLhbDWvCrjUiSNEip6BcE4ROl1EUp9Ymi6KRUnKWUeikVZ6gouigV50RBcLEc51bhOG6OZbkvLMt6WZZ1bmyGgssrgZ7v6EaTeskNLdoAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/9cbb86cc46e7af0d55004e3b07d0df84/8ac56/4e79d4c0b1594e59b0a1087ad1180f9171a3fee735303ec17728bd61b1264670.webp 240w,
/static/9cbb86cc46e7af0d55004e3b07d0df84/d3be9/4e79d4c0b1594e59b0a1087ad1180f9171a3fee735303ec17728bd61b1264670.webp 480w,
/static/9cbb86cc46e7af0d55004e3b07d0df84/b0a15/4e79d4c0b1594e59b0a1087ad1180f9171a3fee735303ec17728bd61b1264670.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/9cbb86cc46e7af0d55004e3b07d0df84/8ff5a/4e79d4c0b1594e59b0a1087ad1180f9171a3fee735303ec17728bd61b1264670.png 240w,
/static/9cbb86cc46e7af0d55004e3b07d0df84/e85cb/4e79d4c0b1594e59b0a1087ad1180f9171a3fee735303ec17728bd61b1264670.png 480w,
/static/9cbb86cc46e7af0d55004e3b07d0df84/0b533/4e79d4c0b1594e59b0a1087ad1180f9171a3fee735303ec17728bd61b1264670.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/9cbb86cc46e7af0d55004e3b07d0df84/0b533/4e79d4c0b1594e59b0a1087ad1180f9171a3fee735303ec17728bd61b1264670.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Very good. Now we can serve static files. Half of our problem is solved, since an AngularJS application it&apos;s just a bunch of Html, javascript, CSS, and imagesfiles.&lt;/p&gt;
&lt;p&gt;But if you remember, we need also to use WebApi, which is the way to return some data to the app. &lt;strong&gt;Let&apos;s add another NuGet, Microsoft.AspNet.WebApi.Owin, which will allow us to host WebApi controllers and provide a REST api on our application&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 55.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAACsElEQVQoz22Sz2vTYBjH8z8JXrzuuA1FmJd53GEgzqH4A3QHPThheJiHHYYwUZkKIigenL/WX2vatVmXtFmXps3bpk3SvMnbpEmabm3ySFIGUzx8+T4PvHze78PzUBcuXvqycHO1sLC0ml5YWmUWbz87Wn74Infj7lpl8d763oPVNz/uPHmZubWyUVx5vp14tPa69Hj9XeH+082jt19zpZ18PbezXz/8ldlv/0xkNqjLV662iyUBmFINjoQO1CUMYqMLfBVBNs8BcyhArlCBA1YEvtoAsdEGDTugYhskuQvNDgbdtEFWCbyn1W/Utbm5qiBIUCyWR7WaFHTaWqAoePx7lw6SKWa8myjEonPlIJstjlOpfMAw3HgvVwgO2GrAHTXGOu6dmCYB1Gx9oK7Pz/MIydBqKQEhFvR6/ViW5YDdd6HveNDve2DZDli2C67rQwO1IUGXoHKMoNvFISH2CGMTkCRtUTMzMxwhNtiWE0SgqLasPgwGg7/kx+7ByYkPqIOB5hCgjgGm2Qt7vf4I6yYIgrhFzc7MliMIIf1g4hOg53n/1XA4BCQhoLN0BABF6YaW5cQJJan1ipqenq7bthuNGERjTjQBRsn+Bfq+DwY2oVTiQBDq0O0aoWH0RoZBQOko29TU1BSvaTqoqh6oajf6MU55HnY29hlQ1zFwHA8sWwaePw55vjqSZQU0VftILS8vV1i2AgxzOOb5asiylVDXjcDzvNB13XDiTuC6bnDWmyYJogCahmPpOjnFmICqqp8p0yCS1GhEGwLPG8ZbdN0B+P4JDIensXtelM4/10/eOc4gvgCl0wFZlkHTtO9UTRA/ZfcycjqdEulcXk+l0qRQYJrp1J6eTKYxTecVhimhYvEAJZNpkkxm9Kguc/yxKDZQs9mSytyhWObYNkJo8w89OPx/mabdQAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/c9199131b10bbda826dff15cc4c29084/8ac56/338e0059bf7e33ae814470dae83157e500b72d0f528ca70206d06b8988b0fa78.webp 240w,
/static/c9199131b10bbda826dff15cc4c29084/d3be9/338e0059bf7e33ae814470dae83157e500b72d0f528ca70206d06b8988b0fa78.webp 480w,
/static/c9199131b10bbda826dff15cc4c29084/b0a15/338e0059bf7e33ae814470dae83157e500b72d0f528ca70206d06b8988b0fa78.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/c9199131b10bbda826dff15cc4c29084/8ff5a/338e0059bf7e33ae814470dae83157e500b72d0f528ca70206d06b8988b0fa78.png 240w,
/static/c9199131b10bbda826dff15cc4c29084/e85cb/338e0059bf7e33ae814470dae83157e500b72d0f528ca70206d06b8988b0fa78.png 480w,
/static/c9199131b10bbda826dff15cc4c29084/0b533/338e0059bf7e33ae814470dae83157e500b72d0f528ca70206d06b8988b0fa78.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/c9199131b10bbda826dff15cc4c29084/0b533/338e0059bf7e33ae814470dae83157e500b72d0f528ca70206d06b8988b0fa78.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Now we need to configure the WebApi, telling the route pattern to use.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 65.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAACyklEQVQ4y5WS32tTZxjHv2+S8+s9J2lsk5yTc05TE5fZNha0tleziS6O2h9uw/9g/4gg7Nqb4TbaXWwIglUUYWwXQ4RdOhnFbmpj0xYUSemmVUR0SfOVtxyLE3exiw/Pw/vyfp/n+T4vlpbXfnywsbXRfLCxent5be328vr91l9PV5b/bj/66ubWvXO3ni6d+fVJ48bKVrO1+bi5+eyfh6sPN1cW7zb/XGqsN5ca6/daT14sth4/b/3+R+MHfFSt3fn4+CesTlR55MgEa7WjnJ6e4cnZWZ76/LMdPp2Z5tSJE5ycnGS9fpxHa8dYq9U4MVFltVplvV7n1NQUZ2ZmzwHALQAE0Aaw/R46/3H+Nq8ijS+RkM6ilUwxHhPbIhajqcVZzFo8NPIhRw8f5qGDBzk8XGGlHHC0MsDx0REWi0VmshkGQUDf97uu67b7+vroed4FCMNcM6TNqJKKtKTGwt5eul6W0rJo2zZtW1IacZp6nNK2KaWk4ziKrpSybZomk8nkWQjdvG5YkjEh1Gg7j7PZHDOZHHt7+5jL5ei67k7M+wHT6T18UziiG9ml8rOAZvyS8fLsD/s7Smj/4BDHx8c5NqYYY6VygH4+oOt6DMOQQRAyn/ffppvP+22Ve543rzpsWk6SsVhsGxA0DIOZTIblcpmlUol7iwXu+6DIMAyYSGhRV2I3CiG6Qoi2EEJpzEFo+qpuWf/yUOEHAYeHhzhYKbI81M+gsIfJHpOptEnpaHRSOnUj8e7I80qwYUi5K6hpmvKTPek09w8OMvA8Zntspnt76LtJlsIUS/0pFsI0CwMF5W03lUq9EfwewrBuRltWf6ljmGZH1/V2VPV9dMRuvjOqyl9Ggt8owd9M22EiHqeu6+9u8P/yNaDppy0nuWDo+gKAnwHcAHANwBUAcwAuAvgWgLq/BOAnAFcBnAfwHYDLAK5Hb754DW9/UVkdnkN/AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/68de7b58f4189b0e388a194c7b929751/8ac56/8b57815a11fc0b00ed8486c176719a8cfed5ee3b378231fd5527fe73afce9007.webp 240w,
/static/68de7b58f4189b0e388a194c7b929751/d3be9/8b57815a11fc0b00ed8486c176719a8cfed5ee3b378231fd5527fe73afce9007.webp 480w,
/static/68de7b58f4189b0e388a194c7b929751/b0a15/8b57815a11fc0b00ed8486c176719a8cfed5ee3b378231fd5527fe73afce9007.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/68de7b58f4189b0e388a194c7b929751/8ff5a/8b57815a11fc0b00ed8486c176719a8cfed5ee3b378231fd5527fe73afce9007.png 240w,
/static/68de7b58f4189b0e388a194c7b929751/e85cb/8b57815a11fc0b00ed8486c176719a8cfed5ee3b378231fd5527fe73afce9007.png 480w,
/static/68de7b58f4189b0e388a194c7b929751/0b533/8b57815a11fc0b00ed8486c176719a8cfed5ee3b378231fd5527fe73afce9007.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/68de7b58f4189b0e388a194c7b929751/0b533/8b57815a11fc0b00ed8486c176719a8cfed5ee3b378231fd5527fe73afce9007.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Basically we configured to use the route /api/{controller} tou our WebApi controllers. Let&apos;s add a simple HomeController with the Get method, returning a simple string.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 72.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC/ElEQVQ4y42Ty2sUWRTGT91H3bp1q6u7qx/pdOxgMiYakCyiYlzoQnyAo/MHzMBs/Bd070pChIww0SSaRAMDrhwREV2KYHwHCRInGmNMoyaoIAQZx67qb6iyBQ0KLj7Ody6XH985l0uzc8/OzVeXl97/W5v5Y/Lt7O/nqzMHLyxe/+38i9sHL76a/mfx9cxCdWnq5ZuVqQ8Rppfertx5Wl1+sPKhfu/d+/DWo7nFm/PV5amFF68f3r4/fZj6+/vmBwZHMHJ6FCPDwxga/wtnzv2NgROn0Xf8JIZGz2L4C42MTST11PgEBofGcPzPYZw4NZac9x0bOEpEdI+IYBPVmm2KKqV81N7WFmZ8L/Q9E6Y8E2lHhb6fCiVnIRF9S//FDCLqI87ZZaY0ilmv1l026OneiK29vdi8eQu6urrALAtKKdi2guM4YJyDMQbGPldWZ4zVYm9Z1mCccI4sjvU/rY32bNmAvbt2Yv+BX7B79x7s2/czdmzfga2929DTswktLWtQqbSuVr1Saa3Fvlxu6Y+Bd4lLZFJuuDbnorNjHdZv6EJ7exs6OzvR0bEuSai1ThJJKb+SELIuhKw1+mSHN0gqpIwTFj2BQDOkPINScxmFYhOCIIc1lVbkC0UEQYDGrr5UvbHH2B+KgVcspZHLBTXfESgYgbTRKGRTKARpNBcyKOXjmoZnNIyOp1HIeAopV34G1hrAgRg4KTwfUjmhY0uU0hqeTchphoJvo1I0KOU9NAUajs0R+A5KgYtiViPnq9XAZORJpl24rpvEllKglFYwNoOvGLLGQbGpDMblt8ZdDUwe5SpzPThaJ0DBOYQQyBuBjBbI5DUKzQb5kkGu6KKpxUM2p5HJfnqkVcAjMfAC0wbKcT4yy4qUUiHnPGQWfRK3IiFYyIUV8dhLFsaVCxZZlhURUayPDeDhGHjJclx4KR+2lOCcf2+0H9GxGHiNafNSSPmEiB4T0TQR3SKim0R0n4geNvpHRDTb+KoLRPSciJ4R0XzjzlMi+vV/iFB49I4sAdsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/69d69973c738701062fc4cd17d55afb0/8ac56/ce6139d68f067fe8fc67a1698d2ac30988ed0015df985d016a65c58894df6629.webp 240w,
/static/69d69973c738701062fc4cd17d55afb0/d3be9/ce6139d68f067fe8fc67a1698d2ac30988ed0015df985d016a65c58894df6629.webp 480w,
/static/69d69973c738701062fc4cd17d55afb0/b0a15/ce6139d68f067fe8fc67a1698d2ac30988ed0015df985d016a65c58894df6629.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/69d69973c738701062fc4cd17d55afb0/8ff5a/ce6139d68f067fe8fc67a1698d2ac30988ed0015df985d016a65c58894df6629.png 240w,
/static/69d69973c738701062fc4cd17d55afb0/e85cb/ce6139d68f067fe8fc67a1698d2ac30988ed0015df985d016a65c58894df6629.png 480w,
/static/69d69973c738701062fc4cd17d55afb0/0b533/ce6139d68f067fe8fc67a1698d2ac30988ed0015df985d016a65c58894df6629.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/69d69973c738701062fc4cd17d55afb0/0b533/ce6139d68f067fe8fc67a1698d2ac30988ed0015df985d016a65c58894df6629.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Let&apos;s Hit F5 and browse to the url http://localhost:12345/api/home&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 67.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAAC1UlEQVQ4y52RyU8UQRjF+6gYBwdHcQtKOPg/ePTk/2HCXaMHEw8iicZoiFERDSQQgQDjqGzCKLIIwmxsOkYzPUvX9DQ9ytYDztJdU1XPdI/GeHKp5OVVVSq/79X3Sb093UHvQN/sQH/vbE93V/DpQF/kuc+74n3qnR4dGQqPDL2Y8Xn7xnw+36R/fOzdq/FR/+SEf+L1+GgkMD/3jqj6VIqszavaV1mOp5qlupOnUN9wGsdP1MNz6Cg8h49hv6sGe/dVY09VNar2u+E64IHL7XH8wMFauD1HnHPro3ZE4xo+ygSyksFCeKVFOnP2HG49eFa+erOd3esYZA87R/jDzmF+p+0Zu932nN/tGGb3u16yth4/a++fYJ2+afZk8C3rHwvwoeklNjizxObCq2b3ky7U1dVdlc43nsfGZpbLchRbGzrSqRjWs2kYmzqMzbWKNtaw7UjD9rqGrfWKk+QnxD6vCD2ToJMTY6h2ua5Ily5fAgBWKhZRphSmWQKlFiilfxTnHIxxAaAsyzJqampuSRcvXrCBnJbL+J/FHR5oPB6H2+1ukZqarlWAlEII8c/iFSKNxWJ2wutSzjAcoPPgZ1khfrkQf0hYAdpfrq2tbZbsfkEIZt+KfB6CMQf8rwmTyQQaGhpuSKVSyRmKU67MgdwuIP6+h6LymhqGgY6OzsuSPVUbKJgFzgsQhW2ItRREOQ+wwm/OrN3fVLZ2wGjembJlWZDlxF3JrCSkZn6d5/RFvvNlle3oyyyXXWabmTA39CW2oYacM8/HOfsmM/Ytzmzn+TgrGTKDEJZpWVhdfd/6I6GAaVooFC0USxRFkzr73G7e8Z3dgnOv6zoyqgpCFGiaBqIoUNWM00ub8yH68bGUzerzmqYF0mkSIkoqRIgSSCUTw2mizKppEiZEmSdEeUOIMh2Nvg+HggF/KBSYWoyEF0LBwFwkEp5MJJNTiURSDQRDjd8BvJDBz1gohjIAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/1d9d1ade3c82f456ed155323790f99e1/8ac56/006617ba75714298b6bc0ab3d4c1fc8f16806fff744637e20aa6d963c8f20907.webp 240w,
/static/1d9d1ade3c82f456ed155323790f99e1/d3be9/006617ba75714298b6bc0ab3d4c1fc8f16806fff744637e20aa6d963c8f20907.webp 480w,
/static/1d9d1ade3c82f456ed155323790f99e1/b0a15/006617ba75714298b6bc0ab3d4c1fc8f16806fff744637e20aa6d963c8f20907.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/1d9d1ade3c82f456ed155323790f99e1/8ff5a/006617ba75714298b6bc0ab3d4c1fc8f16806fff744637e20aa6d963c8f20907.png 240w,
/static/1d9d1ade3c82f456ed155323790f99e1/e85cb/006617ba75714298b6bc0ab3d4c1fc8f16806fff744637e20aa6d963c8f20907.png 480w,
/static/1d9d1ade3c82f456ed155323790f99e1/0b533/006617ba75714298b6bc0ab3d4c1fc8f16806fff744637e20aa6d963c8f20907.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/1d9d1ade3c82f456ed155323790f99e1/0b533/006617ba75714298b6bc0ab3d4c1fc8f16806fff744637e20aa6d963c8f20907.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The WebApi&amp;nbsp;content-negotiation resulted in a json fle. Let&apos;s click Open to see the content&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 62.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAAChElEQVQ4y6WQW08TURDH91vgI4/gA34C5dIiFqSAJVYKfAE18SNoTHwyAR8QMIAajGhQ5KISKGgJIU3AlAK9Wov2xtJqu93d7jm7oXv6N9saY0xQjJP8M5M5M7+ZM1wwGN71+wNboVA44A8E9kLB0G7kY8QX+bTvje7HdhKJ5E48nvJGo/vb0c/xDf7gcDOT/upKpzNb8VjcHYslPYnkoTuTyW6FQpGbnKPXgbZWC6zt7TCbmmA2N8FkakT9ubNobKiHqanhp5qbTWg5b4blQku59ordBu+2BzyfhpDLI/YlcY+rOlWFnv6+o/7+PubodTC7vYfZui8za0cXs7RZmaXVytoudrJ26yVm7bTpHV3d+iWb3fDs6vUb+tLyKnOurmmr71x4OTM7yNWcrsWm18MCAS88vj2MPJrFwPA0hifmcHdoGgOjc7j/8C1GJ5cwNrWCxy9cePJqHc8W3Jia38DEc2dpcub90dO5NYxMLgxwtbU1SB4kmChkccgn4fftwrdXUTgcrPhQAPvRCFLJOMR8DnkhC0HIlr0k5UuSKBRlSQTPp4a4M3V1KBaLOgBomoZSqYR/NKOhaASiKI5z1dXVUFVaBhKiQC8WK1Wl0kll2JER53K529z4+JixITMglBLouv5H4K9vP+Iy0IgFQbjDVZJMrwDpX4HHbWj05PP5QU6WJTBWAaoq/d8bTnBEUQygMUEvyDIrFCSmaapu3FU7uTRNpeAPUrc445uVIZUNhdw3FGQJsiweq8LvOUlEoSAhmYg94NLp9KIsSyuyLLsJIR8oVbcVQpYIoS5FIYuEUKeikHlCyAIhZJlS6lYU5TWl1EkI3SCEriuEvKGq6uF5/tp3zah/qRmuhXcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/68a1e6fa328f0a99018ef357e329d6cb/8ac56/3f0b9d1cc0a56bc641b7bf0f730800b7bad06aa74422b29f8981adfa622ecdac.webp 240w,
/static/68a1e6fa328f0a99018ef357e329d6cb/d3be9/3f0b9d1cc0a56bc641b7bf0f730800b7bad06aa74422b29f8981adfa622ecdac.webp 480w,
/static/68a1e6fa328f0a99018ef357e329d6cb/b0a15/3f0b9d1cc0a56bc641b7bf0f730800b7bad06aa74422b29f8981adfa622ecdac.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/68a1e6fa328f0a99018ef357e329d6cb/8ff5a/3f0b9d1cc0a56bc641b7bf0f730800b7bad06aa74422b29f8981adfa622ecdac.png 240w,
/static/68a1e6fa328f0a99018ef357e329d6cb/e85cb/3f0b9d1cc0a56bc641b7bf0f730800b7bad06aa74422b29f8981adfa622ecdac.png 480w,
/static/68a1e6fa328f0a99018ef357e329d6cb/0b533/3f0b9d1cc0a56bc641b7bf0f730800b7bad06aa74422b29f8981adfa622ecdac.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/68a1e6fa328f0a99018ef357e329d6cb/0b533/3f0b9d1cc0a56bc641b7bf0f730800b7bad06aa74422b29f8981adfa622ecdac.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Bingo. Our application now&amp;nbsp;handles WebApi.&lt;/p&gt;
&lt;p&gt;Finally, to install this as a windows service, we just need to add a project installer&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 68.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsTAAALEwEAmpwYAAADCElEQVQ4y31SO4/kRBj0T+IXIBEhOOkkMoILEAEiuoCYX0BAANKJhJeQWAKQEAQEq72B253Tre5mZ2dm53Zm/Hbb3X6On922x49C9jKnQ0IEpSp97i5VuT9psdEWsh1OPv1Dv/joZ/n841+UycNf1cUnv6m7Byfb+e8LdsmC+EY12VLeqc9vb3fXpmmvCKGXum7dmKb9xHHYM9Wg8uO/ph9IeV6g4BxZ8W/kBUea3zEXAmmawXV92Db9hx3ohgnPC7Dfx9BtD6eT6QOpFAJC8EMpRPsaOiFEN2hxh44XvAvDqCWW1cmy3CVJ0h4Oh66u67au60NVVZjP5/ckIQQ45y3nHP8PgTCMIMsyLMtCFEVI0xRFUfSc8y7L8sHw/tGwGy6JMe1/YzDMsgwOtREEPsIwRBzvUddVX1VlW1XlYPihNBw8Gh5RFHc4aiE4kiSDbjiYzRZ4/uIaO9mAptsgttdTFnamxfB4cvGmVNclqkq0h0M5VtJ0C4pqgLkhXC8a2Q/2SJIctuNidbPGdHqJ+fUKuk7gemHv+/t2ODOdPntfkncEqup0iuzANBk0nUBWDFjEBWUBTMJGHtJmeQovYNBUdazdNoexcl1XY+Wrq9l7kiynUJSs29xmICSBblhYrm6x2Sqj0THhPs6g0xjEz8D8GKZpwyIUUZT2UZR2QRDj6dPLd15VrmuBLM9hmDbWL7dgro84yREnGZK0GH/HcrnGdqtAVQ0YBoFtMxBCe0Joa1o2Tk/P3n31KEKUvR+EvW6QXtOtPgjjPgzjfkgXx2lPvah/MV/BMknPmNd7rt+H4X7Efp90nufj/Hz69nFtas55I4RoyrJsylKMesAwH2ZxnDZXV4tG182G87JJkrzJMt64rt+s1y9rRVExmfx5XyrLctyzgY/6uHevz5IkxXK5gqpq47eiKEYekmmaPu7lbDZ7S6KUfkMpfeS67onruj8xxn5kjH3vOM6XrusO+oRS53NN0x+dP7k42Wx2P1DKvibE/o4Q+ytN07+VZfULy7I/OzubvPE31c/6drJWyh0AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/45d74d981e55c3cc6ea5af8ea9e3d545/8ac56/29e84d3b24b13af8dc5c5f9da79dfe5d1db29fba6f81bd7d351d42ab1ae8cba3.webp 240w,
/static/45d74d981e55c3cc6ea5af8ea9e3d545/d3be9/29e84d3b24b13af8dc5c5f9da79dfe5d1db29fba6f81bd7d351d42ab1ae8cba3.webp 480w,
/static/45d74d981e55c3cc6ea5af8ea9e3d545/b0a15/29e84d3b24b13af8dc5c5f9da79dfe5d1db29fba6f81bd7d351d42ab1ae8cba3.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/45d74d981e55c3cc6ea5af8ea9e3d545/8ff5a/29e84d3b24b13af8dc5c5f9da79dfe5d1db29fba6f81bd7d351d42ab1ae8cba3.png 240w,
/static/45d74d981e55c3cc6ea5af8ea9e3d545/e85cb/29e84d3b24b13af8dc5c5f9da79dfe5d1db29fba6f81bd7d351d42ab1ae8cba3.png 480w,
/static/45d74d981e55c3cc6ea5af8ea9e3d545/0b533/29e84d3b24b13af8dc5c5f9da79dfe5d1db29fba6f81bd7d351d42ab1ae8cba3.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/45d74d981e55c3cc6ea5af8ea9e3d545/0b533/29e84d3b24b13af8dc5c5f9da79dfe5d1db29fba6f81bd7d351d42ab1ae8cba3.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Compile in release mode, install the windows service (using installutil.exe) and you are ready to add your AngularJS application, which will be served by the windows service process, without the need of Internet Information Service (IIS). With this, now I can&amp;nbsp;consider to build my configuration tool (to run on desktop) using AngularJS and WebApi.&lt;/p&gt;
&lt;p&gt;You can download the full code in &lt;a href=&quot;https://github.com/bfcamara/KatanaWinSvcSample&quot; target=&quot;_blank&quot;&gt;my github account&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[An Overview of Project Katana and OWIN]]></description><link>https://bfcamara.com/post/51811783989/an-overview-of-project-katana-and-owin</link><guid isPermaLink="false">https://bfcamara.com/post/51811783989/an-overview-of-project-katana-and-owin</guid><pubDate>Fri, 31 May 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://www.asp.net/vnext/overview/owin-and-katana/an-overview-of-project-katana&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://www.asp.net/vnext/overview/owin-and-katana/an-overview-of-project-katana&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;
&lt;div&gt;The ASP.NET Framework has been around for over ten years, and the platform has enabled the development of countless Web sites and services. As Web application development strategies have evolved, t...&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;A very good &lt;a href=&quot;http://www.asp.net/vnext/overview/owin-and-katana/an-overview-of-project-katana&quot; target=&quot;_blank&quot;&gt;white paper&lt;/a&gt; explaining &lt;a href=&quot;http://owin.org/&quot; target=&quot;_blank&quot;&gt;OWIN&lt;/a&gt; and the &lt;a href=&quot;http://katanaproject.codeplex.com/&quot; target=&quot;_blank&quot;&gt;Katana Project&lt;/a&gt;. It begins to be very easy to have a lightweight web server embedded in our own process (console applications, windows services, etc). It opens a lot of possibilities. I&apos;m dirtying my hands, trying to host an AngularJS application inside a Windows Service.&amp;nbsp;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Video post]]></title><description><![CDATA[The AngularJS video tutorial course featured on Egghead.io]]></description><link>https://bfcamara.com/post/51058584741/the-angularjs-video-tutorial-course-featured-on</link><guid isPermaLink="false">https://bfcamara.com/post/51058584741/the-angularjs-video-tutorial-course-featured-on</guid><pubDate>Wed, 22 May 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;False&lt;/p&gt;
&lt;p&gt;&lt;span&gt;The AngularJS video tutorial course featured on Egghead.io&lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Video post]]></title><description><![CDATA[I'm in love with AngularJS. Here is the presentation about design decisions on Google I/O 2013.   It is impressive how the...]]></description><link>https://bfcamara.com/post/50641543547/im-in-love-with-angularjs-here-is-the</link><guid isPermaLink="false">https://bfcamara.com/post/50641543547/im-in-love-with-angularjs-here-is-the</guid><pubDate>Fri, 17 May 2013 00:00:00 GMT</pubDate><content:encoded>&lt;div class=&quot;gatsby-resp-iframe-wrapper&quot; style=&quot;padding-bottom: 56.2%; position: relative; height: 0; overflow: hidden; margin-bottom: 1.0725rem&quot; &gt; &lt;iframe id=&quot;youtube_iframe&quot; src=&quot;https://www.youtube.com/embed/HCR7i5F5L8c?feature=oembed&amp;amp;enablejsapi=1&amp;amp;origin=https://safe.txmblr.com&amp;amp;wmode=opaque&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot; style=&quot; position: absolute; top: 0; left: 0; width: 100%; height: 100%; &quot;&gt;&lt;/iframe&gt; &lt;/div&gt;
&lt;p&gt;&lt;strong&gt;I&apos;m in love with AngularJS&lt;/strong&gt;. Here is the presentation about design decisions on&amp;nbsp;&lt;span&gt;Google I/O 2013.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;It is impressive how the Google feedback project, with 17K lines of code turned into a project with 1.5K lines of code using AngularJS.&lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[NoBackend: Front-End First Web Development]]></description><link>https://bfcamara.com/post/50089491429/nobackend-front-end-first-web-development</link><guid isPermaLink="false">https://bfcamara.com/post/50089491429/nobackend-front-end-first-web-development</guid><pubDate>Fri, 10 May 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://www.infoq.com/news/2013/05/nobackend&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://www.infoq.com/news/2013/05/nobackend&lt;/a&gt;&lt;/p&gt;
&lt;blockquote class=&quot;link_og_blockquote&quot;&gt;At the Front-Trends 2013 conference last week, Gregor Martynus gave a talk entitled &quot;Look ma, no backend!&quot; about developing applications primarily from a front-end perspective, falling back to using server-side components only to implement the features the browser does not yet support.&lt;/blockquote&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Why You Should Do A Tiny Product First «  Unicornfree with Amy Hoy: Creating And Selling Your Own Products]]></description><link>https://bfcamara.com/post/49922862765/why-you-should-do-a-tiny-product-first</link><guid isPermaLink="false">https://bfcamara.com/post/49922862765/why-you-should-do-a-tiny-product-first</guid><pubDate>Wed, 08 May 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://unicornfree.com/2013/why-you-should-do-a-tiny-product-first&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://unicornfree.com/2013/why-you-should-do-a-tiny-product-first&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A good post from Amy Hoy, where she advices that we should make the first product an inforproduct (e-book, screencast, workshop, etc.), like 37signals did. &amp;nbsp;This advice goes along the line of thought of the quote that&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;the best marketing is education&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[ASP.NET MVC - Default Model Binder with HTML Validation]]></title><description><![CDATA[ASP.NET MVC - Default Model Binder with HTML Validation]]></description><link>https://bfcamara.com/post/48031562990/aspnet-mvc-default-model-binder-with-html</link><guid isPermaLink="false">https://bfcamara.com/post/48031562990/aspnet-mvc-default-model-binder-with-html</guid><pubDate>Mon, 15 Apr 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;This post demonstrates how we can handle gracefully the HTTP request validation which exists in ASP.NET, when using ASP.NET MVC.&lt;/strong&gt; Request validation is a feature in ASP.NET that examines an HTTP request and determines whether it contains potentially dangerous content. For example, if a user tries to input some malicious code in a field using the script element, the ASP.NET throws a &quot;potentially dangerous value was detected&quot; error and stops page processing. Without this validation, the site is vulnerable to this exploit typically referred as a cross-site scripting (XSS) attack.&lt;/p&gt;
&lt;p&gt;Consider this form&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;470&quot; data-orig-width=&quot;500&quot;&gt;&lt;img alt=&quot;image&quot; src=&quot;https://66.media.tumblr.com/65aeb86afead403581aee09b8c95103d/a530e3b9dda3aaca-2b/s540x810/7813a045ef5e112ad59ac7c20cb9d1c53662fdc9.png&quot; data-orig-height=&quot;470&quot; data-orig-width=&quot;500&quot;&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Here is the error when the user tries to submit a field with HTML elements, pressing the Save button&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;354&quot; data-orig-width=&quot;500&quot;&gt;&lt;img alt=&quot;image&quot; src=&quot;https://66.media.tumblr.com/1ae9f8f8c0d150c6dc42b7a55b1304f6/a530e3b9dda3aaca-bb/s540x810/2f2a66c9a1e8805bfbeba51a9efa0d93dd1cd557.png&quot; data-orig-height=&quot;354&quot; data-orig-width=&quot;500&quot;&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;We can disable this validation at a field, action, controller, or application level. But we have to think about the consequences of disabling it and being vulnerable to an XSS attack. &lt;strong&gt;Instead of disabling it, I want to continue validating the potential dangerous requests, but rather than throw the error and stop processing, I want to add a validation message for the field that is violating the validation.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;421&quot; data-orig-width=&quot;500&quot;&gt;&lt;img alt=&quot;image&quot; src=&quot;https://66.media.tumblr.com/f4fdeb5ab7319eff0e7de8e8cebdd83b/a530e3b9dda3aaca-e1/s540x810/f8931121223d166489a86b914efb9301d111e35b.png&quot; data-orig-height=&quot;421&quot; data-orig-width=&quot;500&quot;&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;In ASP.NET MVC, we can do this using a custom default model binder. &lt;strong&gt;The model binding is the mechanism that automatically populates the controller action parameters, taking care of the details of property mappings and type conversions&lt;/strong&gt;. The default model binder in ASP.NET MVC is the class &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.web.mvc.defaultmodelbinder(v=vs.98).aspx&quot; title=&quot;Default Model Binder&quot; target=&quot;_blank&quot;&gt;DefaultModelBinder&lt;/a&gt; . The good news is that we can have a custom default model binder. In our case, we want to inherit the DefaultModelBinder, overriding the main method BindModel, and handle the exception HttpRequestValidationException which is thrown when a potential dangerous request is detected&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DefaultModelBinderWithHtmlValidation&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token type-list&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;DefaultModelBinder&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;object&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;BindModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ControllerContext&lt;/span&gt; controllerContext&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ModelBindingContext&lt;/span&gt; bindingContext&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;BindModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;controllerContext&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bindingContext&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;HttpRequestValidationException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            Trace&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;TraceWarning&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Ilegal characters were found in field {0}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bindingContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ModelMetadata&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;DisplayName &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; bindingContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ModelName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            bindingContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ModelState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;AddModelError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;bindingContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ModelName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Ilegal characters were found in field {0}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bindingContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ModelMetadata&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;DisplayName &lt;span class=&quot;token operator&quot;&gt;??&lt;/span&gt; bindingContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ModelName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;//Cast the value provider to an IUnvalidatedValueProvider, which allows to skip validation&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;IUnvalidatedValueProvider&lt;/span&gt; provider &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; bindingContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ValueProvider &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IUnvalidatedValueProvider&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;provider &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;//Get the attempted value, skiping the validation&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; provider&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;GetValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;bindingContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ModelName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token named-parameter punctuation&quot;&gt;skipValidation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        Debug&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Assert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;result is null&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;AttemptedValue&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, what we do is quite simple: we catch the HttpRequestValidationException exception and add a validation error message to the ModelState specifying the field name that is violating the request. Next we read the attempted value, skipping the validation and return. &lt;strong&gt;In our action controller we can&apos;t forget to check if the ModelState is valid&lt;/strong&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attribute&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;HttpPost&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;ActionResult&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;MyModel&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; fieldArgument&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ModelState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;IsValid&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//The model is OK. We can do whatever we want to do with the model&lt;/span&gt;
        model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MyMessage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Model Ok Updated @ &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; DateTime&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Now&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    ViewBag&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;FieldArgument &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; fieldArgument&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next we have to register our binder as the default binder. We do this in the application start&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;//Register our binder as the default model binder&lt;/span&gt;
ModelBinders&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Binders&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;DefaultBinder &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;DefaultModelBinderWithHtmlValidation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can check the full source code &lt;a href=&quot;https://github.com/bfcamara/DefaultModelBinderWithHtmlValidation-AspNetMVc&quot; title=&quot;Sample Source Code&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; on my github.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Taking the leap]]></description><link>https://bfcamara.com/post/45673660655/taking-the-leap</link><guid isPermaLink="false">https://bfcamara.com/post/45673660655/taking-the-leap</guid><pubDate>Mon, 18 Mar 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://swombat.com/2013/3/15/taking-the-leap&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://swombat.com/2013/3/15/taking-the-leap&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A very good post from Daniel Tenner on his&amp;nbsp;&lt;span&gt;successful&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://swombat.com/&quot; target=&quot;_blank&quot;&gt;startup blog, swombat.com&lt;/a&gt;, where he gives some advices to&amp;nbsp;&amp;nbsp;those who want to go to &lt;strong&gt;&lt;em&gt;&amp;ldquo;taking the leap&amp;rdquo;&lt;/em&gt; (quit your job and start your own company).&lt;/strong&gt; Here is the list, with my personal comments from my experience of co-founding a company and primarily from my&amp;nbsp;&lt;a href=&quot;http://bfcamara.com/post/17149497531/my-first-big-mistake-as-founder&quot; title=&quot;My first big mistake as a founder&quot; target=&quot;_blank&quot;&gt;mistakes&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;&lt;em&gt;&lt;strong&gt;&amp;ldquo;Cut (personal) costs to the minimum&amp;rdquo; &amp;nbsp;&lt;/strong&gt;-&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/em&gt;&lt;/span&gt;In the begining it is absolutely essential to cut the personal costs, since there is no income (worst case scenario, but a realistic one). There are some expenses that can&amp;rsquo;t be cut. &lt;strong&gt;Most of the trouble here is caused by decisions made in the past: big house, big car, etc.&lt;/strong&gt; If you are married it is better to inform your wife about the potential changes of this movement: go out to dinner less often, postpone some house improvements, etc. And it is also absolutely crucial to answer to the question &lt;strong&gt;&lt;em&gt;&amp;ldquo;how many months can you handle without any income and what is your stop loss limit?&lt;/em&gt;&lt;/strong&gt;&amp;rdquo;.&amp;nbsp;if you have a partner,&amp;nbsp;do not skip this question and have an answer from your partner as well. It does not make sense that you accept to handle no income during 12 months and your partner just can handle 2 months.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;&amp;ldquo;Do not take funding&amp;rdquo;&lt;/strong&gt;&lt;/em&gt;&amp;nbsp;- I believe that there are some kind of businesses where it is needed to take some funding. Although, I think it is always preferable to be self-funding. First, &lt;strong&gt;if you take money from some VC or if you sell part of the company, you maybe loose the operational control&lt;/strong&gt;, and some frictions arise as consequence. If you follow the self-funding path, as Daniel refers, you will be pressured to make sales and get some revenue. This pressure will force you to be very pragmatic and force you to &lt;strong&gt;validate your idea as soon as possible&lt;/strong&gt;. You will be forced to launch early, which in my opinion it is a good thing. Even if the product does not gain any traction, you didn&apos;t waste all &amp;nbsp;your time and money. &lt;strong&gt;If we have to fail, then we should fail early&lt;/strong&gt;, allowing us to have more second chances.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;&amp;ldquo;Connect with mentors and peers and listen to them&amp;rdquo;&lt;/em&gt;&lt;/strong&gt;&amp;nbsp;- Absolutely right. I think I should have listened more people in the field, who already took the leap. In 2004, when I decided to found my company, there was too much wishful thinking around my head. But that&apos;s it: &quot;wishful thinking&quot;, with some distance from the reality. &lt;strong&gt;Listening experiences from other people, and knowing in advance how hard it is to take the leap it is crucial to handle hard times&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;Don&apos;t tie yourself to one idea&lt;/strong&gt;&lt;/em&gt;&lt;span&gt;&amp;nbsp;- It is very difficult to know if &amp;nbsp;our idea it will be or not a&amp;nbsp;successful&amp;nbsp;idea . I think &lt;strong&gt;the execution is more important than the idea&lt;/strong&gt;, however picking the wrong idea, even with a good execution, can be something that it&apos;s not profitable. The &lt;a href=&quot;http://theleanstartup.com/&quot; title=&quot;Lean Startup&quot; target=&quot;_blank&quot;&gt;Lean Startup&lt;/a&gt; approach popularized from Eric Ries (credits here also to Steven Blank with the Customer Development techniques popularized in the book &amp;nbsp;the &quot;&lt;a href=&quot;http://www.amazon.com/Four-Steps-Epiphany-Successful-Strategies/dp/0976470705&quot; title=&quot;The 4 Steps to the Epiphany&quot; target=&quot;_blank&quot;&gt;4 Steps to the Epiphany&lt;/a&gt;&quot;), &amp;nbsp;can help us to rapidly &lt;strong&gt;validate our idea&lt;/strong&gt;. If the feedback of this validation it&apos;s not what we are really expecting,&lt;strong&gt; we have to be prepared to pivot or jump to another idea&lt;/strong&gt;. But the lack of focus on an idea can be bad to the execution. &lt;a href=&quot;http://sivers.org/&quot; title=&quot;Derek Sivers&quot; target=&quot;_blank&quot;&gt;Derek Sivers&lt;/a&gt;, from CDBaby tell us that the&lt;a href=&quot;http://sivers.org/multiply&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt; Ideas are just multipliers of Executions&lt;/strong&gt;&lt;/a&gt;. My observations on this field tell me that a possible recipe, with apparently some kind of success, consists in &lt;strong&gt;building something to an audience that you know well, and the audience recognizes you as an authority and trusts you&lt;/strong&gt;. The hard part is to grab the audience. But there are a lot of guys that follow this recipe with some success: start a blog which gains buzz, write a book, record screencasts, develop workshops, etc. Then finally build a product to this audience. However, this evidence of success doesn&apos;t tell us nothing about the&amp;nbsp;efficacy&amp;nbsp;of this recipe, since &lt;strong&gt;it is not possible to know how many people have tried &amp;nbsp;this recipe and have failed&lt;/strong&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;strong&gt;&quot;Don&amp;rsquo;t make plans or set deadlines&quot;&lt;/strong&gt;&lt;/em&gt;&amp;nbsp;- &amp;nbsp;Well, I don&apos;t agree with this statement. I think the statement should be&amp;nbsp;&lt;em&gt;&quot;Don&apos;t make a detailed plan or set rigid deadlines&quot;&lt;/em&gt;. &lt;strong&gt;I think that we should have a plan an write it on piece of paper, primarily if you are co-founding with a partner. But the plan should be no longer than a page&lt;/strong&gt;.&amp;nbsp;&lt;em&gt;&quot;The shorter your plan the better&quot;&lt;/em&gt;, very well said in this &lt;a href=&quot;http://ceklog.kindel.com/2013/03/02/have-a-plan/&quot; title=&quot;Have a Plan&quot; target=&quot;_blank&quot;&gt;post &lt;/a&gt;. &amp;nbsp;But Daniel gives an excellent advice: if you for some reason have to rollback, then get a daily-job in a startup instead of a large company. By that time, you should be known in the startup scene, and maybe you go-back for a job without the need to be interviewed. Very good advice.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[SQLFiddle - sharing database problems and their solutions]]></title><description><![CDATA[SQLFiddle - sharing database problems and their solutions]]></description><link>https://bfcamara.com/post/44500610899/sqlfiddle-sharing-database-problems-and-their</link><guid isPermaLink="false">https://bfcamara.com/post/44500610899/sqlfiddle-sharing-database-problems-and-their</guid><pubDate>Mon, 04 Mar 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you are a web developer, probably you know &lt;a href=&quot;jsFiddle.net&quot; title=&quot;jsFiddle&quot; target=&quot;_blank&quot;&gt;jsFiddle&lt;/a&gt;. If you don&apos;t know you can always start play with it today. &lt;strong&gt;jsFiddle it&apos;s an online playground tool where you can test your javascript/css/html problems and share it with others&lt;/strong&gt;. Many StackOverflow answers, the answers site for developers, include a link to jsFiddle to demonstrate a problem and/or a solution. jsFiddle became very popular among web developers. There are other online playground tools, but they are tipically focused in just &amp;nbsp;one technology, HTML or CSS or Javascript. jsFiddle combines the three.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Until recently, I didn&apos;t know any tool similar with jsFiddle, but focused on database problems. But there is! It&apos;s the &lt;a href=&quot;http://sqlfiddle.com&quot; title=&quot;SQL Fiddle&quot; target=&quot;_blank&quot;&gt;SQLFiddle&lt;/a&gt;. &amp;nbsp;And if you use jsFiddle you start to recognize the similarities, and in seconds you start to use SQLFiddle without problems&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The other day I was talking with a guy, who started testing my SQL knowledge and asked me to solve a problem.&lt;/p&gt;
&lt;p&gt;Here is the problem:&lt;br /&gt; &lt;br /&gt;If you have a table with a date column and an int column, write a query which gives me the interval start date and end date, and the sum of the values for the interval. In other words, if we have these records in table&lt;br /&gt;&lt;br /&gt; Dt1, 5&lt;br /&gt; Dt2, 6&lt;br /&gt; Dt3, 2&lt;br /&gt; Dt4, 8&lt;br /&gt; &lt;br /&gt; I want the result&lt;br /&gt; &lt;br /&gt; Dt1, Dt2, 11 (5+6)&lt;br /&gt; Dt2, Dt3, 8 (6 + 2)&lt;br /&gt; Dt3, Dt4 10 (2 + 8)&lt;/p&gt;
&lt;p&gt;The problem was not new for me, since I already had to face it in real life. In this new version of Sql Server 2012 we have to functions &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/hh213125.aspx&quot; title=&quot;Lead (T-SQL)&quot; target=&quot;_blank&quot;&gt;Lead&lt;/a&gt; and &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/hh231256.aspx&quot; title=&quot;Lag (T-SQL)&quot; target=&quot;_blank&quot;&gt;Lag&lt;/a&gt; that we can use to solve the problem without having to &amp;nbsp;think too much. So my first answer was &lt;em&gt;&quot;Can I assume that I am using a Sql Server 2012?&quot; &amp;nbsp;&lt;/em&gt;&lt;span&gt;The guy is a MySql guy, so he answered me &lt;/span&gt;&lt;em&gt;&quot;No. Write a query that we can port to another database without too much effort&quot;&lt;/em&gt;&lt;span&gt;.&amp;nbsp;&lt;/span&gt;&lt;span&gt;So, I wrote the query on paper, which consists of a self join combined with the use of &amp;nbsp;row_number() function.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; The guy looked to the query and didn&apos;t recognize the row_number() function. Then he show me a query using his approach with MySql.&lt;br /&gt; &lt;br /&gt; None of us had our laptop, prepared with the tools to show the solution to each other using a real database instance.&amp;nbsp;&lt;span&gt;We could use SQLFiddle to show the solution to each other.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;BTW, &lt;a href=&quot;http://sqlfiddle.com/#!6/b5d9a/2&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; is the solution without using Lead and Lag&amp;nbsp;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[A Customer is your MVP]]></description><link>https://bfcamara.com/post/43388500459/a-customer-is-your-mvp</link><guid isPermaLink="false">https://bfcamara.com/post/43388500459/a-customer-is-your-mvp</guid><pubDate>Mon, 18 Feb 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://unicornfree.com/2013/a-customer-is-your-mvp-a-video-talk-on-making-products-that-sell&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://unicornfree.com/2013/a-customer-is-your-mvp-a-video-talk-on-making-products-that-sell&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Great session from &lt;a href=&quot;http://unicornfree.com&quot; title=&quot;Amy Hoy - Unicorn Free&quot; target=&quot;_blank&quot;&gt;Amy Hoy&lt;/a&gt;, where she talks on making products that sell. Her advice: don&apos;t look for an idea. Look for an audience; understand and know your audience; kill a pain of your audience with a unique selling proposition (USP).&amp;nbsp;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[The 4 Personality Types Every Startup Needs]]></description><link>https://bfcamara.com/post/42090161740/the-4-personality-types-every-startup-needs</link><guid isPermaLink="false">https://bfcamara.com/post/42090161740/the-4-personality-types-every-startup-needs</guid><pubDate>Sat, 02 Feb 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://onstartups.com/tabid/3339/bid/94858/The-4-Personality-Types-Every-Startup-Needs.aspx&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://onstartups.com/tabid/3339/bid/94858/The-4-Personality-Types-Every-Startup-Needs.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A great post from Dharmesh Shah, on &lt;a href=&quot;http://onstartups.com&quot; title=&quot;OnStartups &quot; target=&quot;_blank&quot;&gt;OnStartups&lt;/a&gt;, where &amp;nbsp;he identifies the 4 most important startup personalities to build an unbeatable team:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Beast (The X-men), who has a &quot;get shid done&quot; mentality&lt;/li&gt;
&lt;li&gt;Lara Croft, with an adventurer and entrepreneurial spirit&lt;/li&gt;
&lt;li&gt;The Architect (the character from the Matrix), who understands the big picture and can still focus on the details.&lt;/li&gt;
&lt;li&gt;The Most Interesting Man in the World, with character, charm, and adds depth to the company culture.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Worth reading.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[WebHooks testing tools: Requestb.in and LocalTunnel]]></title><description><![CDATA[WebHooks testing tools: Requestb.in and LocalTunnel]]></description><link>https://bfcamara.com/post/41699252979/webhooks-testing-tools-requestbin-and</link><guid isPermaLink="false">https://bfcamara.com/post/41699252979/webhooks-testing-tools-requestbin-and</guid><pubDate>Mon, 28 Jan 2013 00:00:00 GMT</pubDate><content:encoded>&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p&gt;&lt;strong&gt;The goal of this post is to show how we can use the tools &lt;a href=&quot;http://requestb.in/&quot; title=&quot;Requestb.in - Inspect HTTP requests&quot; target=&quot;_blank&quot;&gt;Requestb.in&lt;/a&gt; and &lt;a href=&quot;http://progrium.com/localtunnel/&quot; title=&quot;localtunnel - share localhost to the world&quot; target=&quot;_blank&quot;&gt;LocalTunnel&lt;/a&gt; to make it easier the process of testing WebHooks integration.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;WebHooks offer an easy and elegant way for applications and services to integrate with one another. There is a trend that we have been watching in the last years, which consists in having an interconnected set of loosely coupled cloud services, talking to each other via HTTP. &lt;strong&gt;The term &quot;webhooks&quot; was introduced by &lt;a href=&quot;http://progrium.com&quot; title=&quot;Jeff Lindsay web site&quot; target=&quot;_blank&quot;&gt;Jeff Lindsay&lt;/a&gt; in 2006, as a pattern in web architecture.&lt;/strong&gt; Both services, RequestBin and LocalTunnel were created by Jeff.&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;Today there are a lot of cloud services which already offer WebHook integration, such as &lt;a href=&quot;https://zapier.com/zapbook/webhook&quot; title=&quot;Zapier webhooks integration&quot; target=&quot;_blank&quot;&gt;Zapier&lt;/a&gt;, &lt;a href=&quot;http://developer.uservoice.com/docs/service-hooks/introduction/)&quot; title=&quot;UserVoice - WebHooks Integration&quot; target=&quot;_blank&quot;&gt;UserVoice&lt;/a&gt;, &lt;a href=&quot;http://webhooks.wordpress.com/2009/01/22/zendesk-targets-are-web-hooks/&quot; title=&quot;ZernDesk - webhooks integration&quot; target=&quot;_blank&quot;&gt;ZenDesk&lt;/a&gt;, &lt;a href=&quot;https://help.github.com/articles/post-receive-hooks&quot; title=&quot;GitHub - webhooks integration&quot; target=&quot;_blank&quot;&gt;GitHub&lt;/a&gt;, etc.&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;The idea is quite simple. Taking the UserVoice as an example, when a new Ticket is posted on my UserVoice, I want to trigger an HTTP call to my CRM system to create a case and record the customer interaction on it. This is a typical use case of a webhook integration.&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;&lt;span&gt;Here is the screen of user voice where I am defining the WebHook integration&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;448&quot; data-orig-width=&quot;500&quot;&gt;&lt;img alt=&quot;image&quot; src=&quot;https://66.media.tumblr.com/807997727593365145d09169d7e0b0d7/30b06b4f6185de41-4b/s540x810/c13ec5933124b26f1034c1ca535ef1856cc843fa.png&quot; data-orig-height=&quot;448&quot; data-orig-width=&quot;500&quot;&gt;&lt;/figure&gt;&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;A WebHook is just an HTTP callback sent to a URL, defined by the user in response to an event.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;&lt;strong&gt;When I started to develop this kind of webhook integrations I felt the need to have a quick way to have real examples of the POST messages. The first Cloud service that I used to have this reals messages is Requestb.in.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;RequestBin lets me create a URL that will collect requests made to it, for further inspection in a human-friendly way. With RequestBin you can look at webhook requests. Here as an example of a request made in response to a new suggestion on the UserVoice site.&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;368&quot; data-orig-width=&quot;500&quot;&gt;&lt;img alt=&quot;image&quot; src=&quot;https://66.media.tumblr.com/a600d6f301ab19507130b95cbe24cdd7/30b06b4f6185de41-25/s540x810/dab0ac99c4f570082dc20ddb24a90bee5d8e8e8e.png&quot; data-orig-height=&quot;368&quot; data-orig-width=&quot;500&quot;&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;br&gt;&lt;div&gt;
&lt;p&gt;With Requestb.in you have a quick way to inspect the HTTP request that you have to handle.&amp;nbsp;&lt;span&gt;&lt;strong&gt;But what I really like is to have a way to test the WebHook in my local machine, which means that I have to expose my web server to the world&lt;/strong&gt;, which in some scenarios it&apos;s not easy (firewall, NATs, etc.). &lt;strong&gt;We can use an easy way with &lt;a href=&quot;http://progrium.com/localtunnel/&quot; title=&quot;LocalTunnel&quot; target=&quot;_blank&quot;&gt;LocalTunnel&lt;/a&gt; to solve this problem.&lt;/strong&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;To use localtunnel, I need to install it in my local machine. Following the instructions on site, I rapidly noticed that I need Ruby and RubyGems, which I don&apos;t have it installed. Alternatively, and if I use version 2, I need to have Python, since the client is written in Python.&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;You can just skip this installation and use localtunnel for windows, which is written in C#, and &lt;a href=&quot;https://github.com/danielrmz/localtunnel-net-client&quot; title=&quot;.Net client for LocalTunnel service&quot; target=&quot;_blank&quot;&gt;available on GitHub&lt;/a&gt;. That&apos;s what I did. &amp;nbsp;In a further post I will show the how to use LocalTunnel on IIS Express.&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Maybe a not well known GO statement in Sql Server Management Studio]]></title><description><![CDATA[Maybe a not well known GO statement in Sql Server Management Studio]]></description><link>https://bfcamara.com/post/40595247187/maybe-a-not-well-known-go-statement-in-sql-server</link><guid isPermaLink="false">https://bfcamara.com/post/40595247187/maybe-a-not-well-known-go-statement-in-sql-server</guid><pubDate>Tue, 15 Jan 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recently it was launched a new blog targeted to the community involved with Microsoft Sql Server (&lt;a href=&quot;http://www.sql.pt&quot; title=&quot;sql.pt&quot; target=&quot;_blank&quot;&gt;www.sql.pt&lt;/a&gt;). The blog was launched by a friend of mine, Pedro Correia,  which is a Sql Server 2008 Microsoft Certified Master (I think it&apos;s the only one in Portugal).&lt;/p&gt;&amp;#13;
&lt;p&gt;Well, first of all let me say that I consider myself a guy which is well above the average in terms of Sql Server and T-SQL. Since the beginning of my career, which was in 1999, I had to deal with Sql Server and I have been involved in projects that I had to understand the internals and write all the T-SQL by hand.&lt;/p&gt;&amp;#13;
&lt;p&gt;I was reading a blog post on this new blog when I saw this snippet of code&lt;/p&gt;&amp;#13;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;TABLE&lt;/span&gt; T1 &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;C1 &lt;span class=&quot;token keyword&quot;&gt;INT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
GO
&lt;span class=&quot;token keyword&quot;&gt;INSERT&lt;/span&gt; t1 &lt;span class=&quot;token keyword&quot;&gt;SELECT&lt;/span&gt; CAST&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;RAND&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;AS&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;INT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
GO &lt;span class=&quot;token number&quot;&gt;27&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;INSERT&lt;/span&gt; t1 &lt;span class=&quot;token keyword&quot;&gt;VALUES&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;310&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;450&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;945&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt; &lt;/span&gt;&lt;/div&gt;&amp;#13;
&lt;p&gt;At first glance, there is one thing in this script that surprised me a lot:&lt;/p&gt;&amp;#13;
&lt;p&gt;&lt;strong&gt;   GO 27&lt;/strong&gt;&lt;/p&gt;&amp;#13;
&lt;p&gt;My first reaction was, this script doesn&apos;t  run, since the syntax it&apos;s not valid. I copied and pasted to my Management Studio, with a connection to a Sql Server 2012, and Bang! It runs! Basically it runs 27 times the insert that precedes this GO statement.&lt;/p&gt;&amp;#13;
&lt;p&gt;Oh my god: how I couldn&apos;t know this? I checked the&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms188037.aspx&quot; title=&quot;GO statement documentation&quot; target=&quot;_blank&quot;&gt; documentation of the GO statement&lt;/a&gt;  and here what I read&lt;/p&gt;&amp;#13;
&lt;blockquote&gt;&amp;#13;
&lt;p&gt;&lt;em&gt; GO [count]&lt;br /&gt;&lt;br /&gt;  count      Is a positive integer. The batch preceding GO will execute the specified number of times.&lt;/em&gt;&lt;/p&gt;&amp;#13;
&lt;/blockquote&gt;&amp;#13;
&lt;p&gt;&lt;strong&gt;I felt so frustrated because I didn&apos;t know about this optional argument that I started to check the documentation of previous versions&lt;/strong&gt;. Basically I was trying to justify my ignorance. The Sql Server 2005 already supported this syntax. Got dammit! However, the documentation available for Sql Server 2000 in &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa258908(v=sql.80).aspx&quot; title=&quot;GO statement documentation in Sql Server 2000&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; does not reference any optional count argument. Well, I don&apos;t have a chance to test a Sql Server 2000 right now, but I believe that this is something that was introduced with the Sql Server 2005. I started my career with Sql Server 7...bla..bla..bla... No excuses! I am an ignorant! But I didn&apos;t remember to be presented to this feature.&lt;/p&gt;&amp;#13;
&lt;p&gt;&lt;strong&gt;The fact is that this optional count argumenf of GO statement it&apos;s useful, particular when testing some situations in Management Studio, when we need to load some data for the tests being run. We can always use a while statement to do some repetitions, although this GO [count] it&apos;s much more elegant.&lt;/strong&gt;&lt;/p&gt;&amp;#13;
&lt;p&gt;&lt;strong&gt;As a final remark, the GO is not a Transact-SQL statement; it is a command recognized by the sqlcmd and osql utilities and SQL Server Management Studio Code editor.&lt;/strong&gt;&lt;/p&gt; </content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Failed Entrepreneur]]></description><link>https://bfcamara.com/post/38374747844/failed-entrepreneur</link><guid isPermaLink="false">https://bfcamara.com/post/38374747844/failed-entrepreneur</guid><pubDate>Thu, 20 Dec 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://blog.bahadir.io/posts/failed-entrepreneur.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://blog.bahadir.io/posts/failed-entrepreneur.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Great post about the reasons why Bahadir thinks he had failed as an entrepreneur. Every item of this list it&apos;s a lesson to all of us, who wishes to follow this path.&lt;/p&gt; </content:encoded></item><item><title><![CDATA[The Mini Sales Site approach as the first MVP when developing a SaaS application]]></title><description><![CDATA[The Mini Sales Site approach as the first MVP when developing a SaaS application]]></description><link>https://bfcamara.com/post/37713680937/the-mini-sales-site-approach-as-the-first-mvp-when</link><guid isPermaLink="false">https://bfcamara.com/post/37713680937/the-mini-sales-site-approach-as-the-first-mvp-when</guid><pubDate>Tue, 11 Dec 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 88.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAACXBIWXMAAAsTAAALEwEAmpwYAAADcElEQVQ4y32U61NaRxjGCVCPiGiAicSiQoIIHi6Sg6ACB49NEEQleEClsdYYoomKyCQZo9NpmHTSNmqaL7k4mVzamXzITCb5B3qx/cv26ewiDFrthz17Ofs+83ved3cVveEMnCEZ1d4zPIs+KQevlEPfSA6+ka/h+6rS6JzucYYy6A3LcIYzLK6+KZgY2ySDj0zD1OVAq6ENhnNmGE0dMLaZce58J4wmMzqtPbgkTcMxJDPBKkQVqCbIFiLT6PYnoNfrYdC3orGRA8c1wKA/y8ZfqNXosdtwo1iG1Z+CS5w+InRMcAqu4RzMjiD6vB7IcgZiNApB8GM0Hkc6nUZEFCHLMjLfFtDhuQLnULpiuy5dRwh5cYbZjYRDGJYkuN1uDAwMQBRFxONxaDQazM3Nob29HQqFAo5AHK5o7nTLfCSDRm0rlGcU0DY3Q6vVQqlUguM4tLS0MJFisYj+/n64Xb24tljAl67L4CPZ/xJSOpsQg1KlYmSCIGBwcBCBQABerxd2ux1GoxG7e7sIBoPI5/OwXbSioakV7sNc1glOMXSz3c8omnU68DzPSDweD0wmE1u3dduwvb3FaMvlMpo0GtxYWoFwZR49g+mjll3iDPRtXSywgeNgsViYaFWMtkQigWg0yqhXVleQmpxAcfsxrP6Jmu2KIB2E0uA0WhaoaWqCwWBgFnU6HcsjXV9augmPx13Jo1/Ava3vcenyNzW6mmVenCUWd5QGkcOG+l6tVrNxqVSCJEnIZrNIjo0hX3qITt8YXJHs0Sq7xFlYnQJRKc9AqVThBFGoVCqysbGBhYUFTE4ksfXgJzjD2dptqRAeCtqCV8nVa7fxy5MdUiqVyPLyMgqFAlldXcH8/DyJxWKEnr+9vT1yM5/H5uYm0gt3YRHGWe6O3xZaFELP4INHT8iLF89IcX0NkjRMfD4fRiSJZGSZ3Lq1THNHfnz0A+6Xd3AhkDpRjAnSjyMkE4qcWbyHV79+IAcHB9h/+Zwkk2Os4tT++noBHz99xlDyOrqDKfAnvDQ1wspEJhZhnHT6kkjMrpH9dx/w+x9/kjevXxF6/v75+y9y/+FTdNBCnPIw1AirP6kNWrWL/ZPo6EsgMrGIO9/9jMc7u3j723v2JjqGpuoKccprc3wDExazsAVT6BLGMTqzhlj2Nmz/k7uq4L/GU2LRKMOIQwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/c0b3752e8b5f4249ee75f9194721a136/8ac56/ea3d3eabaa3bd4c65566a73d60f37b127a8c251d83d2da0cc865257d96036ffa.webp 240w,
/static/c0b3752e8b5f4249ee75f9194721a136/d3be9/ea3d3eabaa3bd4c65566a73d60f37b127a8c251d83d2da0cc865257d96036ffa.webp 480w,
/static/c0b3752e8b5f4249ee75f9194721a136/b0a15/ea3d3eabaa3bd4c65566a73d60f37b127a8c251d83d2da0cc865257d96036ffa.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/c0b3752e8b5f4249ee75f9194721a136/8ff5a/ea3d3eabaa3bd4c65566a73d60f37b127a8c251d83d2da0cc865257d96036ffa.png 240w,
/static/c0b3752e8b5f4249ee75f9194721a136/e85cb/ea3d3eabaa3bd4c65566a73d60f37b127a8c251d83d2da0cc865257d96036ffa.png 480w,
/static/c0b3752e8b5f4249ee75f9194721a136/0b533/ea3d3eabaa3bd4c65566a73d60f37b127a8c251d83d2da0cc865257d96036ffa.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/c0b3752e8b5f4249ee75f9194721a136/0b533/ea3d3eabaa3bd4c65566a73d60f37b127a8c251d83d2da0cc865257d96036ffa.png&quot; alt=&quot;Start Small, Stay Small from Rob Walling&quot; title=&quot;Start Small, Stay Small from Rob Walling&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;A &lt;a href=&quot;http://theleanstartup.com/principles&quot; title=&quot;Lean Startup Principles: MVP&quot; target=&quot;_blank&quot;&gt;minimum viable product&lt;/a&gt; (MVP) is a core concept of the&lt;a href=&quot;http://theleanstartup.com/&quot; title=&quot;The Lean Startup Movement&quot; target=&quot;_blank&quot;&gt; Lean Startup&lt;/a&gt; movement. The MVP is that version of the product that enables a team to test and validate the fundamental hypotheses (the leap-of-faith assumptions) and help entrepreneurs begin the learning process as quickly as possible, allowing a full turn of the&lt;a href=&quot;http://theleanstartup.com/principles&quot; title=&quot;Lean Startup Principles: Build-Measure-Learn&quot; target=&quot;_blank&quot;&gt; Build-Measure-Learn&lt;/a&gt; loop with a minimum amount of effort and the least amount of development time. But when the time arrives to get your your hands dirty, it remains the question: &lt;strong&gt;How minimum is the minimum in MVP?&lt;/strong&gt; It&apos;s not an easy question to answer.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;We know that the MVP will &amp;nbsp;lack many features that may prove essential later on. And since &lt;strong&gt;we are trying to validate our hypotheses and measure the impact of the product&lt;/strong&gt;, we will need to build something that we can measure from. And the first metric that we need to know is: &lt;strong&gt;do we have buyers for our product?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In my continuous learning process about startups and how to bootstrap, &amp;nbsp;I read the &amp;nbsp;book &lt;a href=&quot;http://www.startupbook.net/&quot; title=&quot;Start Small, Stay Small&quot; target=&quot;_blank&quot;&gt;&quot;Start Small, Stay Small&quot;&lt;/a&gt; from &lt;a href=&quot;http://www.softwarebyrob.com&quot; title=&quot;Software By Rob&quot; target=&quot;_blank&quot;&gt;Rob Walling&lt;/a&gt;, which I strongly recommend for those who pursuit the &lt;a href=&quot;http://changethis.com/manifesto/80.03.MicropreneurManifesto/pdf/80.03.MicropreneurManifesto.pdf&quot; title=&quot;Micropreneur Manifesto&quot; target=&quot;_blank&quot;&gt;Micropreneur&lt;/a&gt; lifestyle. &amp;nbsp;In this book I learned a new approach, which seems to me to fit in the MVP concept boundaries: &lt;strong&gt;The Mini Sales Site&lt;/strong&gt;. The main idea of this approach is to reduce uncertainty &amp;nbsp;about the conversion rate, and whether or not the prospect would buy our product.&lt;/p&gt;
&lt;p&gt;Asking to a&amp;nbsp;potential&amp;nbsp;customer &quot;You will buy my product?&quot; in a survey, or even building a Landing page asking for an email in case he is interested in the product, it&apos;s seems not enough and &amp;nbsp;provide us with inaccurate data.&lt;/p&gt;
&lt;p&gt;The Mini Sales Site is a stripped version of what will be the Sales Site. &lt;strong&gt;This approach will force us to think how to market our product, even before we start coding&lt;/strong&gt;. A few years ago I thought that the most important think to get the path to success it was the quality of the product itself. Don&apos;t get me wrong: a product with quality it&apos;s important (although quality in the context of software development, among developers, it&apos;s usually associated how clean is the code, and how beautiful patterns were used in the solution, etc., which it&apos;s not a correct definition btw), but marketing is more important in my opinion.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The Mini Sales Site consists of 2 or 3 pages:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Home&lt;/li&gt;
&lt;li&gt;Tour (optional)&lt;/li&gt;
&lt;li&gt;Pricing and Sign-up&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;The Home and Tour page will enumerate the benefits (better to enumerate the benefits rather the features) of using the product, screen shots and/or videos, the full product information, &lt;strong&gt;and most important a call to action to try the button &apos;Try Now&apos; button&lt;/strong&gt;.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The Pricing and Sign-up page will contain the prices and the different editions availabe of the SaaS application, with call to action buttons &quot;Try Now&quot; or &quot;Select Plan&quot;.&lt;/p&gt;
&lt;p&gt;Next we create an AdWords Campaign, configured with our keywords, and send the targeted traffic to our Mini Sales Site.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When someone clicks on &quot;Try Now&quot; or &quot;Select Plan&apos;, we will notify the prospect that the product is under development yet and will be available soon, asking for the email address to notify him when the product will be available.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We should also have configured the AdWord conversions, &amp;nbsp;to know which keyword was converted and the &amp;nbsp;money spent on each conversion.&lt;/p&gt;
&lt;p&gt;Of course I have mixed feelings about this approach, since it seems that I am fooling my prospect. But in fact, the most people on the web are browsing, and if the user it&apos;s not interested in the product, he will bounce, leaving the mini sales immediately . If they are interested, maybe they don&apos;t mind to sign up for a launch notification.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;At the end of the day, with this approach you can measure the searches performed with the keywords defined in AdWords, which keywords converted, and have a rough estimate of the conversion rate.&lt;/strong&gt; We get this with a small investment, including the AdWord campaign, the development and design of the HTML pages of the mini sales site, and the screen-shots of the application if we have it.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In summary, I would like to say that the Mini Sales Site it seems to me a valid approach for those that who desire to build an MVP for SaaS applications, without much investment involved. It can be the first iteration of the Build-Measure-Learn loop, without compromising the next iterations.&lt;/strong&gt;&lt;/p&gt; </content:encoded></item><item><title><![CDATA[EF5: Entity Framework cache problems]]></title><description><![CDATA[EF5: Entity Framework cache problems]]></description><link>https://bfcamara.com/post/37112709703/ef5-entity-framework-cache-problems</link><guid isPermaLink="false">https://bfcamara.com/post/37112709703/ef5-entity-framework-cache-problems</guid><pubDate>Mon, 03 Dec 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The majority of ORMs supports a first-level cache (L1), common named as &quot;identity cache&quot;. Basically, if we request the same entity twice &amp;nbsp;by its ID, it doesn&apos;t require a new round-trip to the database. EF5 is no exception, and provide us with the method &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/gg696418(v=vs.103).aspx&quot; target=&quot;_blank&quot;&gt;Find()&lt;/a&gt; on the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/gg696460(v=vs.103).aspx&quot; target=&quot;_blank&quot;&gt;DbSet&amp;lt;T&amp;gt;&lt;/a&gt; class. From the documentation we have that Find&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Uses the primary key value to attempt to find an entity tracked by the context. If the entity is not in the context then a query will be executed and evaluated against the data in the data source, and null is returned if the entity is not found in the context or in the data source. Note that the Find also returns entities that have been added to the context but have not yet been saved to the database.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Given that, if I make the call&lt;/p&gt;
&lt;div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Contacts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;I know what is the expected behavior. The main problem exists with this code below&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;//Get the contact for Id=1&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; contact &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Contacts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;First&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ContactId &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
Console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;The Current Name is: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; contact&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//Update the contact in the same session without using the context tracking&lt;/span&gt;
db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Database&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ExecuteSqlCommand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;update dbo.Contacts set Name = &apos;Filipe&apos; where ContactId = 1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//Get the contact again&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; updatedContact &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Contacts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;First&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ContactId &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;The Updated Name is: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; updatedContact&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Assuming that the initial name is André, what do you think is the output of this code? Here is the output&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;148&quot; data-orig-width=&quot;500&quot;&gt;&lt;img src=&quot;https://66.media.tumblr.com/c6aa00b9aeebe99e9f98ea3f74a88fbd/2f6b4eb2bd18dd10-c7/s540x810/1744f857aaba6d0e20edbdf0e4cdf03280f01d08.png&quot; data-orig-height=&quot;148&quot; data-orig-width=&quot;500&quot;&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;To be honest, this is not what I expected to see. I was expecting to see André followed by Filipe.&lt;/p&gt;
&lt;p&gt;After looking at the code, I thought: well EF is smart enough to see that I am using the same query twice,&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Contacts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;First&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ContactId &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;with the same params, in the same session, and is caching the data, then the 2nd call does not go to the database. Cool, I thought.&lt;/p&gt;
&lt;p&gt;Let&apos;s confirm with the SQL profiler, expecting to see just one query&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;186&quot; data-orig-width=&quot;500&quot;&gt;&lt;img src=&quot;https://66.media.tumblr.com/e5cde9cec95feb7ebd16d5c9dc16b998/2f6b4eb2bd18dd10-f6/s540x810/b6f4f499c02ee7d98d57d7c707e1ae39f238362f.png&quot; data-orig-height=&quot;186&quot; data-orig-width=&quot;500&quot;&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I was totally wrong. The EF goes to database twice, getting the contact by Id. However, EF does not refresh the entity that is in context. Maybe this a a by design decision, to not sacrifice performance, since it would be required to merge the entity that is currently in context with the entity fetched from the database. However, in my opinion, it&apos;s hard to accept the fact that EF goes to the store to fetch the entity, and does nothing with it if the entity already exists in context.&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;To get the updated entity in context, we have two options :&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;1) detach the entity before querying it again&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;IObjectContextAdapter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;db&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ObjectContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Detach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;contact&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;2) Refresh the entity&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;IObjectContextAdapter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;db&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ObjectContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Refresh&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Objects&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;RefreshMode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;StoreWins&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; contact&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;If you opt for the Refresh option, it is not necessary to query again. Here is the final code&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;//get the contact&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; contact &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Contacts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;First&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ContactId &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
Console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;The Current Name is: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; contact&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//update using ExecuteSqlCommand&lt;/span&gt;
db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Database&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ExecuteSqlCommand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;update dbo.Contacts set Name = &apos;Filipe&apos; where ContactId = 1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//Refresh the entity&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;IObjectContextAdapter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;db&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ObjectContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Refresh&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;System&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Objects&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;RefreshMode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;StoreWins&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; contact&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;WriteLine&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;The Updated Name is: &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; contact&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Here is the ouput&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;130&quot; data-orig-width=&quot;500&quot;&gt;&lt;img src=&quot;https://66.media.tumblr.com/51dfe076c6fb2f35c092f4ad9cc6fe45/2f6b4eb2bd18dd10-f4/s540x810/d881ce3f6f2dd553a7d8d6fa6c8360f1bd2d7680.png&quot; data-orig-height=&quot;130&quot; data-orig-width=&quot;500&quot;&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;This a warning to all readers that can have this situation in a project, for example, when in the same context execute a stored procedure that modify entities that are already loaded in the current EF context, and for some reason you need to refresh the entities. Do not assume that by seeing the statement in the SQL profiler that EF will merge the data in context.&lt;/p&gt;

&lt;div&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;&lt;br&gt;&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Samsara on Software Development]]></title><description><![CDATA[Samsara on Software Development]]></description><link>https://bfcamara.com/post/36589389190/samsara-on-software-development</link><guid isPermaLink="false">https://bfcamara.com/post/36589389190/samsara-on-software-development</guid><pubDate>Mon, 26 Nov 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 57.08333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAACZElEQVQoz3WT609ScRjHfwfEA0cuCoqYh4ugpwMDQW5HETlA4lHxgqlQXnKFW27laLbaqq2t9aI/+9PEps3Vi+/2fLfntj2fRwgheCy7TSKeCuOc9A79/Owoz4wQQnIMvc0m8a+6P7oLfJIgaBeoNsFO2s/Z5TqFeoalosaRNcO3iwxbKzoer3OYP2K3EXVKZGSBJgukxw3VaRel2BjZSRudbJCP13Xen8T5etPi8/U6Z60Fvp+W6OznaFcVLq0QldgY7ZQH/+0yEw6SCRfC7rCz1kzTfWex1W+SLsRYmnJR6VZZbUbJrMzTaJc5rKgU83P0zlfJm7Mc10LUnnrYLvuJyTKtRR+HVgCxEHDTa2domBp77Sxnhwb1cYGuSMRHBRGfzFw8QG85QLG9RM5aRM7EOTBVNtM+Ost+akEPXyyVatGLqDlHOM656FpeLEOh3yuzuzDBTk1jt66zsarRKMfoLgdZTPho5YM8N8Ns5wLki2GKrSQhPYrZjLBZcSNWgm7WM9O8SI2wqzsZnFbZURWudjRuXub49KrAz4sspubBP6Fwslfgx6DNWcdgY6vAVHSamB7BNDU2a1HEk1iQzm6W1+0o3W2NwaVFxSthaOMcpMbphAQnCZliSuXt1RaXbxoYGwYzCZX+cZV9PcKHVp5zM0tSCz9c2aMlKOzV6XUMri4arGwbxHPzJAtzxCdd9DfS/Bo02Yy4ySp2Si6Z/ppKKaAwIwSBe2yku2DUrRCIDydgrWfQlxIc7VcplnTkW7gVQSU5htdlu+NQCKJ+B3bHA+SS9BeHjz/lPun/H3Ev21/+N4A7OCBWuiC2AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/01cf144783caab46273ecad2fc232c58/8ac56/68d0b300758fce401b8d92bc75d7a1d45c9e9aa522cf465205efe01c19b7844e.webp 240w,
/static/01cf144783caab46273ecad2fc232c58/d3be9/68d0b300758fce401b8d92bc75d7a1d45c9e9aa522cf465205efe01c19b7844e.webp 480w,
/static/01cf144783caab46273ecad2fc232c58/b0a15/68d0b300758fce401b8d92bc75d7a1d45c9e9aa522cf465205efe01c19b7844e.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/01cf144783caab46273ecad2fc232c58/8ff5a/68d0b300758fce401b8d92bc75d7a1d45c9e9aa522cf465205efe01c19b7844e.png 240w,
/static/01cf144783caab46273ecad2fc232c58/e85cb/68d0b300758fce401b8d92bc75d7a1d45c9e9aa522cf465205efe01c19b7844e.png 480w,
/static/01cf144783caab46273ecad2fc232c58/0b533/68d0b300758fce401b8d92bc75d7a1d45c9e9aa522cf465205efe01c19b7844e.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/01cf144783caab46273ecad2fc232c58/0b533/68d0b300758fce401b8d92bc75d7a1d45c9e9aa522cf465205efe01c19b7844e.png&quot; alt=&quot;image&quot; title=&quot;image&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;One of the books that touched me deeply was &lt;a href=&quot;http://www.amazon.com/Siddhartha-Hermann-Hesse/dp/1613823789&quot; title=&quot;Siddhartha&quot; target=&quot;_blank&quot;&gt;&quot;Siddhartha&quot;&lt;/a&gt;, a novel written by Herman Hesse . I wish I had been aware of this book earlier in my life. &lt;strong&gt;What motivates me to write this post, is a concept that this book has introduced me into: Samsara&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Briefly, at some point of his life, around 40, &lt;strong&gt;Siddhartha believed he had fallen into a state of Samsara, which in Sanskrit (the primary liturgical language of Hinduism) means ignorance and confusion&lt;/strong&gt;. Siddhartha, an extremely spiritual person in his childhood, was becoming an ordinary person in a gradual way. He became materialistic and ostentatious, practicing vices like drinking, gambling, etc.. He was obfuscating and denying his spirituality with mundane activities. Throughout all these years of &quot;success&quot; with signs of great wealth, the life of Siddhartha was in fact shrinking in terms of meaning. One day, Siddhartha gets tired of his life, one that he consiedred as empty and meaningless, and decides to return to a path of spirituality. It&apos;s this state of confusion that Siddhartha defines as Samsara.&lt;/p&gt;
&lt;p&gt;In terms of software development, I believe we (as an industry) are also in a Samsara. At least for me, &lt;strong&gt;sometimes I am really confused with all the technologies I can use, and with the speed that things changes&lt;/strong&gt;. We, as developers, love technology, and tend to wish to experience the ultimate edge technology in our project. The market players themselves, such as companies that sell software for developers or open source communities, send us updates and new products in very short time cycles. And we, as lovers of technology, are continually pursuing them. I understand that this is a way to influence the the market in terms of supply, which otherwise would stagnate. &lt;strong&gt;But the real question I want to ask is: are we really producing better software than 20 years ago? All this volatility and “wealth” in our development toolbox allows us to actually produce better software?&lt;/strong&gt; Maybe not! Eventually we are producing software that is more complex, but is this all complexity really necessary?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I think that we have lost the north by amusing ourselves with technological onanistic practices, which don’t contribute to the improvement of software development&lt;/strong&gt;. Undoubtedly its really cool to use X or Y, and at the end of day we can eventually add a few more skills on LinkedIn profile. “Yeah, I am really geek!” But the thing is, why do we write software? Yes, Why we do write software? We (should) write software to achieve a particular goal, typically the resolution of a problem for those who will use it. &lt;strong&gt;And one thing is certain, if someone pays us to write software, that same person wishes to get their money back (Return on Investment) in the form of value&lt;/strong&gt;. Typically, he/she doesn&apos;t care about the technology stack used to developed it. Instead, we should be concerned in solving their problem(s), and ensuring that what we produce has a low maintenance cost, and a quick resolution time on error situations. With this in mind, I agree with Jack Dorsey, founder of Twitter and Square, who wrote a few weeks ago a &lt;a href=&quot;http://jacks.tumblr.com/post/33785796042/lets-reconsider-our-users&quot; title=&quot;Lets reconsider our users&quot; target=&quot;_blank&quot;&gt;post &lt;/a&gt;“Let’s reconsider our users”, where he mentions&amp;nbsp;&lt;/p&gt;
&lt;p&gt;“ all of our work is in service of our customers. Period.”&lt;/p&gt;
&lt;p&gt;He goes further, and he decide to abandon the term ‘User’, replacing it everywhere in Square by the term “Customer”.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Many times,we throw more technology into to the solution, just because, or just because the community says so, or because I&apos;m a fantastic geek. The truth is: this doesn’t solves anything, zero, nada, zilch.&lt;/strong&gt; Worse: it&apos;s one more technology that will have to be maintained and learned.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;And with all this technological Samsara, we are dazzled, and lose focus from our goal: to solve the customer problem.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;But do not worry, I&apos;m sure that one more month, some company will &amp;nbsp;release a new IDE &amp;nbsp;or a new Framework to the market that will solve all of our problems.....&lt;/p&gt;
&lt;p&gt;Let&apos;s get more focused, and nominate yourself as a &quot;Problem Solver&quot;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[The Startup’s Guide to Budget Design]]></description><link>https://bfcamara.com/post/35123890064/the-startups-guide-to-budget-design</link><guid isPermaLink="false">https://bfcamara.com/post/35123890064/the-startups-guide-to-budget-design</guid><pubDate>Tue, 06 Nov 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://blog.folyo.me/the-startups-guide-to-budget-design/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://blog.folyo.me/the-startups-guide-to-budget-design/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</content:encoded></item><item><title><![CDATA[How-to: 0-legged OAuth with DotNetOpenAuth]]></title><description><![CDATA[How-to: 0-legged OAuth with DotNetOpenAuth]]></description><link>https://bfcamara.com/post/34630752066/how-to-0-legged-oauth-with-dotnetopenauth</link><guid isPermaLink="false">https://bfcamara.com/post/34630752066/how-to-0-legged-oauth-with-dotnetopenauth</guid><pubDate>Tue, 30 Oct 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;/p&gt;&lt;div&gt;As promissed in &lt;a href=&quot;http://bfcamara.com/post/34158128493/oauth-2-legged-vs-0-legged-uservoice-api-as-an&quot; title=&quot;2-legged vs 0-legged Oauth&quot; target=&quot;_blank&quot;&gt;my previous post&lt;/a&gt;, where I dived in the the difference between a 2-legged and a 0-lgeed oauth, &lt;strong&gt;I will show in this post how to build a 0-legged oauth using the DotNetOpenAuth library&lt;/strong&gt;. Just to remember, a 0-legged oauth consists of a consumer accessing the protected resources submitting oauth signed requests using just the consumer key and the consumer secret.&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;I will take as an example the UserVoice API, the method to list all the users for a given site, which requires a 0-legged API.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;Before you use the UserVoice API or another oauth API from a service provider, &lt;strong&gt;the first thing to to is to get a consumer key and a consumer secret&lt;/strong&gt;. This process is more or less the same in all service providers, but you have to check with the service provider how to get them. Here is a screenshot how I got this data from UserVoice site, in the admin console&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;128&quot; data-orig-width=&quot;500&quot;&gt;&lt;img src=&quot;https://66.media.tumblr.com/7511578c75e07d5fb945398b686f7c3a/50a65bbf97ea6c28-fb/s540x810/d52f917bd638cf7f9339474e98844f22ba9014fe.jpg&quot; data-orig-height=&quot;128&quot; data-orig-width=&quot;500&quot;&gt;&lt;/figure&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;Next, in our visual studio project, we have to get the libraries of dotnetopenauth. Since we are consuming an oauth API, &lt;strong&gt;we have to get the Nuget package DotNetOpenAuth.OAuth.Consumer&lt;/strong&gt;. &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;332&quot; data-orig-width=&quot;500&quot;&gt;&lt;img src=&quot;https://66.media.tumblr.com/40ab5d3ccd5b573684e291174d23aaf8/50a65bbf97ea6c28-38/s540x810/54ba7846f7aae86bf79981cc628610b1d07541df.jpg&quot; data-orig-height=&quot;332&quot; data-orig-width=&quot;500&quot;&gt;&lt;/figure&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;strong&gt;The main class when consuming an API is the class WebConsumer in namespace DotNetOpenAuth.OAuth&lt;/strong&gt;. The constructor of this class receives two arguments as show below&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;WebConsumer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ServiceProviderDescription&lt;/span&gt; serviceDescription&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IConsumerTokenManager&lt;/span&gt; tokenManager&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;strong&gt;&lt;br&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;strong&gt;The serviceDescription defines the endpoints and the behavior of the service provider&lt;/strong&gt;. &lt;strong&gt;The token manager is the component responsible to manage the tokens used by a web site in its role as a consumer&lt;/strong&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;In our case the serviceDescription is something like this&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; providerDesc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;ServiceProviderDescription&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	RequestTokenEndpoint &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;MessageReceivingEndpoint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://bfcamara.uservoice.com/oauth/request_token&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; HttpDeliveryMethods&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;PostRequest&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	AccessTokenEndpoint &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;MessageReceivingEndpoint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://bfcamara.uservoice.com/oauth/access_token&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; HttpDeliveryMethods&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;PostRequest&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    UserAuthorizationEndpoint &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;MessageReceivingEndpoint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://bfcamara.uservoice.com/oauth/authorize&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; HttpDeliveryMethods&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;PostRequest&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ProtocolVersion &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ProtocolVersion&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;V10a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    TamperProtectionElements &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;ITamperProtectionChannelBindingElement&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;HmacSha1SigningBindingElement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;Basically we are describing the oauth endpoints that will be used in the oauth dance, the oauth version, and the signing policy used in the service provider, which in this case is &amp;nbsp;the method HMAC-SHA1 defined in RFC2104.&amp;nbsp;&lt;/span&gt;&lt;strong&gt;Next we have to write our token manager, which must implement the interface IConsumerTokenManager (whic must implement the ITokenManager interface)&lt;/strong&gt;. Using the Alt-F10 Implement Interface of Visual Studio we get the skeleton of our class&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ZeroLeggedTokenManager&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token type-list&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;IConsumerTokenManager&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; ConsumerKey
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;NotImplementedException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; ConsumerSecret
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;NotImplementedException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ExpireRequestTokenAndStoreNewAccessToken&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; consumerKey&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; requestToken&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; accessToken&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; accessTokenSecret&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;NotImplementedException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;GetTokenSecret&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; token&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;NotImplementedException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;TokenType&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;GetTokenType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; token&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;NotImplementedException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;StoreNewRequestToken&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;DotNetOpenAuth&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OAuth&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Messages&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;UnauthorizedTokenRequest&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DotNetOpenAuth&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OAuth&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Messages&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ITokenSecretContainingMessage&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;NotImplementedException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;Since we are using a 0-legged oauth, we have just to worry with the GetTokenSecret method, and the getter properties of our consumer key and consumer secret. Here is the final version of our token manager&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ZeroLeggedTokenManager&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token type-list&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;IConsumerTokenManager&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; _consumerKey&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; _consumerSecret&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ZeroLeggedTokenManager&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; consumerKey&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; consumerSecret&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        _consumerKey &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; consumerKey&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        _consumerSecret &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; consumerSecret&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; ConsumerKey &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; _consumerKey&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; ConsumerSecret &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; _consumerSecret&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ExpireRequestTokenAndStoreNewAccessToken&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; consumerKey&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; requestToken&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; accessToken&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; accessTokenSecret&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;NotImplementedException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;GetTokenSecret&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; token&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;//In a 0-legged conversation only the consumer secret is used to sign the message&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;TokenType&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;GetTokenType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; token&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;NotImplementedException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;StoreNewRequestToken&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;DotNetOpenAuth&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OAuth&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Messages&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;UnauthorizedTokenRequest&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DotNetOpenAuth&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OAuth&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Messages&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ITokenSecretContainingMessage&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;NotImplementedException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;Now we can create our token manager&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; tokenManager &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;ZeroLeggedTokenManager&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;CONSUMER_KEY&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; CONSUMER_SECRET&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;The CONSUMER_KEY and CONSUMER_SECRET are constants which contains the values of the consumer key and secret&amp;nbsp;respectively.&amp;nbsp;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;strong&gt;&lt;br&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;strong&gt;Finally we can create our consumer and use it to make the call, using the method PrepareAuthorizeRequestAndSend&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;cs&quot;&gt;&lt;pre class=&quot;language-cs&quot;&gt;&lt;code class=&quot;language-cs&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; zeroLeggedWebConsumer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;DotNetOpenAuth&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OAuth&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;WebConsumer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;providerDesc&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; tokenManager&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; zeroLeggedWebConsumer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;PrepareAuthorizedRequestAndSend&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token constructor-invocation class-name&quot;&gt;MessageReceivingEndpoint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://bfcamara.uservoice.com/api/v1/users.json&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
       HttpDeliveryMethods&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;GetRequest&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;DUMMY&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;When calling the PrepareAuthorizedRequestToken, we have to pass the endpoint to call, and the token to use, which will be used by the consumer to ask to our token manager what is the secret associated with this token. &lt;strong&gt;There is a little trick here: since our secret is always an empty secret returned by the token manager, it&apos;s quite irrelevant what you pass to the method, however it cannot be null or empty&lt;/strong&gt;, which is not allowed. In our case we pass &quot;DUMMY&quot; as the token. (If you pass an empty or null token you will get an exception at runtime thrown by dotnetopenauth library).&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;Using Fiddler Web Debugger, you can check the content of the request/response&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;346&quot; data-orig-width=&quot;500&quot;&gt;&lt;img src=&quot;https://66.media.tumblr.com/6253cec7b773c3950bedd6e7368000bd/50a65bbf97ea6c28-00/s540x810/50b0440b53be969f5c7c5b59143158858299e2be.jpg&quot; data-orig-height=&quot;346&quot; data-orig-width=&quot;500&quot;&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;Now you can parse the response as you want.&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;strong&gt;Sumarizing, in this post, I demonstrated how to use the DotNetOpenAuth library to consume API&apos;s with a 0-legged OAuth.&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
</content:encoded></item><item><title><![CDATA[OAuth: 2-legged vs 0-legged (UserVoice API as an example)]]></title><description><![CDATA[OAuth: 2-legged vs 0-legged (UserVoice API as an example)]]></description><link>https://bfcamara.com/post/34158128493/oauth-2-legged-vs-0-legged-uservoice-api-as-an</link><guid isPermaLink="false">https://bfcamara.com/post/34158128493/oauth-2-legged-vs-0-legged-uservoice-api-as-an</guid><pubDate>Tue, 23 Oct 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; &quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 99.58333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAAsTAAALEwEAmpwYAAADsElEQVQ4y12US0h6WxTGt2j9dRBqpeajY8fS8HE8J+xGUjSICDKyfGRlAw0xUjPNgeCgQdAkiCwnRkQUjiwaNGlUEARGQpDYgyIIGjSoBgmGPdRzyd3t3ts32Yt9+J291l57fYD8R8VisVAowOD5+TmdTh+XdHZ29vDwAD8VCoVisfiDgF/k6enpwsKCy+WyWCy9vb16vd5mswUCgaWlpWQy+YsHkCRJ8vX1NRKJjI6ONjU1WSwWiUQyNDRkMplwHPd4PBqNxmq1RqPRXC73gwC4ZLPZ+fl5u93u8XhwHHe5XD09PX+V1NDQQBCEwWBwOBxms3l5efnj4wPyAGa7urrqdruZTKbf7zebzWVlZTweT1ySUCgsLy83GAxGo5FGo9lstp2dHZg/gHX6fD6JRAIAoFKpbDZbpVJhGAZhGDOZTFBSbW1tMBi8u7v7rjkcDvf19QEAKBQKm83GMEypVMrl8tnZ2bm5ORjjOF5dXQ35zs7Ozc3NL/j+/t7n88lkMgAAk8lUKpUYholEIr/fD680FAqJRCKVSqVUKuH5KIoGAoFsNguSyaTT6WQwGAAAPp+PlSQQCLa2tiC8t7cnEAhUJfH5fADAnz9/7Hb7zc0NODw8tFqtNBoN/hLDMLlc3tzc/PT0BOFMJtPR0SGTydRqdX19PYQHBwcTiQQ4Ojr6L4zjuEgkstvt8D7z+TxJktPT00KhkCAIFEUhPDw8fHx8DFKp1MTEBJ1Oh2kTBIEgSCwWI0ny4uIinU4Xi8X9/f26ujocx3k8HgCAwWCMj49fX1+Dx8fHmZkZqVQKAGCz2Wq1WiaTvby8HBwcIAjC5XJjsVihUNBqtQqFoqKiAgCgUChCoVAmk/lqVTQa1ev1sMnwhHg87vF4UBSVSqVms3l3d7e1tZXD4VCpVACA2WxeW1v77nMqlZqcnIT1UCiUyspKkUikUCjUajVBECqVSiAQIAgCc0ZRdGpq6vb29guGz3NjY8PpdNLp9MbGxpGRERaLVVVVhSBITU0Nj8djsVhdXV2Li4soitpstu3t7e/nCQcjl8tFo9GxsTGTyRQMBsVicXt7u1gs1uv1Go0mEolwOByTyeRwOFZWVj4/P78HAy7FYvHt7S0ej3u9Xq1WOzAw0N/f39LS4vV6uVyuTqdra2uzWq3r6+vv7+//juSPGcCWXl1dRSIRt9ttNBp1Ol13d7fFYnE4HOFw+Pz8nCTJfD7/PzP4ZSYkSUIbSiQSJycnl5eXmUwG7v+yob8BFrZSbcxiTgYAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/9181d533566e260a77071bb3d0050139/8ac56/f188ae47e7ef202e0f7938896a595a3d28b3d97a940886d65cc1bc1406ba2c60.webp 240w,
/static/9181d533566e260a77071bb3d0050139/d3be9/f188ae47e7ef202e0f7938896a595a3d28b3d97a940886d65cc1bc1406ba2c60.webp 480w,
/static/9181d533566e260a77071bb3d0050139/b0a15/f188ae47e7ef202e0f7938896a595a3d28b3d97a940886d65cc1bc1406ba2c60.webp 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/9181d533566e260a77071bb3d0050139/8ff5a/f188ae47e7ef202e0f7938896a595a3d28b3d97a940886d65cc1bc1406ba2c60.png 240w,
/static/9181d533566e260a77071bb3d0050139/e85cb/f188ae47e7ef202e0f7938896a595a3d28b3d97a940886d65cc1bc1406ba2c60.png 480w,
/static/9181d533566e260a77071bb3d0050139/0b533/f188ae47e7ef202e0f7938896a595a3d28b3d97a940886d65cc1bc1406ba2c60.png 500w&quot; sizes=&quot;(max-width: 500px) 100vw, 500px&quot; type=&quot;image/png&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/9181d533566e260a77071bb3d0050139/0b533/f188ae47e7ef202e0f7938896a595a3d28b3d97a940886d65cc1bc1406ba2c60.png&quot; alt=&quot;Oauth&quot; title=&quot;Oauth&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;Nowadays it&apos;s very common to use &lt;a href=&quot;http://oauth.net/&quot; title=&quot;OAuth Community Site&quot; target=&quot;_blank&quot;&gt;OAuth &lt;/a&gt;as the method for clients to access server resources on behalf of a resource owner. OAuth also provides a process for end-users to authorize 3rd-party access to their server resources without sharing their credentials (tipically, a username and password pair), using user-agent redirections. &amp;nbsp;Google, Twitter, Facebook, LinkedIn, and many other services providers, use OAuth in their APIs.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;However, &lt;strong&gt;there is some debate in the community about &amp;nbsp;the interpretation of the number of legs when using OAuth&lt;/strong&gt;. The curious thing is that &amp;nbsp;both RFCs RFC-5849 for OAuth 1.0 and RFC-6749 for OAuth 2.0, does not use the term leg at all. So, it seems the term leg is kind of an interpretation of the spec, and of course there are multiples interpretations in the community. There are those who consider that the number of legs are the number of steps involved to get the access token. And there are those who consider that the number of legs are the number of parties involved in OAuth dance. &lt;strong&gt;For me, it makes more sense to consider that the number of legs is the number of steps involved to obtain to the access token, which allow me to distinct between a 2-legged from a 0-legged oauth&lt;/strong&gt; (more on that later).&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;The most used oauth dance uses a 3-leg process, and it seems that there is agreement about this 3-leg definition:&lt;/span&gt;&lt;/div&gt;
&lt;ol&gt;&lt;li&gt;&lt;span&gt;The consumer (the app that wants to access data) obtains a request token from the service provider&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;The consumer redirects the user to the service provider , using the request token obtained. The user logs in &amp;nbsp;and grants the requested permissions on the service provider pages&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;The service provider redirects the user to the consumer site, and the consumer obtains the access token from the service provider&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;&lt;span&gt;&lt;strong&gt;The division in the community is when refering to 2-legged OAuth (vs a 0-legged OAuth)&lt;/strong&gt;.&amp;nbsp;&lt;/span&gt;In my point of view, &lt;strong&gt;the 0-legged OAuth consists of a consumer accessing the protected resources submitting OAuth signed requests using just the consumer key and the consumer secret&lt;/strong&gt;. The process of obtaining these is defined by each service provider and is once per application, usually by the application developer. &lt;strong&gt;This is different from the 2-legged OAuth, which is a 3-legged OAuth without requiring the end-user to participate (missing step 2 and no redirections) .&lt;/strong&gt;&amp;nbsp;&lt;a href=&quot;http://blog.nerdbank.net/&quot; title=&quot;Andrew Arnott Blog&quot; target=&quot;_blank&quot;&gt;Andrew Arnott&lt;/a&gt;&amp;nbsp;has a great post where he explains&amp;nbsp;&amp;nbsp;&lt;a href=&quot;http://blog.nerdbank.net/2011/06/what-is-2-legged-oauth.html&quot; title=&quot;What is 2-legged OAuth&quot; target=&quot;_blank&quot;&gt;What is 2-legged OAuth&lt;/a&gt;. &amp;nbsp;If you want to have a sense of the discussion about the 2-legged OAuth vs 0-legged OAuth, see the comments of his post.&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;I had to learn the distinction between the 2-legged OAuth and 0-legged OAuth when trying to integrate with UserVoice API. In the &lt;a href=&quot;http://developer.uservoice.com/docs/api/getting-started/&quot; title=&quot;UserVoice API Getting Started&quot; target=&quot;_blank&quot;&gt;Getting Started section of Uservoice API documentation&lt;/a&gt;, it is said&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;span&gt;&lt;em&gt;There are three types of requests:&lt;br&gt;&lt;br&gt; - Unauthenticated Requests- Requests you can make without any authentication other than passing your API Key. ex: Retrieving ideas or comments from a public forum.&lt;br&gt; - 3-legged OAuth requests- Requests made on the behalf of a user (see any API endpoints marked as requiring a User or Admin). ex: Voting on an idea, Creating a comment, Responding to a idea..&lt;br&gt; - 2-legged OAuth requests- Requests made on behalf of the client not on behalf of any specific user (see any API endpoints marked as requiring a Trusted Client) ex: Retrieving all users for a site, Getting a list of ideas for a private forum.&lt;/em&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;In my case I was developing the method to retrieve all users for a site, which is refered to be a 2-legged OAuth request. I am using the &amp;nbsp;library &lt;a href=&quot;http://www.dotnetopenauth.net/&quot; title=&quot;DotNetOpenAuth Library&quot; target=&quot;_blank&quot;&gt;dotnetopenauth&lt;/a&gt;, which it seems to me the most used oauth library in the .Net world. &amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;In my point of view I had to get a request token first and then exchange it to get the access token, and finally use the access token when signing the requests to access resources. But when submitting the second request to get the access token I always got a 401 Unauthorized.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;I decided to get some help from the support, and here is the answer that I received by email&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;span&gt;&lt;em&gt;Hi Bruno,&lt;br&gt;&lt;br&gt; Our Developers figured out what&apos;s going on.&lt;br&gt;&lt;br&gt;&lt;strong&gt;You&apos;re trying to do 2-legged OAuth basically like 3-legged OAuth without the user part. This is what most people mean by 2-legged OAuth. We don&apos;t support this type of 2-legged OAuth at this time.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;&lt;strong&gt;What we call 2-legged OAuth in our docs is what some people have suggested calling 0-legged OAuth. It is basically signing requests with the client secret only.&lt;/strong&gt;&lt;br&gt;&lt;br&gt; In our examples we do this by creating an AccessToken object for a user. At least in the Ruby OAuth library, this sets the token and secret both to empty string. We then use this token to sign the requests. There is no need to ask the API for a request token or for an access token. You can just create a blank access token and start making requests.&lt;br&gt;&lt;br&gt; Let me know if you have any more questions.&lt;/em&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;div&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;So what can we conclude from this? &lt;strong&gt;We have to understand from the service provider perspective what they are refering as a 2-legged oauth, since there are this 0-legged oauth which is different&lt;/strong&gt;. In the next post I will show how to to this 0-legged oauth using dotnetopenauth, since there are some tricks to do it.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt; </content:encoded></item><item><title><![CDATA[An inspirational story: The Mexican Fisherman]]></title><description><![CDATA[An inspirational story: The Mexican Fisherman]]></description><link>https://bfcamara.com/post/33700369571/an-inspirational-story-the-mexican-fisherman</link><guid isPermaLink="false">https://bfcamara.com/post/33700369571/an-inspirational-story-the-mexican-fisherman</guid><pubDate>Tue, 16 Oct 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;/p&gt;&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;figure data-orig-height=&quot;256&quot; data-orig-width=&quot;192&quot;&gt;&lt;img align=&quot;right&quot; src=&quot;https://66.media.tumblr.com/5cf21a9d78cdd7253bd9ab6e3f11ebbd/b41529a20fa20b46-7b/s540x810/296fc9d53a2fe55172a30719a6ec1df6421edac2.jpg&quot; data-orig-height=&quot;256&quot; data-orig-width=&quot;192&quot;&gt;&lt;/figure&gt;One of the books that I&apos;ve read recently was the &lt;a href=&quot;http://www.amazon.com/4-Hour-Workweek-Anywhere-Expanded-Updated/dp/0307465357&quot; title=&quot;The 4-hour work week&quot; target=&quot;_blank&quot;&gt;4 hour work week&lt;/a&gt; from &lt;a href=&quot;http://www.fourhourworkweek.com/&quot; title=&quot;Timothoy Feriss&quot; target=&quot;_blank&quot;&gt;Timothy Ferriss&lt;/a&gt;. There are some ideas on the book that make me say that it&apos;s a worth reading, however I am skeptical about some of them. There is no doubt that the guy is a great marketer, which can be checked by the book title itself&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;em&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/em&gt;&lt;/div&gt;
&lt;div&gt;&lt;em&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;strong&gt;The 4-Hour workweek - Escape the 9 - 5, live anywhere and join the new rich&lt;/strong&gt;&lt;/span&gt;&lt;/em&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;When I first saw the book &amp;nbsp;I thought &quot;here we have another quick rich scheme scam&quot; of the millions that exists on the internet. However the book was recommended by a friend of mine, and then I &quot;took the shot&quot;. Since the average customer review on the Amazon is also very high, why not buy the book and read it. That&apos;s what I did. And as I said, it is a worth reading, and not a scam at all. The book title is exaggerated, but is a great title in a marketing point of view.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;In this book I had contact with a great and inspirational story of the Mexican Fisherman. Here is the Story&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;&lt;em&gt;&lt;span&gt;An American businessman took a vacation to a small coastal&amp;nbsp;&lt;/span&gt;&lt;span&gt;Mexican village on doctor&apos;s orders. Unable to sleep after an&amp;nbsp;&lt;/span&gt;&lt;span&gt;urgent phone call from the office the first morning, he walked out to&amp;nbsp;&lt;/span&gt;&lt;span&gt;the pier to clear his head. A small boat with just one fisherman had&amp;nbsp;&lt;/span&gt;&lt;span&gt;docked, and inside the boat were several large yellowfin tuna. The&amp;nbsp;&lt;/span&gt;&lt;span&gt;American complimented the Mexican on the quality of his fish.&lt;/span&gt;&lt;/em&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;&lt;em&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; &quot;How long did it take you to catch them?&quot; the American asked.&lt;/span&gt;&lt;/em&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;&lt;em&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; &quot;Only a little while,&quot; the Mexican replied in surprisingly good&amp;nbsp;&lt;/span&gt;&lt;span&gt;English.&lt;/span&gt;&lt;/em&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;&lt;em&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; &quot;Why don&apos;t you stay out longer and catch more fish?&quot; the American&amp;nbsp;&lt;/span&gt;&lt;span&gt;then asked.&lt;/span&gt;&lt;/em&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;&lt;em&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; &quot;I have enough to support my family and give a few to friends,&quot;&amp;nbsp;&lt;/span&gt;&lt;span&gt;the Mexican said as he unloaded them into a basket.&lt;/span&gt;&lt;/em&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;&lt;em&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; &quot;But... What do you do with the rest of your time?&quot;&lt;/span&gt;&lt;/em&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;&lt;em&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; The Mexican looked up and smiled. &quot;I sleep late, fish a little, play&amp;nbsp;&lt;/span&gt;&lt;span&gt;with my children, take a siesta with my wife, Julia, and stroll into the&amp;nbsp;&lt;/span&gt;&lt;span&gt;village each evening, where I sip wine and play guitar with my&amp;nbsp;&lt;/span&gt;&lt;span&gt;amigos. I have a full and busy life, senor.&quot;&lt;/span&gt;&lt;/em&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;&lt;em&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; The American laughed and stood tall. &quot;Sir, I&apos;m a Harvard M.B.A.&amp;nbsp;&lt;/span&gt;&lt;span&gt;and can help you. You should spend more time fishing, and with the&amp;nbsp;&lt;/span&gt;&lt;span&gt;proceeds, buy a bigger boat. In no time, you could buy several boats&amp;nbsp;&lt;/span&gt;&lt;span&gt;with the increased haul. Eventually, you would have a fleet of fishing&amp;nbsp;&lt;/span&gt;&lt;span&gt;boats.&quot;&lt;/span&gt;&lt;/em&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;&lt;em&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; He continued, &quot;Instead of selling your catch to a middleman, you&amp;nbsp;&lt;/span&gt;&lt;span&gt;would sell directly to the consumers, eventually opening your own&amp;nbsp;&lt;/span&gt;&lt;span&gt;cannery. You would control the product, processing, and distribution.&amp;nbsp;&lt;/span&gt;&lt;span&gt;You would need to leave this small coastal fishing village, of course,&amp;nbsp;&lt;/span&gt;&lt;span&gt;and move to Mexico City, then to Los Angeles, and eventually New&amp;nbsp;&lt;/span&gt;&lt;span&gt;York City, where you could run your expanding enterprise with&amp;nbsp;&lt;/span&gt;&lt;span&gt;proper management.&quot;&lt;/span&gt;&lt;/em&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;&lt;em&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; The Mexican fisherman asked, &quot;But, señor, how long will all this&amp;nbsp;&lt;/span&gt;&lt;span&gt;take?&quot;&lt;/span&gt;&lt;/em&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;&lt;em&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; To which the American replied, &quot;15-20 years. 25 tops.&quot;&lt;/span&gt;&lt;/em&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;&lt;em&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; &quot;But what then, señor?&quot;&lt;/span&gt;&lt;/em&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;&lt;em&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; The American laughed and said, &quot;That&apos;s the best part. When the&amp;nbsp;&lt;/span&gt;&lt;span&gt;time is right, you would announce an IPO and sell your company&amp;nbsp;&lt;/span&gt;&lt;span&gt;stock to the public and become very rich. You would make millions.&quot;&lt;/span&gt;&lt;/em&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;&lt;em&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; &quot;Millions, senor? Then what?&quot;&lt;/span&gt;&lt;/em&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;&lt;em&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; &quot;Then you would retire and move to a small coastal fishing village,&amp;nbsp;&lt;/span&gt;&lt;span&gt;where you would sleep late, fish a little, play with your kids,&amp;nbsp;&lt;/span&gt;&lt;span&gt;take a siesta with your wife, and stroll to the village in the evening&amp;nbsp;&lt;/span&gt;&lt;span&gt;where you could sip wine and play your guitar with your amigos.&lt;/span&gt;&lt;/em&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;I don&apos;t know who the author is, but this story had a profound impact on my feelings. Why? &lt;strong&gt;Because in the past I thought as the businessman, that I would need to be rich to have the freedom of how I would spend my time.&lt;/strong&gt; In one of my previous posts I explained &lt;a href=&quot;http://bfcamara.com/post/17149497531/my-first-big-mistake-as-founder&quot; title=&quot;my big mistake as founder&quot; target=&quot;_self&quot;&gt;my big mistake as a founder&lt;/a&gt; which reflects this kind of thinking. &lt;strong&gt;Now I think like the Fisherman, and it&apos;s the road that I want to follow.&amp;nbsp;&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[I'm back with a "fixed" heart]]></title><description><![CDATA[I'm back with a "fixed" heart]]></description><link>https://bfcamara.com/post/33154883793/im-back-with-a-fixed-heart</link><guid isPermaLink="false">https://bfcamara.com/post/33154883793/im-back-with-a-fixed-heart</guid><pubDate>Mon, 08 Oct 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;On June 21 I was the target of a cardiothoracic surgery. This surgery was to &quot;fix&quot; an aneurysm in the ascending aorta and &amp;nbsp;to implant a mechanical aortic valve.&lt;/p&gt;
&lt;p&gt;It all started 12 years ago, around the year 2000, when in a occupational medicine consultation, the physician detected a &quot;murmur&quot; in my heart . It was then that I began to be followed by a cardiologist, with periodic examinations on my heart. Basically I had a defect in the aortic valve and my cardiologist always told me that by the age of 50 I would have to replace the valve.&lt;/p&gt;
&lt;p&gt;Throughout all these years, &amp;nbsp;I have done several exams, and it was detected that the diameter of the ascending aorta was increasing. At the end of 2011 I was informed that that there was a risk of the artery to be ruptured, &amp;nbsp;with potentially fatal consequences. Since the surgery would require to open the chest, then it makes sense take advantage and implant the valve, instead of waiting more years to open the chest again.&lt;/p&gt;
&lt;p&gt;This period of sick leave, although quite painful, served to do some reflections and put some of the reading in day. This week I am returning to work &amp;nbsp;and also in the hope to keep the blog more active.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Things to remember when setting up a SaaS business]]></description><link>https://bfcamara.com/post/24673935033/things-to-remember-when-setting-up-a-saas-business</link><guid isPermaLink="false">https://bfcamara.com/post/24673935033/things-to-remember-when-setting-up-a-saas-business</guid><pubDate>Fri, 08 Jun 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://www.bornontheweb.be/things-to-remember-when-setting-up-a-saas-bus&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://www.bornontheweb.be/things-to-remember-when-setting-up-a-saas-bus&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Freemium Pricing for SaaS: Optimizing Paid Conversion Upgrades]]></description><link>https://bfcamara.com/post/23599789258/freemium-pricing-for-saas-optimizing-paid</link><guid isPermaLink="false">https://bfcamara.com/post/23599789258/freemium-pricing-for-saas-optimizing-paid</guid><pubDate>Wed, 23 May 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://onstartups.com/tabid/3339/bid/84427/Freemium-Pricing-for-SaaS-Optimizing-Paid-Conversion-Upgrades.aspx&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://onstartups.com/tabid/3339/bid/84427/Freemium-Pricing-for-SaaS-Optimizing-Paid-Conversion-Upgrades.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Smart people don't think others are stupid]]></description><link>https://bfcamara.com/post/23220200260/smart-people-dont-think-others-are-stupid</link><guid isPermaLink="false">https://bfcamara.com/post/23220200260/smart-people-dont-think-others-are-stupid</guid><pubDate>Thu, 17 May 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://sivers.org/ss&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://sivers.org/ss&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Designer, Architect, Developer]]></description><link>https://bfcamara.com/post/22961472641/designer-architect-developer</link><guid isPermaLink="false">https://bfcamara.com/post/22961472641/designer-architect-developer</guid><pubDate>Sun, 13 May 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://24waystostart.com/2010/designer-architect-developer/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://24waystostart.com/2010/designer-architect-developer/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Designer, Architect, Developer: The three major skills that should be present in order to best build a successful web application&lt;/span&gt;&lt;/p&gt; </content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[5 Laws of Business You’ve Never Heard Of]]></description><link>https://bfcamara.com/post/22780331246/5-laws-of-business-youve-never-heard-of</link><guid isPermaLink="false">https://bfcamara.com/post/22780331246/5-laws-of-business-youve-never-heard-of</guid><pubDate>Thu, 10 May 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://www.inc.com/jeff-haden/5-laws-of-business-youve-never-heard-of.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://www.inc.com/jeff-haden/5-laws-of-business-youve-never-heard-of.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[7 Reasons I Shouldn’t Be Starting a Company]]></description><link>https://bfcamara.com/post/20459261899/7-reasons-i-shouldnt-be-starting-a-company</link><guid isPermaLink="false">https://bfcamara.com/post/20459261899/7-reasons-i-shouldnt-be-starting-a-company</guid><pubDate>Wed, 04 Apr 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://dannydo.es/a-startup-despite-these-7-reasons/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://dannydo.es/a-startup-despite-these-7-reasons/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link post]]></title><description><![CDATA[Books for Startups « Steve Blank]]></description><link>https://bfcamara.com/post/19626755538/books-for-startups-steve-blank</link><guid isPermaLink="false">https://bfcamara.com/post/19626755538/books-for-startups-steve-blank</guid><pubDate>Tue, 20 Mar 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://steveblank.com/books-for-startups/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://steveblank.com/books-for-startups/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</content:encoded></item><item><title><![CDATA[So you think you can dance?]]></title><description><![CDATA[So you think you can dance?]]></description><link>https://bfcamara.com/post/19567542075/so-you-think-you-can-dance</link><guid isPermaLink="false">https://bfcamara.com/post/19567542075/so-you-think-you-can-dance</guid><pubDate>Mon, 19 Mar 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span&gt;Don&apos;t be fooled by the title, since I don’t have any dancing skills and probably never will. In fact my wife always said me that I am a lousy dancer. Her feet always suffer when we dance together.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;The real question I want to ask is:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;nbsp;&lt;span class=&quot;Apple-tab-span&quot;&gt; &lt;/span&gt;&lt;strong&gt;Do you think you can leave your day job and start your own company?&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;During my life, I’ve listen too many persons criticizing the company partners/directors, about some of the option behind made, or about some policies, etc.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;It&apos;s legitimate, nobody is above critic. I also criticize some options. What makes me uncomfortable is listen sentences such as&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&lt;span&gt;&quot;If I had my own company I...&quot;&lt;/span&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;My question &amp;nbsp;is immediately: &lt;/span&gt;&lt;em&gt;“So, why don’t you?”&lt;/em&gt;&lt;span&gt; or &lt;/span&gt;&lt;em&gt;&quot;So you think you can leave your day job and start your own company?&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Let me show you a chart&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;strong id=&quot;internal-source-marker_0.680594107368961&quot;&gt;&lt;figure class=&quot;tmblr-full&quot; data-orig-height=&quot;296&quot; data-orig-width=&quot;489&quot; data-orig-src=&quot;https://lh5.googleusercontent.com/L693TQBAGOwS0-bkwxIjn3tSWoOntem8b3oPTIderRcd0swWz8ebhpv8gp0Am0jg5n4W2lAGot1Hs6PHBu3RiOL5aJ9GXSW1Jv4iXtkQJYhcCuoaiaU&quot;&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 489px; &quot;&gt;
      &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/4da4bc2db295c8fc6e2b2fe7dfc0c900/17612/156da5aecddea23b14e7af4b2643a1f6898584ebfdee26f738826b34a0ff12ae.jpg&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 60.416666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAMABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAIBBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAe8wUkf/xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAEFAl//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAUEAEAAAAAAAAAAAAAAAAAAAAg/9oACAEBAAY/Al//xAAbEAACAQUAAAAAAAAAAAAAAAAAESEBEDFBsf/aAAgBAQABPyFk01Z4H0cn/9oADAMBAAIAAwAAABCwz//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABsQAQEBAAIDAAAAAAAAAAAAAAERACFRMUGR/9oACAEBAAE/EGIBXrDS1z6zhzw5Zlh8ZdHTv//Z&apos;); background-size: cover; display: block;&quot;&gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source srcset=&quot;/static/4da4bc2db295c8fc6e2b2fe7dfc0c900/8ac56/156da5aecddea23b14e7af4b2643a1f6898584ebfdee26f738826b34a0ff12ae.webp 240w,
/static/4da4bc2db295c8fc6e2b2fe7dfc0c900/d3be9/156da5aecddea23b14e7af4b2643a1f6898584ebfdee26f738826b34a0ff12ae.webp 480w,
/static/4da4bc2db295c8fc6e2b2fe7dfc0c900/6a0ac/156da5aecddea23b14e7af4b2643a1f6898584ebfdee26f738826b34a0ff12ae.webp 489w&quot; sizes=&quot;(max-width: 489px) 100vw, 489px&quot; type=&quot;image/webp&quot;&gt;
          &lt;source srcset=&quot;/static/4da4bc2db295c8fc6e2b2fe7dfc0c900/09b79/156da5aecddea23b14e7af4b2643a1f6898584ebfdee26f738826b34a0ff12ae.jpg 240w,
/static/4da4bc2db295c8fc6e2b2fe7dfc0c900/7cc5e/156da5aecddea23b14e7af4b2643a1f6898584ebfdee26f738826b34a0ff12ae.jpg 480w,
/static/4da4bc2db295c8fc6e2b2fe7dfc0c900/17612/156da5aecddea23b14e7af4b2643a1f6898584ebfdee26f738826b34a0ff12ae.jpg 489w&quot; sizes=&quot;(max-width: 489px) 100vw, 489px&quot; type=&quot;image/jpeg&quot;&gt;
          &lt;img class=&quot;gatsby-resp-image-image&quot; src=&quot;/static/4da4bc2db295c8fc6e2b2fe7dfc0c900/17612/156da5aecddea23b14e7af4b2643a1f6898584ebfdee26f738826b34a0ff12ae.jpg&quot; alt=&quot;156da5aecddea23b14e7af4b2643a1f6898584ebfdee26f738826b34a0ff12ae&quot; title=&quot;156da5aecddea23b14e7af4b2643a1f6898584ebfdee26f738826b34a0ff12ae&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/figure&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;This chart shows my asset values (house mortgage not accounted for). &lt;strong&gt;The inflection point, at January of 2004, is when I left my job and started my own company.&lt;/strong&gt; There were many fringe benefits that I’ve lost, such as car, fuel allowance, mobile phone, stock options, tuition, etc. Some of these perks, I had to buy/pay myself after leaving my job. &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt; &lt;strong&gt;So you think you can handle this?&lt;/strong&gt; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;I think it will be interest to analyze the typical answers, &lt;em&gt;“I have a mortgage to pay”&lt;/em&gt;, &lt;em&gt;“I have kids and I need some security”&lt;/em&gt;, &lt;em&gt;“I want to guarantee my retire plan”&lt;/em&gt;, but maybe in a future post. &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;P.S. I don’t intend to discourage anyone, but if you are doing the talk, you have at least be (seriously) willing to do the walk.&lt;/span&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[My first big mistake as founder]]></title><description><![CDATA[My first big mistake as founder]]></description><link>https://bfcamara.com/post/17149497531/my-first-big-mistake-as-founder</link><guid isPermaLink="false">https://bfcamara.com/post/17149497531/my-first-big-mistake-as-founder</guid><pubDate>Mon, 06 Feb 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;My first big mistake as a founder was my own ambition&lt;/strong&gt; (which could be also seen as greed) and confusing the objective with the path to achieve it. But I&apos;m getting ahead of the story.&lt;/p&gt;
&lt;p&gt;When I, and my co-founders, founded Agilior, we did an exercise where each one had to describe the reasons (personal or professional), for starting our own company. In my case, there were basically two main reasons.&lt;/p&gt;
&lt;p&gt;The professional reason was simple: &lt;strong&gt;professional achievement&lt;/strong&gt;. I wanted to build a brand that would be recognized for his quality, integrity and honesty. I also wanted to build a place that was nice to work, with a culture of friendship, mutual help and wellness. Perhaps too naive, but that was what I thought at the time.&lt;/p&gt;
&lt;p&gt;The personal reason was not so simple: &lt;strong&gt;getting my &quot;freedom&quot;&lt;/strong&gt;. In that exercise, I remember that I wrote the following sentence&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;nbsp;&quot;I want the freedom to leave at 3 pm so I can take my kids to the movies&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Freedom is a term that has many meanings. Josh Kaufman, from the &amp;nbsp;&lt;a href=&quot;http://personalmba.com&quot; target=&quot;_blank&quot;&gt;Personal MBA&lt;/a&gt; project, wrote an &lt;a href=&quot;http://personalmba.com/building-a-business-that-supports-your-life&quot; target=&quot;_blank&quot;&gt;excellent post&lt;/a&gt;&amp;nbsp;on this feeling of wanting to build a business that supports your life. This freedom it&apos;s all I ambitioned and it was my personal reason to build my own company.&lt;/p&gt;
&lt;p&gt;Of course this freedom presupposes a set of assumptions, which would imply an &amp;nbsp;operational distance &amp;nbsp;in the medium term. When I speak of operational distance, I mean not having to be involved full-time in the implementation of the projects we were developing. And to do that, we had to grow the company.&lt;/p&gt;
&lt;p&gt;Some time after founding &amp;nbsp;Agilior, &lt;strong&gt;I realized that much of this freedom that I wanted to achieve, I was already getting it&lt;/strong&gt;, and that it wasn&apos;t necessary to grow the company. I started to managing my own time in my own terms, which allowed me have more free time for myself and my family, &amp;nbsp;and able to work &amp;nbsp;at &quot;less common&quot; hours. I never compromised my team, and I know when we work as a team, it is important to have the team members working at the same time. But the fact is that the freedom that I had ambitioned, I already had to a large extent.&lt;/p&gt;
&lt;p&gt;The big mistake happened, when &lt;strong&gt;I became obsessed with growing the company to increase my operational distance&lt;/strong&gt;, though, in retrospective, it was not necessary at all. When I and my &lt;a href=&quot;http://pascoal.net&quot; target=&quot;_blank&quot;&gt;co-founder&lt;/a&gt;&amp;nbsp;were approached for the 1st time, by another company, to sell to them a part of the company, I saw it as an opportunity to make the company play in the 1st league (we were a small niche shop and profitable since day one), exponentially increase in sales, grow the company and have more freedom. And I can say it was me who insisted more on this step, thinking that everything would go well.(damn wishful thinking)&lt;/p&gt;
&lt;p&gt;What happened was that the &lt;strong&gt;we sold 60% of the company&lt;/strong&gt; (a few years later we would sell the remaining shares). &lt;strong&gt;What did not happen was the growth in sales&lt;/strong&gt; (at least not in the promised terms), yet the company heacount has grown.&lt;/p&gt;
&lt;p&gt;In the first transaction, we lost the financial control of the company since we now had only held 40% of the share, however we agreed that we would continue to have the operational control, allowing us to veto any decisions which we did not agree too. &lt;strong&gt;There was also &amp;nbsp;a period of experimentation, where either party could roll back the transaction&lt;/strong&gt;. During this period, no major changes occurred, except that we were &amp;nbsp;&amp;ldquo;given&amp;rdquo; &amp;nbsp;the opportunity to work on a new contract, a larger one compared to the ones that we were being used to. When the trial period ended, we decided to not rollback the transaction, and start working as a business partners.&lt;/p&gt;
&lt;p&gt;In a retrospective the first transaction, we made the mistake of not writing on paper the expectations of each party.The trial period was not enough. &lt;strong&gt;And more important than to write &amp;nbsp;the expectations, is to write what should happen if the expectations are not met&lt;/strong&gt;. It is really really important.&lt;/p&gt;
&lt;p&gt;What happened next, as I said earlier, was that sales have not grown . Moreover, most of the sales continued to be closed by my co-founder, and others by myself. The expected growth of sales was not met. But the other side started pressuring that we were not having the revenues as high as we should.&lt;/p&gt;
&lt;p&gt;At some point, we realized that it was not worth continuing with this model, and we approached the other side to buy back the shares. The proposal was not accepted, and then we proceed with a proposal to sell the remaining of our shares. &lt;strong&gt;I am currently an employee of the company&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;At end of the the day, I lost my freedom&lt;/strong&gt;. And this was my biggest mistake. I was much happier with the company with three employees, with full autonomy in decision making, personal life, etc.. I was betrayed by my own greed.&lt;/p&gt;
&lt;p&gt;A mistake not to be made again. &lt;strong&gt;If you ask me the reasons which lead me to make a company, I think I will answer it in the same way&lt;/strong&gt;. &amp;nbsp;Maybe I will place more emphasis on doing something what I really love. But the path will certainly be different. The most important thing is the path, and not the end. The path &amp;nbsp;must give me the freedom that I want. &lt;strong&gt;There are times we have to do some trade-offs, I have a family with two children, &amp;nbsp;and have to put the food on the table&lt;/strong&gt;. The problem is when our greed goes far beyond our need and obscures the clarity of thought. Recently I read the book &lt;a href=&quot;http://www.amazon.com/dp/1936719118&quot; target=&quot;_blank&quot;&gt;Anything You Want&lt;/a&gt;&amp;nbsp;from &lt;a href=&quot;http://sivers.org&quot; target=&quot;_blank&quot;&gt;Derek Sivers&lt;/a&gt;,&amp;nbsp;the guy who created CD Baby. I loved the book, and I know understand Derek when he says&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&quot;I&amp;rsquo;m a minimalist. The less I own, the happier I am.&quot;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Welcome to my blog]]></title><description><![CDATA[Welcome to my blog]]></description><link>https://bfcamara.com/post/16629534467/welcome</link><guid isPermaLink="false">https://bfcamara.com/post/16629534467/welcome</guid><pubDate>Sat, 28 Jan 2012 00:00:00 GMT</pubDate><content:encoded>&lt;div&gt;&amp;#13;
&lt;p&gt;One of my resolutions for 2012 was back to blog . I decided to kill &lt;a href=&quot;http://www.agilior.pt/blogs/bruno.camara/&quot; target=&quot;_blank&quot;&gt;my old blog&lt;/a&gt; (in fact, it was already dead),  which is hosted in the &lt;a href=&quot;http://www.agilior.pt/blogs/&quot; target=&quot;_blank&quot;&gt;Agilior&apos;s corporate blog&lt;/a&gt;, the company where I work and I was a co-founder (right now, I already  haven&apos;t  any part of the company&apos;s capital) and create a new blog with a personal touch,associated with the bfcamara.com domain.&lt;/p&gt;&amp;#13;
&lt;p&gt;The most of the content that I will publish is certainly related to my work, software development.&lt;/p&gt;&amp;#13;
&lt;p&gt;As one of the founders of Agilior, I hope also to share some of the stories that were part of my life as founder, and some of the mistakes I made along this route. There will be space also to personal subjects, however with lower frequency.&lt;/p&gt;&amp;#13;
&lt;p&gt;In &lt;a href=&quot;http://www.agilior.pt/blogs/bruno.camara/archive/2007/12/02/3300.aspx&quot;&gt;one of my posts&lt;/a&gt; at the old blog, I explain that my life has been done of cycles. My perception is that a new cycle is about to come. I do not expect an easy time, and certainly I will have to leave the comfort zone. But &quot;freedom&quot; is one of the things that I value most, and to be honest,  I like to be the leader and the captain of the ship&quot;, deciding where to go and when.&lt;/p&gt;&amp;#13;
&lt;p&gt;&lt;span&gt;I hope I can maintain some activity in this blog.&lt;/span&gt;&lt;/p&gt;&amp;#13;
&lt;/div&gt; </content:encoded></item></channel></rss>