<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nicholas Frush</title>
    <description>The latest articles on DEV Community by Nicholas Frush (@cawfeecoder).</description>
    <link>https://dev.to/cawfeecoder</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F795733%2F04b09147-2bf4-4588-aec3-a69584f40171.jpeg</url>
      <title>DEV Community: Nicholas Frush</title>
      <link>https://dev.to/cawfeecoder</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cawfeecoder"/>
    <language>en</language>
    <item>
      <title>Web Components: An Introspective</title>
      <dc:creator>Nicholas Frush</dc:creator>
      <pubDate>Sun, 06 Feb 2022 19:14:25 +0000</pubDate>
      <link>https://dev.to/cawfeecoder/web-components-an-introspective-363c</link>
      <guid>https://dev.to/cawfeecoder/web-components-an-introspective-363c</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Web Components is a specification that provides for a set of APIs that allow creation of re-usable, framework agnostic components with style encapsulation. The goal is to be able to provide a move away from locking into a single framework, so that when another framework comes along there isn't a herculean effort to re-write everything. It runs against the grain of "write this in Angular today, rewrite this in React 3-5 years from now". More importantly, I think web-components force you to think about how to correctly build a re-usable component and prefer composition over inheritance.&lt;/p&gt;

&lt;p&gt;Moreover, there's no guessing about how to style a button to look the same across applications (or how to inject CSS to tweak a component in an existing component library that's popular in your framework of choice). You can definitively craft elements which are tailored to the look/feel of your project with the desired functionality without breaking the bank or looking suspiciously like the component library everyone else is using. &lt;/p&gt;

&lt;h1&gt;
  
  
  A basic component
&lt;/h1&gt;

&lt;p&gt;For my examples, I'm going to choose a relatively new framework called "Atomico". Atomico is a purpose built micro-library that's sole goal is to provide the functionality to build web-components. It's codebase is relatively small and understandable and the experience it very close to one would experience writing in React today.&lt;/p&gt;

&lt;p&gt;I always like to provide a "button" as an example component, because I think it demonstrates a lot of concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Property passing&lt;/li&gt;
&lt;li&gt;Reflected properties&lt;/li&gt;
&lt;li&gt;Closure passing&lt;/li&gt;
&lt;li&gt;State changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The button I'm going to be building will have 3 properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Disabled (boolean) - indicates whether the button is disabled or not&lt;/li&gt;
&lt;li&gt;Type (string enum) - indicates what type of button we're displaying (e.g. text, outlined, normal, etc.)&lt;/li&gt;
&lt;li&gt;onClick (function) - the closure we should run on handling functions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This component in Atomico may look something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { c, css, Props } from "atomico";
import tailwindcss from "../tailwindcss.css";
import {
  base as baseStyle,
  full as fullStyle,
  contained as containedStyle,
  dropdown as dropdownStyle,
  text as textStyle,
  outlined as outlinedStyle,
} from "./styles";
import classNames from "classnames/index";

export function button({
  type,
  disabled,
  onClick,
}: Props&amp;lt;typeof button&amp;gt;) {
  return (
    &amp;lt;host shadowDom&amp;gt;
      &amp;lt;button
        onclick={onClick}
        disabled={disabled}
        type="button"
        class={classNames(
          baseStyle,
          fullStyle,
          type == "contained" ? containedStyle : null,
          type == "text" ? textStyle : null,
          type == "outlined" ? outlinedStyle : null
        )}
      &amp;gt;
        &amp;lt;slot name="pre" /&amp;gt;
        &amp;lt;slot&amp;gt;&amp;lt;/slot&amp;gt;
        &amp;lt;slot name="post" /&amp;gt;
      &amp;lt;/button&amp;gt;
    &amp;lt;/host&amp;gt;
  );
}

button.props = {
  type: {
    type: String,
    value: "contained",
  },
  disabled: {
    type: Boolean,
    reflect: true,
    value: false,
  },
  onClick: {
    type: Function,
  },
};

button.styles = [tailwindcss];

export const Button = c(button);

customElements.define("my-button", Button);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll notice, we have a simple declaration of our properties and a relatively normal looking piece of JSX.&lt;/p&gt;

&lt;p&gt;You may have noticed the use of "slot" elements. These elements allow us to slot other elements/content into the spaces where they are when we use our component (this will be important later). For example, I could use the button like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;my-button&amp;gt;Hello&amp;lt;/my-button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where "Hello" would be slotted into the middle slot.&lt;br&gt;
If I wanted to put an icon before the text in my button, I could do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;my-button&amp;gt;&amp;lt;i slot="pre" class="my-cool-icon"/&amp;gt;Hi&amp;lt;/my-button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's important to note, named slots require the slotting element to declare what slot they go to, while unnamed slots will take any undeclared slotted child. More importantly, there can only be one unnamed slot. &lt;/p&gt;

&lt;h2&gt;
  
  
  Handling functions
&lt;/h2&gt;

&lt;p&gt;As we saw previously, I passed the closure of a function down using the onClick property. This works because JavaScript closures include the context of their execution. For example, a closure such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let myOnClick = () =&amp;gt; { this.store.update(5) }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;maintains the references to the state around it (i.e. this.store) despite getting passed down to a child.&lt;/p&gt;

&lt;p&gt;There's also another way to handle events in web-components - Custom Events. Instead of passing a closure down, one would declare a Custom Event and fire it upward from the child when an action takes place (e.g. click), like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
const dispatchEvent = useEvent("my-click", {
  bubbles: true,
  composed: true
})
...
&amp;lt;host shadowDom&amp;gt;
      &amp;lt;button
        onclick={() =&amp;gt; dispatchEvent()}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Constructing more complex components
&lt;/h1&gt;

&lt;p&gt;Most people constructing more complex components coming from React will argue for high-order components and slots do exactly that. I should make a distinction - high order components work in React by providing "slots" (e.g. props.children) to compose complex components instead of throwing a bunch of components statically together in a single large component. &lt;/p&gt;

&lt;p&gt;Slots - as explained previously - allow us to slot any element into a predefined space. You can - of course - get reference to the slot and filter what elements are allowed to appear there (but I'll leave that for another article for now or an exercise to the reader). Let's assume I have 2 elements - a my-card element that is an encapsulating card and a my-input element that encapsulates an input box.&lt;/p&gt;

&lt;p&gt;If I wanted to make a Login form, I could easily compose something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;my-card&amp;gt;
  &amp;lt;my-input placeholder="Email /&amp;gt;
  &amp;lt;my-input placeholder="Password /&amp;gt;
&amp;lt;/my-card&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In React HOC, you may see something similar like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function myCard = (props) =&amp;gt; {
  ...
  return (
    &amp;lt;div className="...&amp;gt;
      {props.children}
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's important to note, you'll rarely see this in React:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function myLoginForm = (props) =&amp;gt; {
  ...
  return (
    &amp;lt;div className="...&amp;gt;
      &amp;lt;input .../&amp;gt;
      &amp;lt;input .../&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why? What happens when requirements change? It's much easier ensure the functionality of the HOC than to go back to a singular component and re-add a new requirement (e.g. password link). The same is true for web-components. You want your basic building blocks to be static and be modular and rearrangable in any way, shape, or form. Maintaining "one off" complex components can lead to tech debt down the line and become very hard for newer developers to come on board and understand how to build a new component fast that can stand the tests of time for new requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Passing objects/arrays
&lt;/h2&gt;

&lt;p&gt;It's pretty common in other frameworks to be able to pass objects down as properties to components. I'd argue with the atomic nature of web-components and the use of slots, you should avoid passing an object at all costs. Let me explain:&lt;/p&gt;

&lt;p&gt;You have a component that takes an object and assigns the the properties to child components in your framework:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function myComplexObjPass = (props) =&amp;gt; {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;{props.myObj.a}&amp;lt;/p&amp;gt;
      &amp;lt;p&amp;gt;{props.myObj.b}&amp;lt;/p&amp;gt;
      &amp;lt;p&amp;gt;{props.myObj.c}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In web-components, you could achieve the same functionality (without passing the object), like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function myWebComponent = (props) =&amp;gt; {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;slot&amp;gt;&amp;lt;/slot&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

...

&amp;lt;my-web-component&amp;gt;
  &amp;lt;p&amp;gt;{myObj.a}&amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;{myObj.b}&amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;{myObj.c}&amp;lt;/p&amp;gt;
&amp;lt;/my-web-component&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In fact, I'd argue you have very little need to pass an object. If your passing an object, you like have broken your component down to atomic needs or are using slots incorrectly (whether this in web-components or a framework like React that provides props.children is irrelevant). You should always prefer to pass primitive types (e.g. String, Number) and functions and prefer for your wrapping framework to provide the "orchestration" of your web-components.&lt;/p&gt;

&lt;h1&gt;
  
  
  Closing Remarks
&lt;/h1&gt;

&lt;p&gt;As I publish this, I'm open-sourcing Seam's web-component library today. It's far from complete - I still have styles I want to tweak and components I want to add as Seam continues to grow and change as a beloved side project of mine. But, I want to code out there that demonstrates how I have achieved complex functionality with Atomico and web-components in a very short amount of time. You can find seam-web-components &lt;a href="https://github.com/seam-dev/web-components"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webcomponents</category>
      <category>atomico</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Authn/Authz in a distributed, microservice architecture</title>
      <dc:creator>Nicholas Frush</dc:creator>
      <pubDate>Sun, 23 Jan 2022 19:51:41 +0000</pubDate>
      <link>https://dev.to/cawfeecoder/authnauthz-in-a-distributed-microservice-architecture-50j2</link>
      <guid>https://dev.to/cawfeecoder/authnauthz-in-a-distributed-microservice-architecture-50j2</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;When handling user authentication today, one must consider a myriad of problems that are inherently unique to a distributed system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cache Stampede (e.g. “Thundering Herd”)&lt;/li&gt;
&lt;li&gt;Place of evaluation&lt;/li&gt;
&lt;li&gt;Duration of access
Most systems today have opted for an access/refresh token paradigm to ensure access tokens are short lived - and thus limited to exploitation during loss. Moreover, these tokens are kept stateless to ensure that the backend services remain scalable and that authentication/authorization can be pushed to happen down at the service level, instead of a monolithic gateway.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The standard authentication flow
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lBBWMxAe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1y0uzapqzjl7g8aclbvq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lBBWMxAe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1y0uzapqzjl7g8aclbvq.png" alt="Image description" width="880" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Within a standard authentication flow, a user is exchanging their credentials for a short-lived &lt;em&gt;access&lt;/em&gt; token (&amp;lt; 15 minutes) and a long lived &lt;em&gt;refresh&lt;/em&gt; token. The refresh token’s sole purpose is to provide the client the ability to refresh an expired (or expiring) access token. Meanwhile the access token’s sole job is to indicate to the service a form of identity authentication - i.e. this is who I am. &lt;/p&gt;

&lt;p&gt;In this flow, we tend to provide the access and refresh tokens as &lt;em&gt;cookies&lt;/em&gt; (with the Secure and HttpOnly flag set) this prevents arbitrary JavaScript by an attacker during a CSRF or XSS attack from reading the cookies. In more advanced scenarios, we may provide the same values as response headers - such as X-Auth-Token and X-Refresh-Token - and follow something like the &lt;em&gt;double submit cookie&lt;/em&gt; pattern. In this pattern, a client making a request is expected to provide the request headers (i.e. X-Auth-Token and X-Refresh-Token or Authorization and X-Refresh-Token) &lt;em&gt;and&lt;/em&gt; the cookies. Backend middleware will then verify that these 2 values matched (since it’s impossible to reconstruct a signed JWT since the signing secret never leaves our backend) and then verifies the validity (i.e. has this expired, was it signed by us) of the provided JWT.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using our access token
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q6qu8E_q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/10w5xvjxh8xxjlosbun4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q6qu8E_q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/10w5xvjxh8xxjlosbun4.png" alt="Image description" width="880" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As explained previous, during normal use of the access token, server-sided middleware is provided that looks for the particular headers (e.g. Authorization, X-Auth-Token, X-Refresh-Token, Cookie, etc.) that govern a client providing your with their access (and refresh) token. This middleware will often verify the provided JWT has not expired and is signed by your backend services. After successful verification, the decoded claims of the JWT (which &lt;em&gt;should&lt;/em&gt; include the user’s id as the audience claim) will be added to the context of the request so that the ultimate handling function can check for the presence of proof of authentication in the handler. This de-couples the need of each function to verify and decode a JWT from handling business logic.&lt;/p&gt;

&lt;p&gt;When a function needs to assess the roles or permissions of a user, it will often reach out to an Authorization service that - given a particular user id - can provide the roles and permissions of that user. Often times, these roles and permissions will take the form of scopes. In my mind, scopes come in two flavors - &lt;em&gt;atomic&lt;/em&gt; and &lt;em&gt;aggregated&lt;/em&gt;. An atomic scope is a permission which is fine-grained and particular, such as “edit user account information”. An aggregated scope often encompasses atomic scopes in some way to make a larger, logical piece - that would often be referred to as a &lt;em&gt;role&lt;/em&gt;. For example, an aggregated scope of admin may encompass atomic scopes such as “disable user accounts”, “edit organization information”, etc. In practice, I often like my scopes to take a form of “${namespace}.${role}/${restriction}” for my aggregated scopes. For example org.admin/:orgId. For atomic scopes, I often like to follow “${namespace}:${action}:${target}”, such as “user:edit:account”. &lt;/p&gt;

&lt;p&gt;To further de-couple your handler from having to assess the particular roles/permissions of a user, you may choose to offload that evaluation to a sidecar running with your backend service called “Open Policy Agent”. Open Policy Agent (OPA for short) is designed to exclusively author policies to evaluate given some input in a very quick, performant manner. It’s often used toady - by many FAANG companies, open-source and commercial databases, etc. - to asses whether an input providing user information on roles/permissions/context is allowed to perform some set of actions. This is often constructed as an “allow/deny” pattern.&lt;/p&gt;

&lt;h3&gt;
  
  
  When our access token expires
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kczDtsUG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m62cr5zelkk5ib9ik6rx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kczDtsUG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m62cr5zelkk5ib9ik6rx.png" alt="Image description" width="880" height="706"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Often when an access token expires, you expect your client to refresh the token themselves. This can be somewhat problematic when a client is in the middle of a transaction or a series of REST calls that need to happen in succession without loss of access.&lt;/p&gt;

&lt;p&gt;In these case scenarios, it can be beneficial to provide user’s with a renewed access and refresh token when our backend services received an expired access token with a valid refresh token. However, if a client is making 100 REST calls in parallel, we don’t want to refresh this token 100 times. This is a variant of the cache stampede or “Thundering Herd” problem, where you don’t want a particular cache miss (or in our case expired access token) to cause an exponential increase in unnecessary work (e.g. refreshing the cache, renewing the access token). In this case, the first caller will request a lock in the database that specifies that a request is in progress to refresh the token. Of course, before requesting this lock, our first caller may check to see if the “cache” has a recent renewed access token for the user (thus skipping this process). If we do need to refresh the token, this lock is used by subsequently callers to stop and wait, preventing a flurry of access token refresh requests. These requests will enter a loop (with some known upper bound and backoff) to continually check the cache for the presence of a lock or a recently renewed access token. In the off chance our process has failed and neither is present, we begin this process anew and the next caller grabs the lock and beings the token refresh process. Otherwise, if the lock is removed and the access token made available in the cache, all requests are expecting to return the same access token.&lt;/p&gt;

&lt;p&gt;If you want me to elaborate on anything I’ve talked about here, feel free to drop me a comment or DM (or go find me on LinkedIn).&lt;/p&gt;

</description>
      <category>authn</category>
      <category>authz</category>
      <category>microservices</category>
      <category>architecture</category>
    </item>
    <item>
      <title>GraphQL Federation: Microservices Done Right</title>
      <dc:creator>Nicholas Frush</dc:creator>
      <pubDate>Mon, 17 Jan 2022 20:28:47 +0000</pubDate>
      <link>https://dev.to/cawfeecoder/graphql-federation-microservices-done-right-4oli</link>
      <guid>https://dev.to/cawfeecoder/graphql-federation-microservices-done-right-4oli</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Now a days it seems everybody is or wants to do microservices. The endless choice of flavors - gRPC, JSONRPC, GraphQL, etc. - makes it hard to land on a good architectural decision. I've too often seen a microservice turn into a "micro"-lith. I'm not professing to have the right answer for anyone's particular set of constraints - just authoring my experience with GraphQL and giving some of my own insights.&lt;/p&gt;

&lt;h2&gt;
  
  
  Graph - What is it?
&lt;/h2&gt;

&lt;p&gt;GraphQL is an API specification which shifts query information from REST Query Parameters along many different endpoints to a JSON payload made to a single endpoint. The (claimed) beauty is that it becomes much more ergonomic to request the exact amount of data you need, as opposed to appending request parameters &lt;em&gt;sine fine&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;The other added benefit comes with respect to reducing round trips between the server and the client. Instead of making a request for 4 related entities across 4 requests, GraphQL allows you to query the relationships between those entities and return them in one request. This can become incredibly important as you use information from one entity to do a DB lookup (or join) to get particular information.&lt;/p&gt;

&lt;p&gt;The final benefit is strong typing - GraphQL enforces you can only send and request particular fields that are defined in your schema. Requesting a non-existent field or sending bogus data will result in an error to the client, often describing what went wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;p&gt;Before I discuss where GraphQL can fit in the microservice landscape, I think it's important to lay out a traditional scenario with GraphQL - and then show how we can break it up.&lt;/p&gt;

&lt;p&gt;The following schema is very popular - it's the example most GraphQL-ers are familiar with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  extend Query {
    me: User
    topProducts(first: Int = 5): [Product]
  }

  type User {
    id: ID!
    name: String
    username: String
    reviews: [Review]
  }

  type Review {
    id: ID!
    body: String
    author: User
    product: Product
  }

  type Product {
    upc: String!
    name: String
    weight: Int
    price: Int
    inStock: Boolean
    shippingEstimate: Int
    reviews: [Review]
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are constructing a service which has relationships between Reviews, Products, and Accounts. In a sense, you can think of this as a holistic graph - where Accounts, Reviews, and Products share edges that form a relationship. For example, we might say that a Product has many reviews (one-to-many), but a Review focuses on only one product (one-to-one). &lt;/p&gt;

&lt;p&gt;In a traditional GraphQL setup, we'd write resolvers for each of these types - including resolution of nested types. &lt;/p&gt;

&lt;p&gt;An example query may look something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query {
  topProducts(first: 10) {
    name
    weight
    price
    reviews {
      body
      author {
        username
        name
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In traditional REST, this may have required 3 calls - one to get the batched list of products, another to get the reviews for each product, another to retrieve our users. A less than ideal REST implementation may take more than 3 calls. &lt;/p&gt;

&lt;h2&gt;
  
  
  But what about the microservices part?
&lt;/h2&gt;

&lt;p&gt;If you know anything about large graphs, they usually can be broken into connected components - or sub-graphs. That is, the  maximal subset of the space cannot be covered by a union of other sub-graphs.&lt;/p&gt;

&lt;p&gt;If we look at our schema above, there are 3 obvious sub-graphs - Users, Products, and Reviews. In a sense, it is not the responsibility of the service handling users to know that it has reviews (or products for that matter). There's also a 4th hidden sub-grpah above - Inventory - in the form of the inStock and shippingEstimate fields on the Product. Our service handling our catalog of products is probably best served separately from the API used by our warehouse. &lt;/p&gt;

&lt;p&gt;Naturally, we'd want to break this up as independent services - for separation of concerns and independent scaling. In GraphQL, one can do this by using Federation. Federation allows an API Gateway - called the Federation Gateway - to query each sub-graph for it's part of the schema and "stitch" them back into the larger graph. When this gateway receives a query, it can determine which part of the query can be serviced by each backing sub-graph and then executes the queries needed against each service. On some implementations - these executions can occur in parallel.&lt;/p&gt;

&lt;p&gt;Broken up, this may look like:&lt;/p&gt;

&lt;p&gt;User Service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  extend type Query {
    me: User
  }
  type User @key(fields: "id") {
    id: ID!
    name: String
    username: String
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Product Service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  extend type Query {
    topProducts(first: Int = 5): [Product]
  }
  type Product @key(fields: "upc") {
    upc: String!
    name: String
    price: Int
    weight: Int
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Warehouse Service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  extend type Product @key(fields: "upc") {
    upc: String! @external
    weight: Int @external
    price: Int @external
    inStock: Boolean
    shippingEstimate: Int @requires(fields: "price weight")
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Review Service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  type Review @key(fields: "id") {
    id: ID!
    body: String
    author: User @provides(fields: "username")
    product: Product
  }
  extend type User @key(fields: "id") {
    id: ID! @external
    username: String @external
    reviews: [Review]
  }
  extend type Product @key(fields: "upc") {
    upc: String! @external
    reviews: [Review]
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'll note, when a service expects fields (to be able to do a resolution) it will either declare them as @external (e.g. coming from another service) or @requires. @requires is specifically in the fact the client may not specify the required fields (e.g. price, weight), but they are needed by the service to produce an output (e.g. shippingEstimate). &lt;/p&gt;

&lt;h2&gt;
  
  
  Ok, but why isn't this rubbish?
&lt;/h2&gt;

&lt;p&gt;In my mind, GraphQL makes it very easy to think in terms of "Domain" models and boundaries. A sub-graph is - in essence - a domain boundary. The additional strong typing and possible parallel execution fits right in line with my own methodologies and technological attractions (Rust)&lt;/p&gt;

</description>
      <category>rust</category>
      <category>graphql</category>
      <category>microservices</category>
      <category>kubernetes</category>
    </item>
  </channel>
</rss>
