<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Tailcall Blog</title>
        <link>https://tailcall.run/blog/</link>
        <description>Tailcall Blog</description>
        <lastBuildDate>Sat, 14 Dec 2024 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <copyright>Copyright © 2026 Tailcall, Inc.</copyright>
        <item>
            <title><![CDATA[GraphQL Configuration v2]]></title>
            <link>https://tailcall.run/blog/migrating-to-graphql-configuration-v2/</link>
            <guid>https://tailcall.run/blog/migrating-to-graphql-configuration-v2/</guid>
            <pubDate>Sat, 14 Dec 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Our current configuration architecture, while aiming for flexibility, has introduced complexities that hinder its usability and maintainability. This blog outlines the existing design, its shortcomings, and a proposed solution for a simpler, more predictable configuration experience.]]></description>
            <content:encoded><![CDATA[<p>Our current configuration architecture, while aiming for flexibility, has introduced complexities that hinder its usability and maintainability. This blog outlines the existing design, its shortcomings, and a proposed solution for a simpler, more predictable configuration experience.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="current-configuration-design">Current Configuration Design<a href="https://tailcall.run/blog/migrating-to-graphql-configuration-v2/#current-configuration-design" class="hash-link" aria-label="Direct link to Current Configuration Design" title="Direct link to Current Configuration Design">​</a></h2>
<p>Currently, developers define configurations using <code>.graphql</code>, <code>.json</code>, or <code>.yml</code> formats. These configurations contain schema information (types &amp; resolvers), runtime information (upstream settings, server settings, telemetry), and links to other configurations. This linking mechanism was introduced to enable modular configuration management, particularly within larger organizations where each team wants to maintain their own configuration and compose them together to run a federated GraphQL server. A merge algorithm within the Tailcall binary, combines the linked configurations into a single effective configuration. Beyond configuration files, linking also supports external resources like JWTKS, Protobuf files, and JavaScript files.</p>
<p>Typical folder structure with linked configurations:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono">Current Folder Structure</span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockTitle_Ktv7">Current Folder Structure</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">├── .tailcallrc.graphql</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">├── .tailcallrc.schema.json</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">├── main.graphql</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">├── users.graphql</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">└── products.graphql</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>In the above example, <code>main.graphql</code> links to <code>users.graphql</code> and <code>products.graphql</code> using the <code>@link</code> directive. The merge algorithm combines these linked configurations into a single effective configuration.</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono">main.graphql</span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockTitle_Ktv7">main.graphql</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv codeBlockLinesWithNumbering_o6Pm"><span class="token-line codeLine_lJS_" style="color:#fff"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token keyword" style="color:#C586C0">schema</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#fff"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token directive function" style="color:#FDEA2F">@link</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">src</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"./users.graphql"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#fff"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token directive function" style="color:#FDEA2F">@link</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">src</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"./products.graphql"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#fff"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">query</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Query</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#fff"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="merging-algorithm">Merging Algorithm<a href="https://tailcall.run/blog/migrating-to-graphql-configuration-v2/#merging-algorithm" class="hash-link" aria-label="Direct link to Merging Algorithm" title="Direct link to Merging Algorithm">​</a></h2>
<p>The merging process in the current configuration design is intricate due to its implementation of three different algorithms, each tailored to handle specific aspects of the configurations.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="deep-merge-right-for-runtime-configurations">Deep Merge Right for Runtime Configurations<a href="https://tailcall.run/blog/migrating-to-graphql-configuration-v2/#deep-merge-right-for-runtime-configurations" class="hash-link" aria-label="Direct link to Deep Merge Right for Runtime Configurations" title="Direct link to Deep Merge Right for Runtime Configurations">​</a></h3>
<p>For <strong>runtime configurations</strong>, the merge algorithm performs a <strong>deep merge right</strong>, also known as a recursive merge. This process involves merging multiple configuration objects by traversing each level of their nested structures. Here's how it works:</p>
<ul>
<li><strong>Recursive Traversal</strong>: The algorithm starts at the top level of the configuration objects and recursively moves through each nested level.</li>
<li><strong>Right-Biased Overwriting</strong>: When the same key or property exists in both configurations being merged, the value from the configuration on the <strong>right</strong> (the latter one in the sequence) overwrites the one on the left.</li>
<li><strong>Combining Nested Objects</strong>: If the property is itself an object or array, the algorithm continues to merge the nested elements deeply.</li>
</ul>
<p>This approach allows developers to override specific settings in a controlled manner.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="covariant-merging-for-output-types-in-schema-configurations">Covariant Merging for Output Types in Schema Configurations<a href="https://tailcall.run/blog/migrating-to-graphql-configuration-v2/#covariant-merging-for-output-types-in-schema-configurations" class="hash-link" aria-label="Direct link to Covariant Merging for Output Types in Schema Configurations" title="Direct link to Covariant Merging for Output Types in Schema Configurations">​</a></h3>
<p>In <strong>schema configurations</strong>, the merging process differs based on whether the types are inputs or outputs. For <strong>output types</strong>—such as GraphQL object types returned by queries—the merge algorithm is <strong>covariant</strong>.</p>
<ul>
<li><strong>Covariant Merging</strong>: Covariance, in type theory, allows a type to be replaced with its subtype. In the context of merging, covariant merging means combining all the fields from the output types with the same name across different configurations.</li>
<li><strong>Field Union</strong>: The resulting merged output type includes the union of all fields from each configuration.</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="contravariant-merging-for-input-types-in-schema-configurations">Contravariant Merging for Input Types in Schema Configurations<a href="https://tailcall.run/blog/migrating-to-graphql-configuration-v2/#contravariant-merging-for-input-types-in-schema-configurations" class="hash-link" aria-label="Direct link to Contravariant Merging for Input Types in Schema Configurations" title="Direct link to Contravariant Merging for Input Types in Schema Configurations">​</a></h3>
<p>For <strong>input types</strong>—such as input objects used in mutations—the algorithm employs <strong>contravariant</strong> merging.</p>
<ul>
<li><strong>Contravariant Merging</strong>: Contravariance allows a type to be substituted with its supertype. When merging input types, contravariant merging takes the intersection of fields from types with the same name.</li>
<li><strong>Field Intersection</strong>: The merged input type contains only the fields that are common to all configurations.</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="issues-with-the-current-design">Issues with the Current Design<a href="https://tailcall.run/blog/migrating-to-graphql-configuration-v2/#issues-with-the-current-design" class="hash-link" aria-label="Direct link to Issues with the Current Design" title="Direct link to Issues with the Current Design">​</a></h2>
<p>The existing design suffers from several key issues:</p>
<ol>
<li><strong>Unintuitive Merge Algorithm:</strong> The complexity of the merge algorithm makes it difficult to predict the final configuration outcome. Runtime configurations are sometimes unintentionally overridden during the merge process. For example, if two linked configurations define different ports, the final port becomes unpredictable and might default to an undesirable setting.</li>
<li><strong>Confusing Relative Paths:</strong> Linking via relative file paths or URLs introduces ambiguity. It's often unclear whether a relative path is relative to the current directory, the current file, or some other location.</li>
<li><strong>Unused Formats:</strong> The <code>.json</code> and <code>.yml</code> options for writing configurations are rarely used in practice, adding unnecessary complexity to the system.</li>
<li><strong>Unstructured Linking Data:</strong> Linking external resources requires handling unstructured data, leading to further complications. For example, JWTKS linking requires caching mechanisms, Protobuf files require path specifications, and supporting multiple JavaScript files introduces its own set of challenges.</li>
<li><strong>Inconsistency Between Local and Merged Configurations:</strong> A configuration that works perfectly in isolation might break after being merged, making debugging and testing a significant challenge.</li>
<li><strong>Inflexible Merge Strategy:</strong> The fixed deep merge right algorithm limits users who need different merging approaches like deep merge left or shallow merge.</li>
<li><strong>Fighting GraphQL Grammar:</strong> In the <code>main.graphql</code> you will observe that a directive is applied to <code>schema</code> and a field <code>query</code> is defined. The <code>query</code> field is required because without it the schema will be invalid. This is a limitation of the GraphQL grammar and affects the overall design of the configuration.</li>
</ol>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="proposed-configuration-design">Proposed Configuration Design<a href="https://tailcall.run/blog/migrating-to-graphql-configuration-v2/#proposed-configuration-design" class="hash-link" aria-label="Direct link to Proposed Configuration Design" title="Direct link to Proposed Configuration Design">​</a></h2>
<p>The proposed design simplifies the configuration system by separating concerns and streamlining the merging process:</p>
<ol>
<li><strong>Split Configuration:</strong> Configurations are split into two distinct types: <strong>Runtime</strong> and <strong>Schema</strong>. This deprecates the use of <code>@upstream</code>, <code>@server</code>, <code>@telemetry</code> and <code>@link</code> directives within schema configurations.</li>
<li><strong>Runtime Configuration:</strong> Contains only runtime information like <strong>upstream</strong> settings, <strong>server</strong> settings, <strong>telemetry</strong> and <strong>links</strong> to other resources. This is written exclusively in <code>.json</code> or <code>.yml</code> format.</li>
<li><strong>Schema Configuration:</strong> Contains only schema information such as <strong>types</strong>, and resolvers. This is written exclusively in <code>.graphql</code> format.</li>
<li><strong>Simplified Merging:</strong> Merging is only allowed for schema configurations and follows a straightforward covariant and contravariant algorithm like before.</li>
<li><strong>Streamlined Linking:</strong> Linking is only possible within the runtime configuration. A single runtime configuration can link to multiple resources, including multiple schema configurations.</li>
<li><strong>Single Runtime Configuration:</strong> Only one runtime configuration is permitted, eliminating potential conflicts and simplifying management.</li>
</ol>
<p>The new folder structure with linked configurations would look as follows:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono">New Folder Structure</span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockTitle_Ktv7">New Folder Structure</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">├── .tailcallrc.graphql</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">├── .tailcallrc.schema.json</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">├── main.yml</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">├── users.graphql</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">└── products.graphql</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>In the above example, <code>main.yml</code> links to <code>users.graphql</code> and <code>products.graphql</code> using the <code>@link</code> directive. The merge algorithm combines these linked configurations into a single effective configuration.</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono">main.yml</span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-yml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockTitle_Ktv7">main.yml</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yml codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv codeBlockLinesWithNumbering_o6Pm"><span class="token-line codeLine_lJS_" style="color:#fff"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token key atrule" style="color:#b76b01">server</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#fff"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token key atrule" style="color:#b76b01">port</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">8000</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#fff"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain"></span><span class="token key atrule" style="color:#b76b01">configs</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#fff"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#b76b01">src</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"./users.graphql"</span><span class="token plain"></span></span><br></span><span class="token-line codeLine_lJS_" style="color:#fff"><span class="codeLineNumber_Tfdd"></span><span class="codeLineContent_feaV"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#b76b01">src</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"./products.graphql"</span></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This would clearly separate the runtime and schema configurations, making it easier to manage and predict the final configuration outcome. The tailcall command would work like before, but with a more predictable outcome.</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono">Command</span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockTitle_Ktv7">Command</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">tailcall start ./main.yml</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>However, like before starting with a <code>.graphql</code> file would still be possible.</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono">Command</span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockTitle_Ktv7">Command</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">tailcall start ./users.graphql</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="migration-strategy">Migration Strategy<a href="https://tailcall.run/blog/migrating-to-graphql-configuration-v2/#migration-strategy" class="hash-link" aria-label="Direct link to Migration Strategy" title="Direct link to Migration Strategy">​</a></h2>
<p>The proposed changes are designed to simplify the configuration process, and the migration should be relatively straightforward for most users. Existing configurations can be readily split into separate runtime and schema files. The clear separation of concerns and the simplified merging process will make future configuration management more predictable and less error-prone. Tools and documentation will be provided to further facilitate a smooth transition to the new design.</p>
<p>Would love to hear about your thoughts on this proposed design. Feel free to reach out to me on the usual channels!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Lessons from the Frontlines: Our GraphQL Adventure at Dream11]]></title>
            <link>https://tailcall.run/blog/dream11-graphql-case-study/</link>
            <guid>https://tailcall.run/blog/dream11-graphql-case-study/</guid>
            <pubDate>Fri, 30 Aug 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn how Dream11 leverages GraphQL to build a scalable, performant, and user-friendly fantasy sports platform.]]></description>
            <content:encoded><![CDATA[<p><strong>Picture this:</strong></p>
<p>200 million users, countless fantasy teams, and a platform that needs to keep up with the lightning-fast pace of live sports. That was the exciting challenge we faced at <a href="https://www.dream11.com/" target="_blank" rel="noopener noreferrer">Dream11, India's largest fantasy sports platform</a>.</p>
<p>As a former employees, We're thrilled to share how we harnessed the power of GraphQL to create a platform that's not just scalable and performant, but also a joy for both users and developers to interact with.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="case-study-dream11s-graphql-journey">Case Study: Dream11's GraphQL Journey<a href="https://tailcall.run/blog/dream11-graphql-case-study/#case-study-dream11s-graphql-journey" class="hash-link" aria-label="Direct link to Case Study: Dream11's GraphQL Journey" title="Direct link to Case Study: Dream11's GraphQL Journey">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-challenge-taming-the-monolith">The Challenge: Taming the Monolith<a href="https://tailcall.run/blog/dream11-graphql-case-study/#the-challenge-taming-the-monolith" class="hash-link" aria-label="Direct link to The Challenge: Taming the Monolith" title="Direct link to The Challenge: Taming the Monolith">​</a></h3>
<p>During our time at Dream11, we embarked on several major re-architecture projects to supercharge our systems' performance and scalability. But perhaps the most exhilarating (and occasionally hair-raising) journey was our transition from a monolithic architecture to microservices.</p>
<p>Now, let us tell you, this wasn't a walk in the park. We faced hurdles at every turn. But we had one golden rule that guided us through the chaos: "The frontend should never be shackled by the backend's structure." This mantra led us to an exciting solution: using GraphQL as a backend-for-frontend (BFF).</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-magic-of-backend-for-frontends-bffs">The Magic of Backend-for-Frontends (BFFs)<a href="https://tailcall.run/blog/dream11-graphql-case-study/#the-magic-of-backend-for-frontends-bffs" class="hash-link" aria-label="Direct link to The Magic of Backend-for-Frontends (BFFs)" title="Direct link to The Magic of Backend-for-Frontends (BFFs)">​</a></h2>
<p>Think of BFFs as the ultimate middlemen, sitting between our microservices and frontend applications. They're not just passing messages; they're tailoring responses and error handling for each client application. It's like having a personal assistant for each of your frontend apps! By implementing BFFs, we unlocked a treasure trove of advantages:</p>
<ul>
<li><strong>No more data bloat:</strong> Say goodbye to under-fetching and over-fetching. Our BFFs serve each client exactly what they need, nothing more, nothing less.</li>
<li><strong>Divide and conquer:</strong> With BFFs handling the heavy lifting of data formatting, our frontend developers could focus on crafting amazing user experiences.</li>
<li><strong>Network efficiency:</strong> Imagine making one call instead of ten. That's the power of BFFs – they fetch data from multiple sources in one go, keeping our network traffic lean and mean.</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="dream11s-microservices-odyssey">Dream11's Microservices Odyssey<a href="https://tailcall.run/blog/dream11-graphql-case-study/#dream11s-microservices-odyssey" class="hash-link" aria-label="Direct link to Dream11's Microservices Odyssey" title="Direct link to Dream11's Microservices Odyssey">​</a></h2>
<p>Now, we could have gone for the "big bang" approach, but where's the fun (or safety) in that? Instead, we opted for a more measured journey:</p>
<ol>
<li>First, we moved all our monolith APIs to a GraphQL-based BFF.</li>
<li>We then directed all frontend applications to this new BFF, even adding a lint check to catch any sneaky direct API calls to the monolith.</li>
<li>Once we were confident in our new setup, we began the exciting process of moving APIs to microservices, one by one.</li>
</ol>
<p>Sure, it was a longer path, but it was smoother sailing. We minimized risks, kept our testing manageable, and, most importantly, kept our sanity intact!</p>
<p><img decoding="async" loading="lazy" alt="Micro service journey" src="https://tailcall.run/assets/images/monolith-to-microservices-fb96366f894684422eb2d07d4881d009.png" width="1537" height="1139" class="img_ev3q"></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="unveiling-dream11s-bff-architecture">Unveiling Dream11's BFF Architecture<a href="https://tailcall.run/blog/dream11-graphql-case-study/#unveiling-dream11s-bff-architecture" class="hash-link" aria-label="Direct link to Unveiling Dream11's BFF Architecture" title="Direct link to Unveiling Dream11's BFF Architecture">​</a></h2>
<p>Let me pull back the curtain on our BFF architecture at Dream11. It was a symphony of components working in perfect harmony:</p>
<ul>
<li><strong>Frontend Applications:</strong> The face of our platform, built in React. They took the data from our GraphQL server and transformed it into the engaging user interfaces our players loved.</li>
<li><strong>GraphQL Server:</strong> The maestro of our operation, built with Apollo Server. It orchestrated data fetching from microservices and delivered it beautifully to our frontend applications.</li>
<li><strong>API Gateway:</strong> The bouncer of our architecture, powered by Kong. It managed the flow of requests from the GraphQL server to our microservices.</li>
<li><strong>Microservices:</strong> Our data virtuosos, crafted with Node.js and Express. They fetched data from databases and passed it to the GraphQL server.</li>
</ul>
<p><img decoding="async" loading="lazy" alt="Architecture diagram explaining Dream11 GraphQL Based BFF Architecture" src="https://tailcall.run/assets/images/dream11_bff-1926c9fdc3f367c97c4a82106a253763.png" width="1694" height="601" class="img_ev3q"></p>
<p>Now, you might be scratching your head, wondering, "Why put an API Gateway after the GraphQL server?" Great question! It all comes down to resilience. We needed fine-grained control over rate limiting and circuit breaking for each microservice. GraphQL's single endpoint made this tricky, so we added this extra layer to keep our systems robust and responsive.</p>
<p>This architecture was our trusted companion for years, scaling effortlessly to serve tens of millions of users. But as with any great journey, we eventually hit a new challenge: the performance of our GraphQL server started to feel the strain of our massive success.</p>
<div style="position:relative;padding-bottom:56.25%;height:0;overflow:hidden;max-width:100%"><iframe src="https://www.youtube.com/embed/Esb7oQ0PuXw?si=kuSvBFaUki2GYJie&amp;rel=0" frameborder="0" title="Lessons for Scaling GraphQL" style="position:absolute;top:0;left:0;width:100%;height:100%;border:0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-graphql-advantage-dream11s-secret-weapon">The GraphQL Advantage: Dream11's Secret Weapon<a href="https://tailcall.run/blog/dream11-graphql-case-study/#the-graphql-advantage-dream11s-secret-weapon" class="hash-link" aria-label="Direct link to The GraphQL Advantage: Dream11's Secret Weapon" title="Direct link to The GraphQL Advantage: Dream11's Secret Weapon">​</a></h2>
<p>Implementing GraphQL for our BFF layer wasn't just a technical decision – it was a game-changer. Here's why we fell in love with GraphQL:</p>
<ul>
<li><strong>Network efficiency on steroids:</strong> We slashed unnecessary network calls, making our app lightning-fast.</li>
<li><strong>Bug squashing made easy:</strong> Type-safe queries generated at compile time meant fewer surprises in production.</li>
<li><strong>Performance boost:</strong> We fetched only the data we needed, nothing more, nothing less. Also reduced multiple round trips to the server.</li>
<li><strong>Flexibility unleashed:</strong> We could structure our data exactly how we wanted, adapting to new requirements with ease.</li>
<li><strong>Cross-platform harmony:</strong> Consistency across all platforms became a breeze.</li>
<li><strong>Developer joy:</strong> Our frontend team couldn't stop raving about how easy it was to work with.</li>
<li><strong>Time is money:</strong> Reduced development time meant we could innovate faster.</li>
<li><strong>Happy developers, happy life:</strong> The improved developer experience led to more creative solutions and happier teams.</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-next-chapter-from-challenges-to-solutions">The Next Chapter: From Challenges to Solutions<a href="https://tailcall.run/blog/dream11-graphql-case-study/#the-next-chapter-from-challenges-to-solutions" class="hash-link" aria-label="Direct link to The Next Chapter: From Challenges to Solutions" title="Direct link to The Next Chapter: From Challenges to Solutions">​</a></h2>
<p>The journey we embarked on at Dream11 wasn't just about solving immediate problems – it was about reimagining how we approach backend architecture for massive-scale applications. The challenges we faced, the solutions we crafted, and the lessons we learned have directly shaped the development of Tailcall.</p>
<p>Tailcall emerged from the crucible of these experiences, designed to make the implementation of GraphQL and similar migration journeys significantly easier for other companies. Here's how Tailcall is addressing the pain points we encountered:</p>
<ol>
<li>
<p><strong>Simplified Migration:</strong> Tailcall provides tools to streamline the transition from monolithic architectures to microservices, making the journey we undertook at Dream11 more accessible and less risky for other organizations.</p>
</li>
<li>
<p><strong>Performance at Scale:</strong> Drawing from our experiences with GraphQL performance challenges, Tailcall incorporates optimizations that allow GraphQL servers to handle massive loads more efficiently.</p>
</li>
<li>
<p><strong>Automated BFF Generation:</strong> Recognizing the power of the BFF pattern, Tailcall offers features to automatically generate and manage Backend-for-Frontend layers, reducing development time and potential errors.</p>
</li>
<li>
<p><strong>Enhanced Resilience:</strong> Our struggles with rate limiting and circuit breaking at the GraphQL layer have informed Tailcall's design, incorporating these features more seamlessly into the GraphQL ecosystem.</p>
</li>
<li>
<p><strong>Developer Experience:</strong> The joys and pains of our development team at Dream11 have directly influenced Tailcall's focus on developer experience, making it easier for teams to work with GraphQL and microservices architectures.</p>
</li>
<li>
<p><strong>Flexible Scaling:</strong> Tailcall embodies the lessons learned from scaling Dream11 to millions of users, offering flexible scaling options that grow with your application.</p>
</li>
</ol>
<p>The challenges we faced at Dream11 weren't unique – they're common hurdles for any company dealing with rapid growth and complex data needs. Tailcall is our answer to these industry-wide challenges, encapsulating years of hard-won wisdom into a tool that makes these architectural transitions smoother, faster, and more reliable.</p>
<p>As we continue to evolve Tailcall, we're excited to see how it will empower other companies to undertake their own transformative journeys, armed with the insights and tools born from our experiences. The future of backend architecture is bright, and we're thrilled to be part of shaping it.</p>
<p>Stay tuned, fellow tech enthusiasts. With Tailcall, we're not just solving yesterday's problems – we're building tomorrow's solutions.</p>]]></content:encoded>
            <category>GraphQL</category>
            <category>Backend-for-Frontend</category>
            <category>Microservices</category>
            <category>Scalability</category>
        </item>
        <item>
            <title><![CDATA[GraphQL and Microservices: A Match Made in Heaven?]]></title>
            <link>https://tailcall.run/blog/graphql-match-microservices/</link>
            <guid>https://tailcall.run/blog/graphql-match-microservices/</guid>
            <pubDate>Sun, 18 Aug 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Is it really worth combining GraphQL with microservices or is it just a new shiny object with all the hype?]]></description>
            <content:encoded><![CDATA[<p>Is it really worth combining GraphQL with microservices or is it just a new shiny object with all the hype?</p>
<!-- -->
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="introduction">Introduction<a href="https://tailcall.run/blog/graphql-match-microservices/#introduction" class="hash-link" aria-label="Direct link to Introduction" title="Direct link to Introduction">​</a></h2>
<p>In the fast-changing land of software development, two concepts have been gathering momentum: <strong>GraphQL</strong> and <strong>microservices</strong>. While the latter helps businesses decompose their applications into small independent services, the former makes it possible for the clients of these services to request only data of interest. Each of these technologies address specific challenges inherent in building modern applications, and when combined, they offer a powerful toolkit for developers aiming to create efficient and robust APIs.</p>
<p>But is it really worth combining the two or is it just a new shiny object with all the hype? Is it really cost-efficient and time-saving or just an expensive thing for tech majors? Read on as I explore the challenges, features and considerations of using GraphQL with microservices. 🚀</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="what-are-microservices">What Are Microservices?<a href="https://tailcall.run/blog/graphql-match-microservices/#what-are-microservices" class="hash-link" aria-label="Direct link to What Are Microservices?" title="Direct link to What Are Microservices?">​</a></h2>
<p><img decoding="async" loading="lazy" alt="independent scaling" src="https://tailcall.run/assets/images/scaling-3e4bd00fdccd6d0655cb5e2d3f7214a1.png" width="1144" height="654" class="img_ev3q"></p>
<p>Compared to traditional monolithic architecture, in which all the constituents of an application are usually closely integrated and interwoven, <strong>microservices</strong> present a very compelling option. Microservices really orient the technique of decomposition and isolation. Development, scaling, and deployment for every service can be independent. It provides high flexibility and a better developer experience.</p>
<p>The three key characteristics of microservices are <strong>scalability</strong>, <strong>flexibility</strong>, and <strong>maintainability</strong>. The components of the system can be scaled as needed, and in terms of priority. Different languages and technologies can also be used to realize each service according to use cases appropriate for individual use, which can be developed and maintained independently by different teams. Cleanup will not only be in the debugging phase; it will also accelerate the development cycle, from which you can easily adapt and evolve your application over time.</p>
<p><img decoding="async" loading="lazy" alt="spotify logo" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZoAAAB7CAMAAAB6t7bCAAAAgVBMVEX///8e12AA1VQX1l0A1VcA1VMM1lpI3XmD5Z/b9+Ly/PVU3X5J3Xtk4IsK1llW34Po++75/vvg+ei+8c1f4Iid67TJ9Nbs+/HA8s/Q9duW6a822m7V9t+i7Li48Mmx78Ny45WI56Ur2GeQ6Kt145Z95Z2q7b4923Kz78Vs4pAA0kRCT57EAAAS0ElEQVR4nO1dZ7eqOhCVNBUVxN4LFuT+/x/4CAgpZCiKnuN57g93rXukhOzMZDIzmbRaD2DeXVxXx/NhMBkczsfVdrwZPvKYLxrFcHd0GULIcRjDHIw5Don+EHT23Z9u3P8X9uJiRaRgywTMCMLh/is+74d9cwliRlYEGCHB9svOW7E8RDJRwstdegjp7X66uf8bePs1LZMXhR1kreY/3ej/A7ytVVFgJBDW+ZLzamwtUpsYDsc52j/d9j+Nxbq+xGTk4O1PN//vYj6hDxPDgYLNT3/CH8WV1Jn8TcC089Mf8Rdhu/RJYjiI//URNI0Ze1ZkEmD6nXGaxaoJkUlAw5/+mD+FCWqMmchUW3/XOE3BDpwGmeGuz++E0wyGVjPTjMQNmv30R/0JjPBTixkz6PinP+sPYMRewEzEzdcd/SyGr5AZDrT46U/7cNjWi5iJuFn+9Md9NoKmLQABzL7xzycwadZq1rjxvZ/+vs/FqcmVZh7M/ekP/FgsmvPOmIFOP/2JH4r5K7VZAvo1BR5C73UmQApsfaebB7B9tTrjcL5u6PoYvtYESEH/0spzeD2edq/XA+7r1RnHH1Jp3oASx0Fo9eL3jN+hzjjI8cVf8i7Y1t1sohPgioYGoV/BQRNvDMiAH/S2oT/iFBCOk/yaYH49+JTDco+7JwOJU1LACHMIil6D1203PJ8vHOdzOOkHVvRnhBxWiyQ2qNm236kBd5KaQWo25DDSdHf/PcYOei6tyINIiTjB/fPpNuuaczG90XK87QwCQjlD1bihVWOefDOPHwuo37tsl78rG3Qgzc3kKv+y1TLE2VNW6SovNJzu9WE7qyiOw9n0ECAK7L5RmwrpZgX2NiDIwengiwYJ611/kS6UXfSOPH+e9Fn7KWpyQoMJbR8XtYept9wOLFqaJI3KxcY7OvnHYELcd0ey58MUml6VW8cklbXP2VNPUXPVhAa5t8fnrtF1gmmhcmOHsmeMMeA0wjR4KzkeIncgzTfblqVG2M/z/BrkKWrWakc6zwbyvVnHL9JtpEQxdQpyrTF1R082rwbsbCGO2+ov8hxARW73MT81PEPNTHUEoEZSLDYRO9Aq1ilepYXFjglGpk00sBIkavraL0JxsV72V5M99Qw1A6ULcV3jFsRsQMyig/2i2zqlLiPkvivpEKZGWM9y+FaJqzCuCPEz1MxVGWxGaO6PXpm3tBXlpd0q+CVID76/URRQ07rFAw+jtaRgj2KOxOx83e2ng2cyizUjgDZroe5Mu6fYGbzeruLLo++yBYqoac1PgWX1lDWNm30r9tN+XD6eu9pTu442PcuatrZh8GplHsWIYD9iEqlbfd7nhyukxgBhUDUxejR9ZpHmEy13vm63gBpNFhqMJuN46Nnd/YEJfnHQeAsh1KRGWAHF02lF7LRZF5sW6/Pu7Lo6XkK33w7W/joI2r3BuXPa7majSi6uqSY4DjTub0j6OmW/4bifmtSNyzWMmtTYYvg0YUwddOWu5sCOdqfBmlIarb3SujR3MOYQ7vd02ufVuKy3RupbwEElrEXs696ITUIOvRrvfAnqUpO1vnxZXQH5SRrt7y+anfqUklK/ZewFpUFnX8TPTDW8oNCAX6isF5ZTljLVva2OneO0dKzEGC22J371DtoP7NVUaIKaS5X3l7TOsIpAwXU5m/YpVCsIIoiSwRXsEtXaQOb0dFualIwXnCkRwnTq9+6426ebC6Ncuh0HUXYpSd/ZhSzSBc5d+Pt6cZ1h/GCp0W76sn7c7bfs5S5v0TCItHwgrl4PVEyMs+t8kv2ecDkOJ5PBXS3cTJEaTMASTsWI5MfqmKf4reIWY+YgxjCTLQwsXRbSAA8yBcvi3nEV/wOjAbw9YX501GpImNCJwuWCYjVaKDR5PGouJP1/HOWYgZcnIG1TM6Y0/d1Z81b19nzqXvRje7vT+D6nyJYyDdiFIp6AldUV1FRQIMLFiO18nIT72/qAEB+RwX+quudmoFMimShFx8WedPhy+SodQn+TaBax+6lNNem2VA9qY2DIX+mTibayRcYuG0kzUrnpp1ATmrwImOwN9y0tIKiLpRyMpqkxGaXS5zrR57rz1tG3fM4Ll7GCyPMzwA4J1bk1VMc0Mo7nuWgrutWgxrIHwIfQfDLvtMCxjdx0RDRNjWmsnTLZ5f6RbkTepT9bhMxr7Rf10s8U5Vl6NUM9adbRX2TeCmVLj8WlZVQENf4AzAqm+mi9FDrpnLX9ImoMXyxCpXz30Sr64Etk0Az/jVr2pbWpQA1OrGPmr9t9dxLB7fWDteXwtU5hygamvbR7vUC7jphLPUiCgJ2yahDyxXArtKISl5IvZvf1VOPU5NfyGzGzciPgHL340t7ve/w/g9a4WKFh5iDCkybGm7mtCqRtD5e76bnvE0TAlQ+mh3jOWa71KZqZ/QGKVUL8aaH3v+I8SWXxKy9WwdqvoSYfQRSPiAfqJfrYizVhbd7RoWbSam0kyB+UJm5489k2XBME0MNI73wIDA5OsydjqfQcLxdZUMwzTw3jlhd3iipPkVwP6soXRwMvsmu1hQKJlxhlxrNODXi5eK4eAhQ/ObyTr7NYoc3+RcptdGqtIGowssLC5b2K4bizJuaEDcxMrOkB3RRaMJyvN9ZnIM1Op8bBndnc8+zuVh0Lok+UvaoY+afZMJL+2clXro8Ts4c9N4L4s++m6F0M1MSX96z85ZIZuVabL4ZJkptnR/+eJ9z5brc6o9YRWNaQfn2n9nA/YaVVbbN2Al40Q4Yv9zMEnVnewNGooUdxyUKpS+GkP1wk/e340op04UtjVGxtLHDUaNQklwsPoHAniVdqO43P4glJZx9nrTkfhCOvG1kDB7MacuBYVyHs8QCQnfwrgEeYrWDMKDvoo0WhBjvKh3t9qa/THD7ZK0VCleuD/FsqZgXuTRM1kudZODOOioUstTD7ezZMU2/Oht8dPhC8L4a9DyoVuKXA/V7OYsi+jPpTpTsVaoiufWX77f49kped5AbfUZ7I7+9pghrhfLKI3Pxx9mySrb1Og/FotAhjE2lipObJnJXuhZZvPoSoiexs0GqMzAI5GUemJr9xx5bakIR4pC2RJj9QKH5O17tNUCNFpRXfhIh/SG54b3w67WztNhlPl8bwVqzMzQBSw93LBTlsltBbEjWm+IgUlnPisSb5ipDBsPCEjZBOFY1QI+xq2XMoPdrsyQWkpoGKMltcTE4BNa2ZD1fKxTQTHIkaY9ahcB4myz3h4jdHWfeCS5aM3EaokYNQQuvus+4BAiTmucaQ8TLvLnfX6enYiXA8rbb7WVdPA9YxJUVqrYiaaMQXVGSnaZhKUGPeGbIVg4O1FC8QNVvj4h13vdEMNaId0pCQ9JW5HwELTZ5T400APIJDiMMPR2Fx8In/3/Hd43YDL0ntS5FmAm9LMDuA50ukLktBjTl5biSooXaViINYStzntGaokQKEmV06z54MhK6gdQ22kteNrqFP4K0zyeYKP7xCqVZdcLdbBSPQG5+BfQf3+gOCGiCLWrpjI0cNHaC2hJgV7imXzVAjr2DSWVxIErTfCPIGYDK4Xi9+gXtMupbHNgc3Y+/Y4E2AN0BDl28LyQVc79Op5Hk2390XYjWTt95BCV0iJnFvXkPUCCdy5uPMmgZ2xLbIUK1TtY4R0p4aHDt7KGpVORvI22xd/YyWxFTOqIEy00JltIq1H1gATHRh4lRpiBppENHEvhBBNAIlCJV4nmsBO6h/1TOU9AzEFIDnGYB9c5WJJ5n2BTXA3HER3TeW/0ehUJDu72qKGpHsdw+GCG3lQDvMqsRragATdlFVpwdIXmkwRsdI3dvBrZpSqTkoUiN1JiQ1wgfWLDVSWmfy4Cx8BSesNV9kg1FX/vAhIDUPrGp38m4jJa8BsilcZa4RIxV6ufeiuUZO5Y4lVhiLBRWVXpAbgGlfvA+azMy5AcWQcoBja1la15gteGmtt5GdAQTYeyWZ18l03Rg1YoTGyYPZtKcHCmTUy6ipmBqA6eTe80No1WnOqCmBiGLH3qi2IhR5SD4zvsaUHCZABuheN68bo0Zyu/AIRTZmnAJvZZU8tHj5EtvRfhAHmHrttc//BhtxjHb49LYDV0TwaLHhsKaYyGO7RpIaYx6rLGUtRbdS89wr+u/uPGmOGhE3Q3splgu4JWJAxm36CicigC/6F92R9jn2aHNbndcEmc+5cWi7h8GZDFoC86AAvDVFJAdpUmNhk7Ojp/WUiKCaB6vsvk/GR3PUiJdHP2VDzLgtI4Up5zntPkKJe9p1i11lXncPLNqLtB7sQJ04FoWkXDKG+f0SNab1/Ubq6fjnjlBwzPRRYtGergMbpEZa/o/87NZCYwhOhrnsKk/Vw9uAVo49x22CHh1vskV9s8KRNn3pmaeGB0r5VYkdJHFl2vsqpXSkqVjw5vTa1NgS70IRA72QILe/5n6/VXdP5ywsL7SRPR3yoF2T7sHItEbeaU57mZp8qeKOpKrvGxRlsnJG2lDqiHQdKFGjt7guNZLIl8QmMtzMGu2RwzO8fbvi4arQVCNNluucylvqQUo1N2CtStpRyv9I1Z1cjknPuB1JyTZO2jxPMiS0Cbs2Nd18QkrJlmbAk1IsaiA2YSVyAOLlvWsY+StZSXkrOa8iVjiq4Y+Z5LScK6cjZQaZnEOKJnLHbGWJZxnLkpwe0r/t4vfUpkbfz1zBxds3aqGHEzfmlwrkGA2qlq2GELCD/PN11h2NRstryOQVEomHsL4mQ+2kto636ShWo9AbSgYiI+dl0o7hVtkILKXiSm8g7ng06u46Fo17tD41+q5Zi5Rl3OvFg+7v0ydie9hd3K7T1SnCarq9wVHOYVFsP+kUcy7V4p9+YZxtjeJFlfJNicLJLZcxcfx2f21pFok0EDrKxzJkBZNBz1cTtJgx5YLLMYpsVnbv9vrUSOGj+2eUMANoNLGI84ZjntqMSbzVlkc6o3/4HjtiBYPpwqQuu73izGJoIrtVOzwXY9tMjZX4K7Q/KecatVn+evUGbEmj0lAp7nFqTurDKuz3HBgVELrMW97o1mlbsSPAnK/G49J+aCghtytSanCEc+NXKdGe9nU1JxNSTA67rMooJrLrfGMYYw9TM1cfBoYmBIAkd4esLVohnMaVTnDSo6iLApd2QWUn71B+uHFm91baxEG0mN3QL5wKMVE7TM/Btp6gRhWCIs9mBmggVfd8YocG2oaLgiFdWA9tkSvNoUFYvVIAegwtqVAummrDKYiRkrG0paspB/thapR9CmB4U4bZEKgJTMhBHnDAUtYqLXdQnF7IkMiAlJLwvY1RvHFuTxoHmOiD6SRn2oS5xjxOjSKDpEoBTSgSWReM9kSgxpwXylFastZeYcAewNSVJE7ZZjts51Uoscw+KiAFkVgmz56rc8MeNJ5bihBULJN2aiqghmnv3s4RnA9SoWKtt3NJzqEd2Rzq1hJ1c3prqtrAmLAT6Jm9+rrLDyNrar68oyzUoutiK+SSGSxiqEl+MjM1npTaW83dYjckNrxNlG9JbM0N02f6JeWGCcf8drYISgrj8KRERIKVNg9o1LS8qR/dEG8ccxAKroUu81nI7pZnfDmZwBWtRmcWNyRuhXuXrBVK68SLqdPznfRvgExk7ojKmzGKqqPXBUOH0wF2dNapjj5fXk+dcDIJL6frJq+adWp4L+6Pk37QC0/jCt7ZzfbSW1vWun/ZLkuShDdRQ3gpqycLgYsCkCX1RyVUOVOgOjlOgX36SFIAAAM1vxKZ6SpVTS2r2ivwtpM4SvzgtfAh1Iz+BYmyHAotX0d3fOL5NR9CzZlhhNqXTk+y2StOuDE+8dSnz6AmqQit7gOvdq5Ciu07uHnuVAodn0GNaWVS4VgFGe84YbDZLvwMagzMkJpH2kCJ4w2i4frMH0GNwQuG13Un3Jdbaajh+swfQU1+WYJZ/fXD8bXTTeNnQH8CNct/uVAsq2GdZXBfenJ64+c+fgI1rZ26YRjT9kMnA3iw5+t5ZpzGj9MKkJOAVHKw/xRmoRWXZI7PAwzKiyOaMa8RPqsJcLvR45hNt3eYKmz+Injd6+kwmYTHGrWychg+eNpmKWjzRxX83zCqs7e2BjOPyvEXAqNXyA1toLLKFy/QafhPnZf+k7DXzdrQ2HnEkP/CCLfJtafj/6JDaD8fudNyHwcd/M7ztT8Wi6IYcg1gcPPfF4/CLskorwbH/04zL8DWvLO5lsg0cPbRFwYMJ+Wp4UVA6+Z9M1/csVg/bqo5uG6BoC9qYQudwlNGDOn8Zmfwn4A3NR/jXAhCLt+1zBvgXQuqxxqAkXV618nmX8zCqicF8EqCu+8a852w9z2wtq/ghaC1qf7mFy/GfHfGYAVbvqHTmRj2237xJgxvx35cfNtJTyuNz4JFaH0Gaz1/8T4Mu+Pt6ngYTNzJIOTHp2++wtI8/gOD6RaoBaNsWAAAAABJRU5ErkJggg==" width="410" height="123" class="img_ev3q"></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="example-spotify">Example: Spotify<a href="https://tailcall.run/blog/graphql-match-microservices/#example-spotify" class="hash-link" aria-label="Direct link to Example: Spotify" title="Direct link to Example: Spotify">​</a></h3>
<p><strong>Spotify</strong> is a prime example of <a href="https://medium.com/codebase/microservices-architecture-at-spotify-beac905e9622" target="_blank" rel="noopener noreferrer">successful microservice adoption</a>. To efficiently support millions of monthly users, Spotify restructured its application into microservices, resulting in impressive performance and scalability. These microservices likely handle various specialized tasks, such as:</p>
<ul>
<li>Recommending tracks based on a user’s listening history.</li>
<li>Identifying the genre and theme of each track.</li>
<li>Personalizing playlists for users by combining insights from the recommendation and genre microservices.</li>
<li>Delivering lyrics for tracks.</li>
</ul>
<p><a href="https://tailcall.run/blog/graphql-microservices-migration/" target="_blank" rel="noopener noreferrer">Read: Migrating To Microservices</a>.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="what-is-graphql">What is GraphQL?<a href="https://tailcall.run/blog/graphql-match-microservices/#what-is-graphql" class="hash-link" aria-label="Direct link to What is GraphQL?" title="Direct link to What is GraphQL?">​</a></h2>
<p><strong><a href="https://tailcall.run/graphql/" target="_blank" rel="noopener noreferrer">GraphQL</a></strong> was designed based on the concept of <em>returning precisely what is asked for; no more, no less</em>. Open-sourced by Facebook in 2015, it fixes ancient issues of over-fetching and under-fetching that plagued REST APIs right from their very invention.</p>
<p>It empowers the client with <strong>flexibility</strong> regarding which particular fields to request in any use case. This is possible due to the <strong>strongly typed schema</strong> that clearly defines the data structure of the API and specifies what it returns. Plus, subscriptions allow GraphQL to return <strong>real-time data</strong>, meeting demands of modern applications.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="example-github">Example: GitHub<a href="https://tailcall.run/blog/graphql-match-microservices/#example-github" class="hash-link" aria-label="Direct link to Example: GitHub" title="Direct link to Example: GitHub">​</a></h3>
<p><strong>GitHub</strong> is one of the <a href="https://docs.github.com/en/graphql/overview/about-the-graphql-api" target="_blank" rel="noopener noreferrer">prominent adopters of GraphQL</a>. By implementing GraphQL, GitHub provides its users with a more flexible and efficient way to interact with its API. Developers can query for specific data, such as repositories, issues, and commits, all within a single request, enhancing the efficiency of their applications.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="combining-graphql-and-microservices">Combining GraphQL and Microservices<a href="https://tailcall.run/blog/graphql-match-microservices/#combining-graphql-and-microservices" class="hash-link" aria-label="Direct link to Combining GraphQL and Microservices" title="Direct link to Combining GraphQL and Microservices">​</a></h2>
<p>The true magic happens when <strong>GraphQL</strong> and <strong>microservices</strong> are combined. This pairing allows developers to harness the power of microservices while mitigating some of the complexities associated with them.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="benefits-of-combining-graphql-and-microservices">Benefits of Combining GraphQL and Microservices<a href="https://tailcall.run/blog/graphql-match-microservices/#benefits-of-combining-graphql-and-microservices" class="hash-link" aria-label="Direct link to Benefits of Combining GraphQL and Microservices" title="Direct link to Benefits of Combining GraphQL and Microservices">​</a></h3>
<p>By design, GraphQL has made optimization of <strong>data retrieval</strong> and parallel resolutions intrinsic to the system. <strong>Error management</strong> is also much smoother because of the automatic process of partial resolutions and formation of response as a whole. Further, due to <strong>flexibility</strong> and clear ownership, GraphQL makes it possible for clients to fetch data from different microservices. This grants extra control to the clients while communicating with microservices.</p>
<p><em>fetching data from multiple microservices using Tailcall:</em></p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">tracks</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">TrackData</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token directive function" style="color:#FDEA2F">@grpc</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token attr-name" style="color:#8DFFF8">url</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token description string" style="color:#FDB869">"</span><span class="token description string language-markdown" style="color:#FDB869">https://example.com</span><span class="token description string" style="color:#FDB869">"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token attr-name" style="color:#8DFFF8">method</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"tracks.trackService.listTracks"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Track</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">title</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">audioUrl</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">reactions</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">Reaction</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token directive function" style="color:#FDEA2F">@http</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token attr-name" style="color:#8DFFF8">url</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"https://example.com/tracks/{{.value.id}}/reactions"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">lyrics</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">Lyric</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token directive function" style="color:#FDEA2F">@grpc</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token attr-name" style="color:#8DFFF8">url</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token description string" style="color:#FDB869">"</span><span class="token description string language-markdown" style="color:#FDB869">https://example.com</span><span class="token description string" style="color:#FDB869">"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token attr-name" style="color:#8DFFF8">body</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token description string" style="color:#FDB869">"</span><span class="token description string language-markdown" style="color:#FDB869">{{.value.id}}</span><span class="token description string" style="color:#FDB869">"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token attr-name" style="color:#8DFFF8">method</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"tracks.trackService.getLyrics"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">TrackData</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">track</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">Track</span><span class="token punctuation" style="color:#fff">]</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Reaction</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">emoji</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">count</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Lyric</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">text</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">timestampSecond</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="challenges-of-combining-graphql-and-microservices">Challenges of Combining GraphQL and Microservices<a href="https://tailcall.run/blog/graphql-match-microservices/#challenges-of-combining-graphql-and-microservices" class="hash-link" aria-label="Direct link to Challenges of Combining GraphQL and Microservices" title="Direct link to Challenges of Combining GraphQL and Microservices">​</a></h3>
<p>Sometimes, it's a pathway to <strong>overengineering</strong> for an application. You could end up writing long, sprawling schemas and queries for things you could have implemented in a few lines of code in REST. It can bring in unnecessary <strong>complexity</strong> and make it harder for another developer to implement something else in the app.</p>
<p><img decoding="async" loading="lazy" alt="n + 1 problem" src="https://tailcall.run/assets/images/n+1-issue-81f278d76d32c29bfeafbe72ea913ef9.png" width="3000" height="1509" class="img_ev3q"></p>
<p>Another well-known challenge is the <strong>N+1 problem</strong>: this happens when a GraphQL query requesting nested data provokes plural sequential calls to a microservice, often due to a poorly designed schema. Fortunately, Tailcall has a solution to this problem built into the box, thus making your development easier and more efficient. <a href="https://tailcall.run/docs/graphql-n-plus-one-problem-solved-tailcall/#n1-in-graphql-using-tailcall" target="_blank" rel="noopener noreferrer">Read How</a>.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="example-netflix">Example: Netflix<a href="https://tailcall.run/blog/graphql-match-microservices/#example-netflix" class="hash-link" aria-label="Direct link to Example: Netflix" title="Direct link to Example: Netflix">​</a></h3>
<p><strong>Netflix</strong> is a prime example of a company that <a href="https://netflixtechblog.com/rebuilding-netflix-video-processing-pipeline-with-microservices-4e5e6310e359" target="_blank" rel="noopener noreferrer">successfully implemented microservices</a>, transforming its monolithic application into a more scalable, fault-tolerant, and efficient system. By adopting this architecture, Netflix enables each service, such as user profiles, content delivery, and recommendations, to operate independently while seamlessly integrating to provide a cohesive user experience. This approach allows Netflix to scale services based on demand, with resource-intensive microservices like content recommendations being scaled more aggressively than less demanding ones, such as age-group rating calculations.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="designing-scalable-apis-with-graphql-and-microservices">Designing Scalable APIs with GraphQL and Microservices<a href="https://tailcall.run/blog/graphql-match-microservices/#designing-scalable-apis-with-graphql-and-microservices" class="hash-link" aria-label="Direct link to Designing Scalable APIs with GraphQL and Microservices" title="Direct link to Designing Scalable APIs with GraphQL and Microservices">​</a></h2>
<p>Designing scalable APIs that leverage both <strong>GraphQL</strong> and <strong>microservices</strong> requires careful planning and adherence to certain principles.</p>
<ol>
<li>
<p><strong>Schema Design:</strong> Begin with a robust, well-defined schema that accurately represents your data and services. A modular schema is crucial, as it allows your application to grow and evolve without causing disruptions. Ensure that the schema is flexible enough to accommodate new features and changes as your application scales.</p>
</li>
<li>
<p><strong>Service Orchestration:</strong> To manage the complexity of multiple microservices, implement a service orchestration layer that coordinates communication between the GraphQL server and underlying services. This layer should handle essential tasks such as load balancing, caching, and fallback mechanisms to ensure seamless interactions and maintain API performance under varying loads.</p>
</li>
<li>
<p><strong>Caching:</strong> Utilize effective caching strategies at both the GraphQL and microservice levels to enhance performance. Caching reduces the need for repeated data retrieval, lowering latency and improving the user experience. Consider using in-memory caches for frequently accessed data and implement cache invalidation strategies to ensure data consistency.</p>
</li>
<li>
<p><strong>Monitoring and Logging:</strong> Comprehensive monitoring and logging are vital for tracking API performance, identifying potential bottlenecks, and quickly resolving issues. Implementing detailed logging with tools like OpenTelemetry provides valuable insights into the behavior of your API, helping you maintain high availability and optimize performance over time.</p>
</li>
<li>
<p><strong>Security:</strong> With <strong>Tailcall's</strong> <a href="https://tailcall.run/docs/field-level-access-control-graphql-authentication/" target="_blank" rel="noopener noreferrer">built-in auth</a> and <a href="https://tailcall.run/docs/protected-directive" target="_blank" rel="noopener noreferrer">@protected</a> directive, you can add auth functionality and make fields protected with just a few lines of code - which is intelligent enough to protect any query that indirectly resolves to that field:</p>
</li>
</ol>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Reaction</span><span class="token plain"> </span><span class="token directive function" style="color:#FDEA2F">@protected</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">emoji</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">count</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<ol start="6">
<li><strong>Strong Typing:</strong> Nothing can be more painful than having to work with a poorly-typed GraphQL schema where you had <code>email</code> and <code>url</code> as <code>string</code>, but with handmade validation code. These omissions are a big mistake which could usher in potential errors and inconsistencies in handling your data. Instead, make full use of GraphQL's in-built scalars and custom types. It leverages these built-in scalars to ensure that fields are valid according to the expected data types, reducing the need for error-prone manual validation:</li>
</ol>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">findMyAccount</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">phone</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">PhoneNumber</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Account</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token directive function" style="color:#FDEA2F">@http</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token attr-name" style="color:#8DFFF8">url</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"https://example.com/accounts?phone={{.args.phone}}"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Account</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">email</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p><a href="https://tailcall.run/blog/graphql-schema/" target="_blank" rel="noopener noreferrer">Read: Designing The Perfect GraphQL Schema</a></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="example-airbnb">Example: Airbnb<a href="https://tailcall.run/blog/graphql-match-microservices/#example-airbnb" class="hash-link" aria-label="Direct link to Example: Airbnb" title="Direct link to Example: Airbnb">​</a></h3>
<p>Airbnb successfully implemented scalable APIs <a href="https://www.infoq.com/news/2019/12/airbnb-graphql-migration/" target="_blank" rel="noopener noreferrer">by combining GraphQL and microservices</a>. Airbnb’s GraphQL layer acts as an abstraction over numerous microservices, allowing clients to retrieve data efficiently and consistently. By following the principles of schema design, service orchestration, and caching, Airbnb has built a robust platform that can scale with demand.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="where-tailcall-comes-in">Where Tailcall Comes In<a href="https://tailcall.run/blog/graphql-match-microservices/#where-tailcall-comes-in" class="hash-link" aria-label="Direct link to Where Tailcall Comes In" title="Direct link to Where Tailcall Comes In">​</a></h3>
<p>When implementing a combination of GraphQL and microservices, the integration process can become complex, particularly when dealing with schema management, service orchestration, and security concerns. <a href="https://tailcall.run/graphql/" target="_blank" rel="noopener noreferrer">Tools like Tailcall</a> can significantly simplify this process by providing a seamless integration layer that handles the intricacies of connecting GraphQL with various microservices. Tailcall enables developers to focus on building business logic rather than managing the underlying infrastructure, accelerating development and reducing potential errors.</p>
<section class="flex flex-col justify-center px-4 py-4 max-w-3xl mx-auto"><div class="relative flex flex-col max-md:space-y-6 md:flex-row md:items-center p-8 bg-neutral-900 rounded-2xl overflow-hidden max-md:p-6"><svg xmlns="http://www.w3.org/2000/svg" width="740" height="190" fill="none" viewBox="0 0 740 190" class="absolute inset-0 w-full h-full object-cover opacity-5 z-0 max-w-none max-h-none"><g fill="#CECECF"><path d="M51.336 186.568q-12.906 0-21.071-7.902-7.902-8.165-7.902-21.598V83.32h-32.66V55.927h32.66V15.365H55.55v40.562h35.821V83.32h-35.82v67.954q0 7.9 7.374 7.901h25.286v27.393zM151.438 190.255q-13.96 0-25.022-4.741-11.062-5.004-17.647-14.223-6.321-9.481-6.321-22.915 0-13.432 6.321-22.388 6.585-9.218 17.911-13.696 11.589-4.74 26.339-4.741h35.82v-7.375q0-9.218-5.794-15.013-5.795-6.058-18.437-6.058-12.38 0-18.438 5.795-6.057 5.53-7.901 14.486l-30.553-10.272q3.16-10.008 10.008-18.174 7.112-8.428 18.701-13.433 11.852-5.267 28.709-5.267 25.812 0 40.826 12.906 15.013 12.905 15.013 37.401v48.727q0 7.9 7.375 7.901h10.535v27.393h-22.124q-9.746 0-16.067-4.741t-6.321-12.643v-.263h-5.005q-1.053 3.16-4.741 8.428-3.687 5.004-11.589 8.955t-21.598 3.951m5.795-26.865q13.96 0 22.651-7.639 8.955-7.9 8.955-20.807v-2.634h-33.45q-9.219 0-14.486 3.951t-5.268 11.062 5.531 11.589q5.53 4.478 16.067 4.478M252.612 186.568V55.928h33.187v130.64zm16.594-145.917q-8.955 0-15.277-5.795-6.057-5.794-6.058-15.277 0-9.48 6.058-15.276 6.322-5.795 15.277-5.795 9.219 0 15.276 5.795 6.058 5.794 6.058 15.277 0 9.48-6.058 15.276t-15.276 5.795M312.039 186.568V2.196h33.187v184.372zM432.836 190.255q-18.964 0-34.504-7.901-15.276-7.902-24.232-22.915t-8.955-36.348v-3.687q0-21.335 8.955-36.348t24.232-22.915q15.54-7.9 34.504-7.901 18.7 0 32.134 6.584 13.433 6.585 21.597 18.174 8.429 11.326 11.063 25.812l-32.134 6.848q-1.053-7.9-4.741-14.223-3.687-6.321-10.535-10.008-6.585-3.688-16.594-3.688-10.008 0-18.174 4.478-7.901 4.214-12.642 12.906-4.478 8.429-4.478 20.807v2.634q0 12.38 4.478 21.071 4.74 8.428 12.642 12.906 8.166 4.215 18.174 4.215 15.013 0 22.652-7.639 7.901-7.9 10.008-20.544l32.134 7.638q-3.425 13.96-11.853 25.549-8.164 11.327-21.597 17.91-13.434 6.585-32.134 6.585M555.822 190.255q-13.96 0-25.022-4.741-11.062-5.004-17.647-14.223-6.321-9.481-6.321-22.915 0-13.432 6.321-22.388 6.585-9.218 17.911-13.696 11.589-4.74 26.338-4.741h35.821v-7.375q0-9.218-5.794-15.013-5.795-6.058-18.437-6.058-12.38 0-18.438 5.795-6.057 5.53-7.901 14.486L512.1 89.114q3.16-10.008 10.008-18.174 7.112-8.428 18.701-13.433 11.853-5.267 28.709-5.267 25.812 0 40.826 12.906 15.013 12.905 15.013 37.401v48.727q0 7.9 7.375 7.901h10.535v27.393h-22.124q-9.746 0-16.067-4.741-6.322-4.741-6.322-12.643v-.263h-5.004q-1.053 3.16-4.741 8.428-3.687 5.004-11.589 8.955t-21.598 3.951m5.795-26.865q13.96 0 22.651-7.639 8.955-7.9 8.955-20.807v-2.634h-33.45q-9.22 0-14.486 3.951-5.268 3.95-5.268 11.062t5.531 11.589q5.53 4.478 16.067 4.478M656.996 186.568V2.196h33.187v184.372zM716.423 186.568V2.196h33.187v184.372z"></path></g></svg><div class="relative z-10 flex flex-col flex-1 space-y-2.5 text-center max-md:text-left md:text-left"><h2 class="text-3xl font-bold leading-tight text-white sm:text-4xl">Ready to build your next app with GraphQL?</h2><p class="text-base leading-relaxed text-zinc-400 sm:text-lg">Don’t get left behind - Try Tailcall today</p></div><div class="relative z-10 mt-6 max-md:w-full max-md:flex max-md:justify-center md:mt-0 md:ml-6 md:flex-shrink-0"><a class="group relative disabled:opacity-25 disabled:cursor-not-allowed flex items-center justify-center gap-x-SPACE_03 hover:no-underline rounded-lg sm:rounded-xl h-12 sm:h-16 text-content-small font-bold sm:text-title-small cursor-pointer px-SPACE_06 py-SPACE_03 sm:px-SPACE_08 lg:px-SPACE_10 sm:py-SPACE_04 lg:py-SPACE_05 w-fit bg-yellow-300 border border-solid text-tailCall-dark-500 bg-transparent hover:text-tailCall-dark-500" href="https://tailcall.run/docs/"><span class="z-20"> <!-- -->Get Started</span></a></div></div></section>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="security-and-authentication-with-graphql-and-microservices">Security and Authentication with GraphQL and Microservices<a href="https://tailcall.run/blog/graphql-match-microservices/#security-and-authentication-with-graphql-and-microservices" class="hash-link" aria-label="Direct link to Security and Authentication with GraphQL and Microservices" title="Direct link to Security and Authentication with GraphQL and Microservices">​</a></h2>
<p>Security is a major concern when integrating <strong>GraphQL</strong> with <strong>microservices</strong>. Without proper safeguards, the powerful flexibility of GraphQL can lead to significant risks.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="major-concerns-about-security">Major Concerns about Security:<a href="https://tailcall.run/blog/graphql-match-microservices/#major-concerns-about-security" class="hash-link" aria-label="Direct link to Major Concerns about Security:" title="Direct link to Major Concerns about Security:">​</a></h3>
<ol>
<li><strong>Query Complexity</strong>: The superpower of GraphQL is letting clients create incredibly intricate and deeply nested queries. Sometimes, however, this becomes a nemesis. Imagine this: a bad user sending a query that is as deep as a rabbit hole, asking for endless amounts of data and gasping your server's breath. To keep things at hand and prevent your server from melting down, some ground rules should be created. Design query complexity analysis and set <strong>depth limits</strong> to make sure that queries are of manageable size; otherwise, they can overload your server. Have A Look:</li>
</ol>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token object">songs</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token comment" style="color:#30C26D;font-style:italic"># Fetch all songs</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token object">author</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token comment" style="color:#30C26D;font-style:italic"># For each song, fetch the author's details</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token object">songs</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token comment" style="color:#30C26D;font-style:italic"># For each author, fetch their songs</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token object">author</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token comment" style="color:#30C26D;font-style:italic"># For each song by the author, fetch the author's details again</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token property" style="color:#C586C0">comments</span><span class="token plain"> </span><span class="token comment" style="color:#30C26D;font-style:italic"># Retrieve the comments for each author</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token comment" style="color:#30C26D;font-style:italic"># and this can go forever - until your server overloads</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<ol start="2">
<li>
<p><strong>Authentication and Authorization</strong>: If you need to protect your microservices, some strong security configuration is requisite. Every microservice should be armed with a guard at the level of authentication and authorization. But don't stop here. Scale up these security measures to the GraphQL layer. Next, it will help you set up solid authentication strategies and fine-grained access controls right in your GraphQL schema. Think of this as having a bouncer at your door to make sure only the proper users get access to the proper data.</p>
</li>
<li>
<p><strong>Exposure of Data</strong>: GraphQL's introspection and flexible queries can sometimes be a two-edged sword. Unless properly controlled, sensitive information may slip out and unintentionally be exposed. Implement strict field-level access control that guides how data can be queried and by whom to keep your data safe and sound. <a href="https://tailcall.run/blog/graphql-introspection-security/#the-security-implications-of-introspection" target="_blank" rel="noopener noreferrer">Read: How is Introspection a Hidden Treasure for Attackers</a></p>
</li>
</ol>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="example-facebook">Example: Facebook<a href="https://tailcall.run/blog/graphql-match-microservices/#example-facebook" class="hash-link" aria-label="Direct link to Example: Facebook" title="Direct link to Example: Facebook">​</a></h3>
<p><strong>Facebook</strong>, the creator of GraphQL, <a href="https://engineering.fb.com/2020/05/08/web/facebook-redesign/" target="_blank" rel="noopener noreferrer">has implemented robust security measures to protect its API</a>. Query complexity analysis, rate limiting, and other strict authentication protocols are all part of Facebook's efforts to secure the platform. Read: Securing your GraphQL API</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="final-thoughts">Final Thoughts<a href="https://tailcall.run/blog/graphql-match-microservices/#final-thoughts" class="hash-link" aria-label="Direct link to Final Thoughts" title="Direct link to Final Thoughts">​</a></h2>
<p>In conclusion, while exploring these technologies can be exciting and straightforward for some, it can also lead to significant challenges or even career setbacks if approached without proper preparation. Always conduct thorough research and planning before diving into GraphQL. To make the process easier and more secure, consider <a href="https://tailcall.run/docs/" target="_blank" rel="noopener noreferrer">using tools like Tailcall</a> to streamline integration and fully unlock your API's potential. See you next time! 😄</p>]]></content:encoded>
            <category>GraphQL</category>
            <category>Microservices</category>
            <category>API</category>
        </item>
        <item>
            <title><![CDATA[Simplify your monolith to microservices migration using GraphQL]]></title>
            <link>https://tailcall.run/blog/graphql-microservices-migration/</link>
            <guid>https://tailcall.run/blog/graphql-microservices-migration/</guid>
            <pubDate>Thu, 15 Aug 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Streamline your migration from monolithic architecture to microservices with expert tips, practical examples, and step-by-step guidance using GraphQL.]]></description>
            <content:encoded><![CDATA[<p>In the rapidly evolving world of software development, scalability and maintainability are crucial for a company's success. The monolithic architecture, which once served organizations well, is increasingly becoming a bottleneck as applications grow in complexity and scale. Many organizations are shifting towards microservices to address these challenges, but migration is often fraught with complexity, particularly in areas like data management, service communication, and deployment.</p>
<p>GraphQL, a query language for your API, offers a flexible and efficient way to interact with data, making it an ideal tool for easing the transition. This article will explore the intricacies of migrating from a monolithic architecture to microservices, the challenges involved, and how GraphQL can simplify the migration process.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="understanding-monoliths-and-microservices">Understanding Monoliths and Microservices<a href="https://tailcall.run/blog/graphql-microservices-migration/#understanding-monoliths-and-microservices" class="hash-link" aria-label="Direct link to Understanding Monoliths and Microservices" title="Direct link to Understanding Monoliths and Microservices">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="what-is-a-monolithic-architecture">What is a Monolithic Architecture?<a href="https://tailcall.run/blog/graphql-microservices-migration/#what-is-a-monolithic-architecture" class="hash-link" aria-label="Direct link to What is a Monolithic Architecture?" title="Direct link to What is a Monolithic Architecture?">​</a></h3>
<p>A monolithic architecture is a traditional software development model where all components of an application are tightly coupled together and run as a single service. This architecture is characterized by:</p>
<ol>
<li><strong>Single Codebase:</strong> The entire application’s functionality is contained within one codebase.</li>
<li><strong>Tightly Coupled Components:</strong> All modules are interdependent, meaning a change in one module can affect the entire system.</li>
<li><strong>Single Deployment Unit:</strong> The entire application is deployed as a single unit, making scaling a challenge.</li>
</ol>
<p>Monolithic architectures are straightforward to develop initially but become increasingly difficult to manage as the application grows. Changes to one part of the system require rebuilding and redeploying the entire application, leading to slower development cycles and potential downtime.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="what-are-microservices">What are Microservices?<a href="https://tailcall.run/blog/graphql-microservices-migration/#what-are-microservices" class="hash-link" aria-label="Direct link to What are Microservices?" title="Direct link to What are Microservices?">​</a></h3>
<p>Microservices are a design pattern where an application is divided into smaller, independent services that communicate with each other through APIs. Key characteristics of microservices include:</p>
<ol>
<li><strong>Independently Deployable Services:</strong> Each service can be developed, deployed, and scaled independently.</li>
<li><strong>Decoupled Components:</strong> Services are loosely coupled, meaning changes in one service typically do not impact others.</li>
<li><strong>Domain-Driven Design:</strong> Each microservice is aligned with a specific business function or domain.</li>
</ol>
<p>Microservice architecture addresses many of the scalability and maintainability challenges of monolithic systems. However, it can introduce complexity in initial development.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="why-migrate-from-monolith-to-microservices">Why Migrate from Monolith to Microservices?<a href="https://tailcall.run/blog/graphql-microservices-migration/#why-migrate-from-monolith-to-microservices" class="hash-link" aria-label="Direct link to Why Migrate from Monolith to Microservices?" title="Direct link to Why Migrate from Monolith to Microservices?">​</a></h3>
<p>Migrating from a monolithic architecture to microservices offers several advantages:</p>
<ol>
<li><strong>Scalability:</strong> Microservices allow you to scale individual components independently based on demand.</li>
<li><strong>Agility:</strong> Independent services enable faster development cycles and easier maintenance.</li>
<li><strong>Resilience:</strong> Failures in one service do not necessarily bring down the entire application.</li>
</ol>
<p>Despite these advantages, the migration process is complex and requires careful planning and execution.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="challenges-in-monolith-to-microservices-migration">Challenges in Monolith to Microservices Migration<a href="https://tailcall.run/blog/graphql-microservices-migration/#challenges-in-monolith-to-microservices-migration" class="hash-link" aria-label="Direct link to Challenges in Monolith to Microservices Migration" title="Direct link to Challenges in Monolith to Microservices Migration">​</a></h2>
<p>Migrating to microservices presents several challenges that organizations must address to ensure a successful transition.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="data-management-and-consistency">Data Management and Consistency<a href="https://tailcall.run/blog/graphql-microservices-migration/#data-management-and-consistency" class="hash-link" aria-label="Direct link to Data Management and Consistency" title="Direct link to Data Management and Consistency">​</a></h3>
<p>In a monolithic system, data is typically stored in a single database, making it easier to maintain consistency. In a microservice architecture, each service often has its database, leading to challenges in maintaining data consistency across services. Data integrity and managing distributed transactions are significant hurdles in the migration process.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="service-communication">Service Communication<a href="https://tailcall.run/blog/graphql-microservices-migration/#service-communication" class="hash-link" aria-label="Direct link to Service Communication" title="Direct link to Service Communication">​</a></h3>
<p>Monolithic applications typically rely on in-process communication, which is efficient and straightforward. In a microservice architecture, services must communicate over a network, introducing latency and potential failures. Managing inter-service communication, especially in distributed environments, requires robust strategies such as service discovery, load balancing, and circuit breakers.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="deployment-complexity">Deployment Complexity<a href="https://tailcall.run/blog/graphql-microservices-migration/#deployment-complexity" class="hash-link" aria-label="Direct link to Deployment Complexity" title="Direct link to Deployment Complexity">​</a></h3>
<p>Deploying a monolithic application is relatively simple, as there is only one deployment unit. However, in a microservice architecture, each service must be deployed independently, often with different versions running simultaneously. Managing these deployments, along with continuous integration and continuous deployment (CI/CD) pipelines, adds significant complexity.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="introduction-to-graphql">Introduction to GraphQL<a href="https://tailcall.run/blog/graphql-microservices-migration/#introduction-to-graphql" class="hash-link" aria-label="Direct link to Introduction to GraphQL" title="Direct link to Introduction to GraphQL">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="what-is-graphql">What is GraphQL?<a href="https://tailcall.run/blog/graphql-microservices-migration/#what-is-graphql" class="hash-link" aria-label="Direct link to What is GraphQL?" title="Direct link to What is GraphQL?">​</a></h3>
<p>GraphQL is a query language and runtime for APIs that was developed by Facebook in 2012 and open-sourced in 2015. Unlike REST, which exposes multiple endpoints for different types of data, GraphQL allows clients to request exactly the data they need through a single endpoint. This flexibility makes GraphQL an excellent choice for applications with complex data needs.
<a href="https://tailcall.run/graphql/what-is-graphql/">Read More...</a></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="key-features-of-graphql">Key Features of GraphQL<a href="https://tailcall.run/blog/graphql-microservices-migration/#key-features-of-graphql" class="hash-link" aria-label="Direct link to Key Features of GraphQL" title="Direct link to Key Features of GraphQL">​</a></h3>
<ul>
<li><strong>Declarative Data Fetching:</strong> Clients specify the shape and structure of the data they need, which only fetches the required data.</li>
<li><strong>Single Endpoint:</strong> All data queries are sent to a single endpoint, simplifying API design and usage.</li>
<li><strong>Strong Typing:</strong> GraphQL schemas are strongly typed, providing clear documentation and reducing errors.</li>
<li><strong>API Contract</strong> GraphQL schema acts as a contract between the client and server, ensuring a clear understanding of data requirements.</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="graphql-vs-rest">GraphQL vs REST<a href="https://tailcall.run/blog/graphql-microservices-migration/#graphql-vs-rest" class="hash-link" aria-label="Direct link to GraphQL vs REST" title="Direct link to GraphQL vs REST">​</a></h3>
<p>While REST is based on a fixed set of endpoints that return specific data, GraphQL offers a Contract-First approach, which is crucial for decoupling the client and server. Which is very important so that your splitting of the monolith into microservices can be done without affecting the client.</p>
<p>To learn more about the differences between GraphQL and REST, read our article on <a href="https://tailcall.run/graphql/graphql-vs-rest-api-comparison/">GraphQL vs REST</a>.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="how-graphql-simplifies-microservices-migration">How GraphQL Simplifies Microservices Migration<a href="https://tailcall.run/blog/graphql-microservices-migration/#how-graphql-simplifies-microservices-migration" class="hash-link" aria-label="Direct link to How GraphQL Simplifies Microservices Migration" title="Direct link to How GraphQL Simplifies Microservices Migration">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="unified-data-access-layer">Unified Data Access Layer<a href="https://tailcall.run/blog/graphql-microservices-migration/#unified-data-access-layer" class="hash-link" aria-label="Direct link to Unified Data Access Layer" title="Direct link to Unified Data Access Layer">​</a></h3>
<p>GraphQL provides a unified data access layer that abstracts the underlying microservices. This means that clients interact with a single GraphQL API, which then fetches and aggregates data from various microservices. This abstraction layer hides the complexity of the underlying architecture from clients, making the transition from a monolithic system smoother and less disruptive.</p>
<p>Let's take a look at this example using Tailcall:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">schema</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">query</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Query</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">users</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token directive function" style="color:#FDEA2F">@http</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token attr-name" style="color:#8DFFF8">url</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"https://users.example.com/users/{{.args.id}}"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">orders</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">Order</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token directive function" style="color:#FDEA2F">@http</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token attr-name" style="color:#8DFFF8">url</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"https://orders.example.com/users/{{.value.id}/orders"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Order</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">userId</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">total</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>In this specification, the services that handle user accounts and store orders may be separate, while offering data for both under a unified API. This allows for a gradual migration of services without disrupting the client interface. Clients can continue to interact with the GraphQL API, even as the underlying services evolve.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="efficient-data-fetching">Efficient Data Fetching<a href="https://tailcall.run/blog/graphql-microservices-migration/#efficient-data-fetching" class="hash-link" aria-label="Direct link to Efficient Data Fetching" title="Direct link to Efficient Data Fetching">​</a></h3>
<p>In microservice architectures, data is often spread across multiple services. GraphQL’s ability to request only the data needed in a single query reduces the need for multiple round trips to different services, improving performance and reducing latency.</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token object">users</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token object">orders</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">total</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This query fetches only the <code>total</code> of each user's order, optimizing the data transfer and reducing the load on the network.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="schema-stitching-and-federation">Schema Stitching and Federation<a href="https://tailcall.run/blog/graphql-microservices-migration/#schema-stitching-and-federation" class="hash-link" aria-label="Direct link to Schema Stitching and Federation" title="Direct link to Schema Stitching and Federation">​</a></h3>
<p>GraphQL supports schema stitching and federation, which allow you to combine multiple GraphQL schemas into a single schema. This is particularly useful in microservice architectures, where each service might expose its own GraphQL schema. By stitching these schemas together, you can present a unified API to clients, further simplifying the migration process.</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">extend</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Order</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">sellerId</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">seller</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Seller</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token directive function" style="color:#FDEA2F">@http</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token attr-name" style="color:#8DFFF8">url</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"https://orders.example.com/sellers/{{.value.sellerId}}"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Seller</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>In this example, the <code>Order</code> type is extended with a <code>seller</code> field, which could be fetched from a separate microservice for seller accounts, all integrated into a single schema.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="gradual-migration-support">Gradual Migration Support<a href="https://tailcall.run/blog/graphql-microservices-migration/#gradual-migration-support" class="hash-link" aria-label="Direct link to Gradual Migration Support" title="Direct link to Gradual Migration Support">​</a></h3>
<p>One of the most significant advantages of using GraphQL in your migration strategy is its support for gradual migration. You can introduce <strong><em>a GraphQL layer on top of your existing monolithic system and then incrementally refactor parts of the monolith into microservices</em></strong>. The GraphQL layer can continue to serve clients, even as the underlying architecture evolves, minimizing disruption to users.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-by-step-guide-to-using-graphql-in-your-migration">Step-by-Step Guide to Using GraphQL in Your Migration<a href="https://tailcall.run/blog/graphql-microservices-migration/#step-by-step-guide-to-using-graphql-in-your-migration" class="hash-link" aria-label="Direct link to Step-by-Step Guide to Using GraphQL in Your Migration" title="Direct link to Step-by-Step Guide to Using GraphQL in Your Migration">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="analyze-your-monolith">Analyze Your Monolith<a href="https://tailcall.run/blog/graphql-microservices-migration/#analyze-your-monolith" class="hash-link" aria-label="Direct link to Analyze Your Monolith" title="Direct link to Analyze Your Monolith">​</a></h3>
<p>Begin by analyzing your monolithic application to identify the domains and boundaries within the codebase. This will help you determine how to decompose the monolith into microservices. Look for areas of the code that are highly coupled and those that are relatively isolated.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="implement-graphql-layer">Implement GraphQL Layer<a href="https://tailcall.run/blog/graphql-microservices-migration/#implement-graphql-layer" class="hash-link" aria-label="Direct link to Implement GraphQL Layer" title="Direct link to Implement GraphQL Layer">​</a></h3>
<p>Implement a GraphQL API that sits on top of your monolithic application. This API will serve as the single point of entry for clients, allowing you to start refactoring the monolith without disrupting the client interface.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="design-your-microservice-architecture">Design Your Microservice Architecture<a href="https://tailcall.run/blog/graphql-microservices-migration/#design-your-microservice-architecture" class="hash-link" aria-label="Direct link to Design Your Microservice Architecture" title="Direct link to Design Your Microservice Architecture">​</a></h3>
<p>Next, design your microservice architecture based on the analysis. Define the services, their boundaries, and how they will communicate with each other. Ensure that each service is aligned with a specific business function or domain to maintain cohesion.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="migrate-services-incrementally">Migrate Services Incrementally<a href="https://tailcall.run/blog/graphql-microservices-migration/#migrate-services-incrementally" class="hash-link" aria-label="Direct link to Migrate Services Incrementally" title="Direct link to Migrate Services Incrementally">​</a></h3>
<p>Start migrating functionalities from the monolith to microservices incrementally. As you extract services, update the GraphQL layer to fetch data from the newly created microservices instead of the monolith. This approach allows for a smooth transition with minimal impact on the end users.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="test-and-optimize">Test and Optimize<a href="https://tailcall.run/blog/graphql-microservices-migration/#test-and-optimize" class="hash-link" aria-label="Direct link to Test and Optimize" title="Direct link to Test and Optimize">​</a></h3>
<p>Throughout the migration process, continuously test the GraphQL API to ensure it functions correctly with both the monolithic and microservices-based backends. Optimize the GraphQL queries to ensure they are efficient and do not introduce unnecessary latency.</p>
<p><img decoding="async" loading="lazy" alt="Steps to Gradually migrate Monolith to Microservices leveraging GraphQL" src="https://tailcall.run/assets/images/monolith-to-microservices-fb96366f894684422eb2d07d4881d009.png" width="1537" height="1139" class="img_ev3q"></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="best-practices-for-graphql-in-microservices-migration">Best Practices for GraphQL in Microservices Migration<a href="https://tailcall.run/blog/graphql-microservices-migration/#best-practices-for-graphql-in-microservices-migration" class="hash-link" aria-label="Direct link to Best Practices for GraphQL in Microservices Migration" title="Direct link to Best Practices for GraphQL in Microservices Migration">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="use-strong-type-system">Use Strong Type System<a href="https://tailcall.run/blog/graphql-microservices-migration/#use-strong-type-system" class="hash-link" aria-label="Direct link to Use Strong Type System" title="Direct link to Use Strong Type System">​</a></h3>
<p>Leverage GraphQL’s strong typing to ensure your API is well-defined and less prone to errors. Define your types and schema carefully to ensure they align with your domain model and business logic.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="implement-proper-error-handling">Implement Proper Error Handling<a href="https://tailcall.run/blog/graphql-microservices-migration/#implement-proper-error-handling" class="hash-link" aria-label="Direct link to Implement Proper Error Handling" title="Direct link to Implement Proper Error Handling">​</a></h3>
<p>Ensure that your GraphQL API has robust error handling in place. Provide meaningful error messages to clients and ensure that failures in one microservice do not cascade and affect the entire API.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="optimize-performance-with-caching">Optimize Performance with Caching<a href="https://tailcall.run/blog/graphql-microservices-migration/#optimize-performance-with-caching" class="hash-link" aria-label="Direct link to Optimize Performance with Caching" title="Direct link to Optimize Performance with Caching">​</a></h3>
<p>Implement caching strategies within your GraphQL layer to improve performance. This can be done at various levels, including query result caching, response caching, and even partial query caching.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="ensure-security-measures">Ensure Security Measures<a href="https://tailcall.run/blog/graphql-microservices-migration/#ensure-security-measures" class="hash-link" aria-label="Direct link to Ensure Security Measures" title="Direct link to Ensure Security Measures">​</a></h3>
<p>Security is critical when migrating to microservices, especially when introducing a new API layer like GraphQL. Implement proper authentication and authorization mechanisms. Additionally, consider rate limiting, input validation, and other security best practices to protect your GraphQL API.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="successful-migration-stories-using-graphql">Successful Migration Stories Using GraphQL<a href="https://tailcall.run/blog/graphql-microservices-migration/#successful-migration-stories-using-graphql" class="hash-link" aria-label="Direct link to Successful Migration Stories Using GraphQL" title="Direct link to Successful Migration Stories Using GraphQL">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="netflix">Netflix<a href="https://tailcall.run/blog/graphql-microservices-migration/#netflix" class="hash-link" aria-label="Direct link to Netflix" title="Direct link to Netflix">​</a></h3>
<p>In 2021, Netflix published a <a href="https://netflixtechblog.com/beyond-rest-1b76f7c20ef6" target="_blank" rel="noopener noreferrer">blog post</a> detailing the company’s adoption of GraphQL. Netflix encountered performance challenges as it expanded globally, requiring a more efficient way to manage data interactions between microservices. By integrating GraphQL as a central data layer, Netflix reduced the number of network requests and minimized data transfer, significantly lowering latency. This improvement allowed Netflix to deliver content more efficiently, maintaining high customer satisfaction across a growing user base.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="github">GitHub<a href="https://tailcall.run/blog/graphql-microservices-migration/#github" class="hash-link" aria-label="Direct link to GitHub" title="Direct link to GitHub">​</a></h3>
<p>GitHub needed a more flexible and user-friendly API to meet increasing demands. By adopting GraphQL, they replaced their monolithic REST API with a single, unified API layer, allowing developers <a href="https://docs.github.com/en/graphql/overview/about-the-graphql-api" target="_blank" rel="noopener noreferrer">to query only the data they needed</a>. This transition improved efficiency, reduced the complexity of API version management, and enabled GitHub to introduce new features more seamlessly.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="airbnb">Airbnb<a href="https://tailcall.run/blog/graphql-microservices-migration/#airbnb" class="hash-link" aria-label="Direct link to Airbnb" title="Direct link to Airbnb">​</a></h3>
<p>Airbnb faced inefficiencies with its monolithic architecture, as multiple REST API calls were needed to fetch data, leading to slow response times. In response, they entered <a href="https://www.infoq.com/news/2019/12/airbnb-graphql-migration/" target="_blank" rel="noopener noreferrer">a close partnership with Apollo</a>. By implementing GraphQL as a unified data layer on top of their microservices, Airbnb reduced the number of API calls and improved performance. This allowed for more effective scaling and a better user experience while enabling independent development across teams.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="shopify">Shopify<a href="https://tailcall.run/blog/graphql-microservices-migration/#shopify" class="hash-link" aria-label="Direct link to Shopify" title="Direct link to Shopify">​</a></h3>
<p>Shopify's monolithic REST API became a bottleneck as their platform grew in complexity. To address this, <a href="https://thenewstack.io/why-shopify-favors-graphql-over-rest-for-its-apis/" target="_blank" rel="noopener noreferrer">they introduced GraphQL to their tech stack</a>, which provided a more flexible and powerful API. This enabled developers to request exactly the data they needed, improving efficiency and supporting larger merchants. The strong typing and introspection features of GraphQL also enhanced API documentation, fostering greater innovation among developers.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="pinterest">Pinterest<a href="https://tailcall.run/blog/graphql-microservices-migration/#pinterest" class="hash-link" aria-label="Direct link to Pinterest" title="Direct link to Pinterest">​</a></h3>
<p>Pinterest needed to scale its monolithic architecture while continuing to innovate. They used GraphQL as an intermediary layer during their migration to microservices, <a href="https://graphql.org/conf/2024/schedule/515c8ade2da6e1fc710e87df182dd8e6/" target="_blank" rel="noopener noreferrer">allowing for a gradual transition</a> without disrupting the user experience. This approach enabled Pinterest to decouple its front end from the back end, facilitating independent development and smoother scaling.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion">Conclusion<a href="https://tailcall.run/blog/graphql-microservices-migration/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>Migrating from a monolithic architecture to microservices is a complex but rewarding process. By leveraging GraphQL, organizations can ease the transition, maintain a consistent API for clients, and gradually refactor their systems without significant disruption. The flexibility and efficiency of GraphQL make it a powerful tool for navigating the challenges of modern software architecture.</p>
<p><a href="https://tailcall.run/contact/" target="_blank" rel="noopener noreferrer">Contact us today</a> to learn more about how Tailcall can help you overcome Monolith to Microservices Migration challenges using GraphQL.</p>
<section class="flex flex-col justify-center px-4 py-4 max-w-3xl mx-auto"><div class="relative flex flex-col max-md:space-y-6 md:flex-row md:items-center p-8 bg-neutral-900 rounded-2xl overflow-hidden max-md:p-6"><svg xmlns="http://www.w3.org/2000/svg" width="740" height="190" fill="none" viewBox="0 0 740 190" class="absolute inset-0 w-full h-full object-cover opacity-5 z-0 max-w-none max-h-none"><g fill="#CECECF"><path d="M51.336 186.568q-12.906 0-21.071-7.902-7.902-8.165-7.902-21.598V83.32h-32.66V55.927h32.66V15.365H55.55v40.562h35.821V83.32h-35.82v67.954q0 7.9 7.374 7.901h25.286v27.393zM151.438 190.255q-13.96 0-25.022-4.741-11.062-5.004-17.647-14.223-6.321-9.481-6.321-22.915 0-13.432 6.321-22.388 6.585-9.218 17.911-13.696 11.589-4.74 26.339-4.741h35.82v-7.375q0-9.218-5.794-15.013-5.795-6.058-18.437-6.058-12.38 0-18.438 5.795-6.057 5.53-7.901 14.486l-30.553-10.272q3.16-10.008 10.008-18.174 7.112-8.428 18.701-13.433 11.852-5.267 28.709-5.267 25.812 0 40.826 12.906 15.013 12.905 15.013 37.401v48.727q0 7.9 7.375 7.901h10.535v27.393h-22.124q-9.746 0-16.067-4.741t-6.321-12.643v-.263h-5.005q-1.053 3.16-4.741 8.428-3.687 5.004-11.589 8.955t-21.598 3.951m5.795-26.865q13.96 0 22.651-7.639 8.955-7.9 8.955-20.807v-2.634h-33.45q-9.219 0-14.486 3.951t-5.268 11.062 5.531 11.589q5.53 4.478 16.067 4.478M252.612 186.568V55.928h33.187v130.64zm16.594-145.917q-8.955 0-15.277-5.795-6.057-5.794-6.058-15.277 0-9.48 6.058-15.276 6.322-5.795 15.277-5.795 9.219 0 15.276 5.795 6.058 5.794 6.058 15.277 0 9.48-6.058 15.276t-15.276 5.795M312.039 186.568V2.196h33.187v184.372zM432.836 190.255q-18.964 0-34.504-7.901-15.276-7.902-24.232-22.915t-8.955-36.348v-3.687q0-21.335 8.955-36.348t24.232-22.915q15.54-7.9 34.504-7.901 18.7 0 32.134 6.584 13.433 6.585 21.597 18.174 8.429 11.326 11.063 25.812l-32.134 6.848q-1.053-7.9-4.741-14.223-3.687-6.321-10.535-10.008-6.585-3.688-16.594-3.688-10.008 0-18.174 4.478-7.901 4.214-12.642 12.906-4.478 8.429-4.478 20.807v2.634q0 12.38 4.478 21.071 4.74 8.428 12.642 12.906 8.166 4.215 18.174 4.215 15.013 0 22.652-7.639 7.901-7.9 10.008-20.544l32.134 7.638q-3.425 13.96-11.853 25.549-8.164 11.327-21.597 17.91-13.434 6.585-32.134 6.585M555.822 190.255q-13.96 0-25.022-4.741-11.062-5.004-17.647-14.223-6.321-9.481-6.321-22.915 0-13.432 6.321-22.388 6.585-9.218 17.911-13.696 11.589-4.74 26.338-4.741h35.821v-7.375q0-9.218-5.794-15.013-5.795-6.058-18.437-6.058-12.38 0-18.438 5.795-6.057 5.53-7.901 14.486L512.1 89.114q3.16-10.008 10.008-18.174 7.112-8.428 18.701-13.433 11.853-5.267 28.709-5.267 25.812 0 40.826 12.906 15.013 12.905 15.013 37.401v48.727q0 7.9 7.375 7.901h10.535v27.393h-22.124q-9.746 0-16.067-4.741-6.322-4.741-6.322-12.643v-.263h-5.004q-1.053 3.16-4.741 8.428-3.687 5.004-11.589 8.955t-21.598 3.951m5.795-26.865q13.96 0 22.651-7.639 8.955-7.9 8.955-20.807v-2.634h-33.45q-9.22 0-14.486 3.951-5.268 3.95-5.268 11.062t5.531 11.589q5.53 4.478 16.067 4.478M656.996 186.568V2.196h33.187v184.372zM716.423 186.568V2.196h33.187v184.372z"></path></g></svg><div class="relative z-10 flex flex-col flex-1 space-y-2.5 text-center max-md:text-left md:text-left"><h2 class="text-3xl font-bold leading-tight text-white sm:text-4xl">Simplify your Microservices migration with Tailcall</h2><p class="text-base leading-relaxed text-zinc-400 sm:text-lg">Try Tailcall today</p></div><div class="relative z-10 mt-6 max-md:w-full max-md:flex max-md:justify-center md:mt-0 md:ml-6 md:flex-shrink-0"><a class="group relative disabled:opacity-25 disabled:cursor-not-allowed flex items-center justify-center gap-x-SPACE_03 hover:no-underline rounded-lg sm:rounded-xl h-12 sm:h-16 text-content-small font-bold sm:text-title-small cursor-pointer px-SPACE_06 py-SPACE_03 sm:px-SPACE_08 lg:px-SPACE_10 sm:py-SPACE_04 lg:py-SPACE_05 w-fit bg-yellow-300 border border-solid text-tailCall-dark-500 bg-transparent hover:text-tailCall-dark-500" href="https://tailcall.run/docs/"><span class="z-20"> <!-- -->Get Started</span></a></div></div></section>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="faqs">FAQs<a href="https://tailcall.run/blog/graphql-microservices-migration/#faqs" class="hash-link" aria-label="Direct link to FAQs" title="Direct link to FAQs">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="what-is-the-main-advantage-of-using-graphql-in-microservices-migration">What is the main advantage of using GraphQL in microservices migration?<a href="https://tailcall.run/blog/graphql-microservices-migration/#what-is-the-main-advantage-of-using-graphql-in-microservices-migration" class="hash-link" aria-label="Direct link to What is the main advantage of using GraphQL in microservices migration?" title="Direct link to What is the main advantage of using GraphQL in microservices migration?">​</a></h3>
<p>GraphQL provides a unified API layer that abstracts the complexity of the underlying microservices, allowing for a smoother and less disruptive migration process.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="can-i-use-graphql-with-existing-rest-apis">Can I use GraphQL with existing REST APIs?<a href="https://tailcall.run/blog/graphql-microservices-migration/#can-i-use-graphql-with-existing-rest-apis" class="hash-link" aria-label="Direct link to Can I use GraphQL with existing REST APIs?" title="Direct link to Can I use GraphQL with existing REST APIs?">​</a></h3>
<p>Yes, GraphQL can be layered on top of existing REST APIs, allowing you to gradually transition to a more flexible API architecture.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="is-graphql-secure">Is GraphQL secure?<a href="https://tailcall.run/blog/graphql-microservices-migration/#is-graphql-secure" class="hash-link" aria-label="Direct link to Is GraphQL secure?" title="Direct link to Is GraphQL secure?">​</a></h3>
<p>Yes, but it requires proper security measures such as authentication, authorization, and rate limiting to ensure that the API is protected from threats.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="how-does-graphql-improve-performance-in-microservices">How does GraphQL improve performance in microservices?<a href="https://tailcall.run/blog/graphql-microservices-migration/#how-does-graphql-improve-performance-in-microservices" class="hash-link" aria-label="Direct link to How does GraphQL improve performance in microservices?" title="Direct link to How does GraphQL improve performance in microservices?">​</a></h3>
<p>GraphQL allows clients to request only the data they need in a single query, reducing the number of round trips and the amount of data transferred over the network.</p>]]></content:encoded>
            <category>GraphQL</category>
            <category>Microservice</category>
            <category>Best Practices</category>
            <category>Migration</category>
        </item>
        <item>
            <title><![CDATA[API Strategy: Driving Innovation and Growth in Modern Business]]></title>
            <link>https://tailcall.run/blog/api-strategy/</link>
            <guid>https://tailcall.run/blog/api-strategy/</guid>
            <pubDate>Tue, 13 Aug 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn how a well-defined API strategy can drive innovation, improve efficiency, and create new opportunities for growth in modern businesses.]]></description>
            <content:encoded><![CDATA[<p>As I reflect on the evolution of APIs, I am reminded of <strong>Jeff Bezos' famous 2002 mandate</strong> to his IT organization at Amazon.</p>
<p>The CEO's directive to expose data and functionality through service interfaces, and to design these interfaces to be externalizable, was a game-changer.</p>
<p><img decoding="async" loading="lazy" alt="Jeff Bezos&amp;#39; mandate" src="https://tailcall.run/assets/images/bezos_api_mandate-bce9e9b3f0a893a6dc975dc47c2cec33.png" width="2272" height="1172" class="img_ev3q"></p>
<p>Fast-forward to today, and APIs have become the backbone of modern business, with even the smallest companies having hundreds of APIs.</p>
<p>However, the landscape has shifted dramatically. Having good APIs is no longer enough; we need a strategy for APIs.
Having good APIs is indeed a crucial starting point, but it's only the beginning. A well-designed API can provide a solid foundation for your business, but without a comprehensive strategy, you risk missing out on opportunities for growth, innovation, and efficiency.</p>
<p>A strategy for APIs involves considering the entire API lifecycle, from design and development to deployment, management, and maintenance. It requires a deep understanding of your business goals, target audience, and the role APIs play in achieving those goals.</p>
<p>In 2024, API strategy needs to be defined at the sub-API level, not just at the company level. This is where the rubber meets the road, and businesses must adapt to stay ahead of the curve.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="what-is-an-api-strategy">What is an API Strategy?<a href="https://tailcall.run/blog/api-strategy/#what-is-an-api-strategy" class="hash-link" aria-label="Direct link to What is an API Strategy?" title="Direct link to What is an API Strategy?">​</a></h2>
<p>An API strategy is an outline of the steps needed to design, develop, and manage APIs effectively. It's no longer just about having good APIs; it's about ensuring they are secure, scalable, and reliable. It's about making sure developers are more productive and machine utilization is more efficient. In essence, API strategy is about abstracting cross-cutting concerns from business logic.
Abstracting cross-cutting concerns from business logic is a critical aspect of API strategy. Cross-cutting concerns refer to functionalities that are essential to the operation of your API but are not directly related to the business logic. Examples of cross-cutting concerns include:</p>
<ul>
<li><strong>Security</strong>: authentication, authorization, and encryption</li>
<li><strong>Monitoring</strong>: logging, analytics, and error tracking</li>
<li><strong>Scalability</strong>: rate limiting, caching, and load balancing</li>
</ul>
<p>By abstracting these concerns from business logic, you can decouple them from the core functionality of your API, making it easier to maintain, update, and scale your API without affecting the underlying business logic.</p>
<p>For instance, if you're building an e-commerce API, you might abstract security concerns by implementing OAuth 2.0 authentication and authorization. This would allow you to focus on the business logic of processing orders, managing inventory, and handling payments, while ensuring that security is handled separately.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="why-do-you-need-an-api-strategy">Why Do You Need an API Strategy?<a href="https://tailcall.run/blog/api-strategy/#why-do-you-need-an-api-strategy" class="hash-link" aria-label="Direct link to Why Do You Need an API Strategy?" title="Direct link to Why Do You Need an API Strategy?">​</a></h2>
<p>The importance of an API strategy cannot be overstated. Without one, you risk exposing your business to security vulnerabilities, scalability issues, and reliability problems. A well-defined API strategy helps you address critical concerns such as:</p>
<ul>
<li>Cross-functional collaboration</li>
<li>Rate limiting</li>
<li>Circuit breaking</li>
<li>Caching</li>
<li>Routing</li>
<li>Composition</li>
<li>Access control</li>
<li>Authentication</li>
<li>Versioning</li>
<li>Logging</li>
<li>Monitoring</li>
<li>Documentation</li>
</ul>
<p>Having a strategy in place ensures that you're not just documenting your APIs, but also managing them effectively, securing them, scaling them, monitoring them, and making sure they're reliable.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-role-of-tools-in-api-strategy">The Role of Tools in API Strategy<a href="https://tailcall.run/blog/api-strategy/#the-role-of-tools-in-api-strategy" class="hash-link" aria-label="Direct link to The Role of Tools in API Strategy" title="Direct link to The Role of Tools in API Strategy">​</a></h2>
<p>There are many tools available in the market to help with API strategy, such as API gateways and Swagger. An API gateway can help with rate limiting, caching, routing, access control, authentication, authorization, logging, and monitoring. Swagger can assist with documentation. However, are these tools enough? Are they capable of addressing all the challenges that come with API strategy? Let's discuss.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="api-composition-a-critical-aspect-of-api-strategy">API Composition: A Critical Aspect of API Strategy<a href="https://tailcall.run/blog/api-strategy/#api-composition-a-critical-aspect-of-api-strategy" class="hash-link" aria-label="Direct link to API Composition: A Critical Aspect of API Strategy" title="Direct link to API Composition: A Critical Aspect of API Strategy">​</a></h3>
<p>API composition is a critical aspect of API strategy. How do you compose your APIs? Do you use an API gateway or a different tool? How do you prevent the <a href="https://tailcall.run/docs/graphql-n-plus-one-problem-solved-tailcall/#what-is-the-n1-problem">N+1 problem</a> when composing APIs using an API gateway? How do you handle the failure of one of the APIs in the composition? How do you handle caching in the composition? These are just a few of the questions that need to be addressed in your API strategy.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="access-control-a-key-consideration">Access Control: A Key Consideration<a href="https://tailcall.run/blog/api-strategy/#access-control-a-key-consideration" class="hash-link" aria-label="Direct link to Access Control: A Key Consideration" title="Direct link to Access Control: A Key Consideration">​</a></h3>
<p>Access control is another key consideration in API strategy. Can you create an API and use it as both a public API and an admin API, restricting access to fields based on user role? The answer is no, not without a well-defined API strategy.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="a-solution-to-api-strategy-challenges">A Solution to API Strategy Challenges<a href="https://tailcall.run/blog/api-strategy/#a-solution-to-api-strategy-challenges" class="hash-link" aria-label="Direct link to A Solution to API Strategy Challenges" title="Direct link to A Solution to API Strategy Challenges">​</a></h2>
<p>For having a well-defined API strategy, you need a set of tools that can help you with the above points. Such a solution should have first-class support for:</p>
<ul>
<li><strong>API Composition:</strong> Easily compose APIs to create complex workflows and integrations.</li>
<li><strong>Access Control:</strong> Implement fine-grained access control to restrict access to APIs and resources based on user roles and permissions.</li>
<li><strong>Rate Limiting:</strong> Enforce rate limits to prevent abuse and ensure fair usage of your APIs.</li>
<li><strong>Circuit Breaking:</strong> Detect and prevent cascading failures in your API ecosystem.</li>
<li><strong>Caching:</strong> Improve performance and reduce latency with intelligent caching mechanisms.</li>
<li><strong>Routing:</strong> Route API requests efficiently and securely to the right backend services.</li>
<li><strong>Authentication and Authorization:</strong> Implement robust authentication and authorization mechanisms to ensure secure access to your APIs.</li>
<li><strong>Versioning:</strong> Manage multiple versions of your APIs and ensure backward compatibility.</li>
<li><strong>Logging and Monitoring:</strong> Gain visibility into API performance and behavior with real-time logging and monitoring.</li>
<li><strong>Documentation:</strong> Generate accurate and up-to-date documentation for your APIs.</li>
</ul>
<p>A good solution should also:</p>
<ul>
<li><strong>Introspect and detect problems:</strong> Analyze your configurations to identify potential issues and provide recommendations for improvement.</li>
<li><strong>Transfer type safety:</strong> Ensure that your API configurations are type-safe and consistent with your code.</li>
<li><strong>Provide access control to the sub-API level:</strong> Restrict access to specific fields in the APIs based on user roles and permissions.</li>
</ul>
<p>By using such a solution, you can overcome the challenges of API strategy and create a robust, scalable, and secure API ecosystem that drives innovation and growth in your business.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion">Conclusion<a href="https://tailcall.run/blog/api-strategy/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>In conclusion, API strategy is no longer a nice-to-have; it's a must-have for businesses that want to stay ahead of the curve. By defining a clear API strategy, businesses can drive innovation, improve efficiency, and create new opportunities for growth. At Tailcall, we're committed to helping businesses achieve their API goals with our GraphQL solution.</p>
<p><strong>Take the First Step Towards a Well-Defined API Strategy</strong></p>
<p>If you're struggling to define your API strategy, take the first step today. Assess your current API landscape, identify areas for improvement, and start building a strategy that works for your business. Remember, A well-defined API strategy is essential for driving innovation and growth in modern business because it enables companies to:</p>
<ul>
<li><strong>Unlock New Revenue Streams</strong>: By providing APIs that offer value to external developers, businesses can create new revenue streams through API-based partnerships and monetization models.</li>
<li><strong>Enhance Customer Experience</strong>: APIs can provide real-time data and services that enhance customer experience, leading to increased loyalty and retention.</li>
<li><strong>Foster Innovation</strong>: APIs can enable innovation by providing access to new data, services, and capabilities, allowing businesses to create new products and services that drive growth.</li>
<li><strong>Improve Operational Efficiency</strong>: A well-defined API strategy can help businesses streamline their operations, reduce costs, and improve efficiency, freeing up resources to focus on innovation and growth.</li>
</ul>
<p>By having a well-defined API strategy, businesses can create a solid foundation for innovation and growth, enabling them to stay ahead of the competition and achieve their goals.</p>
<p><strong>Ready to Take Your API Strategy to the Next Level?</strong></p>
<p>Contact us today to learn more about how Tailcall can help you overcome API strategy challenges and drive innovation and growth in your business.</p>
<section class="flex flex-col justify-center px-4 py-4 max-w-3xl mx-auto"><div class="relative flex flex-col max-md:space-y-6 md:flex-row md:items-center p-8 bg-neutral-900 rounded-2xl overflow-hidden max-md:p-6"><svg xmlns="http://www.w3.org/2000/svg" width="740" height="190" fill="none" viewBox="0 0 740 190" class="absolute inset-0 w-full h-full object-cover opacity-5 z-0 max-w-none max-h-none"><g fill="#CECECF"><path d="M51.336 186.568q-12.906 0-21.071-7.902-7.902-8.165-7.902-21.598V83.32h-32.66V55.927h32.66V15.365H55.55v40.562h35.821V83.32h-35.82v67.954q0 7.9 7.374 7.901h25.286v27.393zM151.438 190.255q-13.96 0-25.022-4.741-11.062-5.004-17.647-14.223-6.321-9.481-6.321-22.915 0-13.432 6.321-22.388 6.585-9.218 17.911-13.696 11.589-4.74 26.339-4.741h35.82v-7.375q0-9.218-5.794-15.013-5.795-6.058-18.437-6.058-12.38 0-18.438 5.795-6.057 5.53-7.901 14.486l-30.553-10.272q3.16-10.008 10.008-18.174 7.112-8.428 18.701-13.433 11.852-5.267 28.709-5.267 25.812 0 40.826 12.906 15.013 12.905 15.013 37.401v48.727q0 7.9 7.375 7.901h10.535v27.393h-22.124q-9.746 0-16.067-4.741t-6.321-12.643v-.263h-5.005q-1.053 3.16-4.741 8.428-3.687 5.004-11.589 8.955t-21.598 3.951m5.795-26.865q13.96 0 22.651-7.639 8.955-7.9 8.955-20.807v-2.634h-33.45q-9.219 0-14.486 3.951t-5.268 11.062 5.531 11.589q5.53 4.478 16.067 4.478M252.612 186.568V55.928h33.187v130.64zm16.594-145.917q-8.955 0-15.277-5.795-6.057-5.794-6.058-15.277 0-9.48 6.058-15.276 6.322-5.795 15.277-5.795 9.219 0 15.276 5.795 6.058 5.794 6.058 15.277 0 9.48-6.058 15.276t-15.276 5.795M312.039 186.568V2.196h33.187v184.372zM432.836 190.255q-18.964 0-34.504-7.901-15.276-7.902-24.232-22.915t-8.955-36.348v-3.687q0-21.335 8.955-36.348t24.232-22.915q15.54-7.9 34.504-7.901 18.7 0 32.134 6.584 13.433 6.585 21.597 18.174 8.429 11.326 11.063 25.812l-32.134 6.848q-1.053-7.9-4.741-14.223-3.687-6.321-10.535-10.008-6.585-3.688-16.594-3.688-10.008 0-18.174 4.478-7.901 4.214-12.642 12.906-4.478 8.429-4.478 20.807v2.634q0 12.38 4.478 21.071 4.74 8.428 12.642 12.906 8.166 4.215 18.174 4.215 15.013 0 22.652-7.639 7.901-7.9 10.008-20.544l32.134 7.638q-3.425 13.96-11.853 25.549-8.164 11.327-21.597 17.91-13.434 6.585-32.134 6.585M555.822 190.255q-13.96 0-25.022-4.741-11.062-5.004-17.647-14.223-6.321-9.481-6.321-22.915 0-13.432 6.321-22.388 6.585-9.218 17.911-13.696 11.589-4.74 26.338-4.741h35.821v-7.375q0-9.218-5.794-15.013-5.795-6.058-18.437-6.058-12.38 0-18.438 5.795-6.057 5.53-7.901 14.486L512.1 89.114q3.16-10.008 10.008-18.174 7.112-8.428 18.701-13.433 11.853-5.267 28.709-5.267 25.812 0 40.826 12.906 15.013 12.905 15.013 37.401v48.727q0 7.9 7.375 7.901h10.535v27.393h-22.124q-9.746 0-16.067-4.741-6.322-4.741-6.322-12.643v-.263h-5.004q-1.053 3.16-4.741 8.428-3.687 5.004-11.589 8.955t-21.598 3.951m5.795-26.865q13.96 0 22.651-7.639 8.955-7.9 8.955-20.807v-2.634h-33.45q-9.22 0-14.486 3.951-5.268 3.95-5.268 11.062t5.531 11.589q5.53 4.478 16.067 4.478M656.996 186.568V2.196h33.187v184.372zM716.423 186.568V2.196h33.187v184.372z"></path></g></svg><div class="relative z-10 flex flex-col flex-1 space-y-2.5 text-center max-md:text-left md:text-left"><h2 class="text-3xl font-bold leading-tight text-white sm:text-4xl">Discover future of GraphQL</h2><p class="text-base leading-relaxed text-zinc-400 sm:text-lg">Try Tailcall today</p></div><div class="relative z-10 mt-6 max-md:w-full max-md:flex max-md:justify-center md:mt-0 md:ml-6 md:flex-shrink-0"><a class="group relative disabled:opacity-25 disabled:cursor-not-allowed flex items-center justify-center gap-x-SPACE_03 hover:no-underline rounded-lg sm:rounded-xl h-12 sm:h-16 text-content-small font-bold sm:text-title-small cursor-pointer px-SPACE_06 py-SPACE_03 sm:px-SPACE_08 lg:px-SPACE_10 sm:py-SPACE_04 lg:py-SPACE_05 w-fit bg-yellow-300 border border-solid text-tailCall-dark-500 bg-transparent hover:text-tailCall-dark-500" href="https://tailcall.run/docs/"><span class="z-20"> <!-- -->Get Started</span></a></div></div></section>]]></content:encoded>
            <category>API</category>
            <category>Strategy</category>
            <category>GraphQL</category>
            <category>Scalability</category>
        </item>
        <item>
            <title><![CDATA[How Tailcall statically identifies N+1 issues in GraphQL]]></title>
            <link>https://tailcall.run/blog/tailcall-n+1-identification-algorithm/</link>
            <guid>https://tailcall.run/blog/tailcall-n+1-identification-algorithm/</guid>
            <pubDate>Sun, 04 Aug 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[A deep dive into the implementation details of the N+1 tracker]]></description>
            <content:encoded><![CDATA[<p>As a developer working with GraphQL, you're likely familiar with the concept of N+1 issues. If not, you're in for a treat - check out our <a href="https://tailcall.run/docs/graphql-n-plus-one-problem-solved-tailcall/">N+1 guide!</a></p>
<p>To summarize, they occur when a GraphQL resolver is called multiple times for a single GraphQL request, leading to a large set of requests upstream and overall slower query execution. In this blog post, we'll dive into how Tailcall specifically identifies N+1 issues in GraphQL, and explore the algorithm and data structures used to detect these issues.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="high-level-working">High-Level Working<a href="https://tailcall.run/blog/tailcall-n+1-identification-algorithm/#high-level-working" class="hash-link" aria-label="Direct link to High-Level Working" title="Direct link to High-Level Working">​</a></h2>
<p>Unlike a traditional GraphQL implementation where the resolvers are written by hand, Tailcall encourages developers to take a configuration-driven approach. This has many benefits, and we have talked about them in our previous <a href="https://tailcall.run/blog/writing-a-graphql-backend-by-hand-is-long-gone/">blog</a>.</p>
<p>One of the main advantages of not handwriting is the ability to introspect and optimize. Let's take an example of two functions written in Rust, though the problem is evident in all general purpose programming languages.</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> </span><span class="token constant" style="color:#C586C0">BASE_URL</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">&amp;</span><span class="token keyword" style="color:#C586C0">str</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"https://jsonplaceholder.typicode.com"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token comment" style="color:#30C26D;font-style:italic">// Describes a typical Post returned from the /posts API</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:#C586C0">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">i32</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    user_id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">i32</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    title</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">String</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    body</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">String</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    user</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Option</span><span class="token operator" style="color:#8DFFF8">&lt;</span><span class="token class-name" style="color:#C586C0">User</span><span class="token operator" style="color:#8DFFF8">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token comment" style="color:#30C26D;font-style:italic">// Describes a typical User object from the /users API</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">struct</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:#C586C0">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">i32</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">String</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    email</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">String</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token comment" style="color:#30C26D;font-style:italic">// Asynchronously retrieves a `User` object by making a GET request using the given `user_id`.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">async</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#FDEA2F">get_user</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">user_id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">i32</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">let</span><span class="token plain"> response </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">request</span><span class="token punctuation" style="color:#fff">(</span><span class="token class-name" style="color:#C586C0">Method</span><span class="token punctuation" style="color:#fff">::</span><span class="token constant" style="color:#C586C0">GET</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token macro property" style="color:#C586C0">format!</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">"{}/users/{}"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token constant" style="color:#C586C0">BASE_URL</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> user_id</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">.</span><span class="token keyword" style="color:#C586C0">await</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token comment" style="color:#30C26D;font-style:italic">// Decode the body as a User</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token function" style="color:#FDEA2F">decode</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">response</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">body</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token comment" style="color:#30C26D;font-style:italic">// Asynchronously fetches and updates posts with user details from the API.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">async</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#FDEA2F">get_posts</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Vec</span><span class="token operator" style="color:#8DFFF8">&lt;</span><span class="token class-name" style="color:#C586C0">Post</span><span class="token operator" style="color:#8DFFF8">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">let</span><span class="token plain"> response </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">request</span><span class="token punctuation" style="color:#fff">(</span><span class="token class-name" style="color:#C586C0">Method</span><span class="token punctuation" style="color:#fff">::</span><span class="token constant" style="color:#C586C0">GET</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token macro property" style="color:#C586C0">format!</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">"{}/posts"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token constant" style="color:#C586C0">BASE_URL</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">.</span><span class="token keyword" style="color:#C586C0">await</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token comment" style="color:#30C26D;font-style:italic">// Decode the response into a Vec&lt;Post&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">let</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">mut</span><span class="token plain"> posts </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">decode</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">response</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">body</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token comment" style="color:#30C26D;font-style:italic">// Set the actual user by making an HTTP call</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">for</span><span class="token plain"> post </span><span class="token keyword" style="color:#C586C0">in</span><span class="token plain"> posts </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        post</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">user </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Some</span><span class="token punctuation" style="color:#fff">(</span><span class="token function" style="color:#FDEA2F">get_user</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">post</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">user_id</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">.</span><span class="token keyword" style="color:#C586C0">await</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    posts</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>You might have identified that there are few issues in the implementation above:</p>
<ol>
<li>For each post item we end up making a call for the user independently, there is a clear N+1 issue here.</li>
<li>It's possible that two posts can be written by the same user, and yet we will end up making duplicate calls for the same user.</li>
<li>All calls to the <code>/users</code> API is being made in sequence, even though they can be paralyzed.</li>
<li>There are multiple points of failure which the above code doesn't handle.</li>
</ol>
<p>Now, yes all of these issues can be solved by better coding practices, using a <a href="https://doc.rust-lang.org/std/result/" target="_blank" rel="noopener noreferrer">Result</a> type and using a <a href="https://github.com/graphql/dataloader" target="_blank" rel="noopener noreferrer">DataLoader</a> but that's besides the point. The point here is - Semantic analysis of any code is critical to building a robust systems and is only possible with some sort of human intervention typically in the form of code reviews or perhaps using some LLM if you are into that hype. What you can't do is - Write an algorithm to identify the N+1 issue in your GraphQL implementation that <strong>100% accurate</strong>.</p>
<p>With a configuration its a completely different story, take the below Tailcall configuration for example:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">schema</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">query</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Query</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">posts</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">Post</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token directive function" style="color:#FDEA2F">@http</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">url</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"https://jsonplaceholder.typicode.com/posts"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">userId</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">title</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">body</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">user</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token directive function" style="color:#FDEA2F">@http</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token attr-name" style="color:#8DFFF8">url</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"https://jsonplaceholder.typicode.com/users{{.value.userId}}"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">email</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>It's simple, expressive and doesn't expose the guts of how data will be queried, batched, deduped, parsed etc. Sure, configurations take away flexibility from writing anything but in return it liberates you from a ton of such nitty gritties of building a robust software system. The above configuration file can be parsed, validated and semantically analyzed accurately to identify issues such as N+1 very precisely using the <a href="https://tailcall.run/docs/tailcall-graphql-cli/#check">check</a> command as follows:</p>
<p><img decoding="async" loading="lazy" alt="Actual Usage Image" src="https://tailcall.run/assets/images/n+1-image-terminal-2bfbafada99d3c089f9d703c60855bef.png" width="3232" height="984" class="img_ev3q"></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-algorithm">The Algorithm<a href="https://tailcall.run/blog/tailcall-n+1-identification-algorithm/#the-algorithm" class="hash-link" aria-label="Direct link to The Algorithm" title="Direct link to The Algorithm">​</a></h2>
<p>Tailcall reads your configuration, parses it, and internally stores it in an efficient graph data-structure that resembles a <code>HashMap</code>. This allows <code>O(1)</code> access to a GraphQL type which represented as a node by its name. Once the graph data-structure is ready we make it go through a series of validators, one of them being the <strong>N+1 tracker</strong>.</p>
<p>Now, here's where it gets fascinating. We use a Depth-First Search (DFS) algorithm, starting at the root query and traversing all the connected nodes. Let me walk you through this cool process:</p>
<ol>
<li>Initialize two variables to track the currently traversed <code>path</code> and <code>visited</code> fields so that we can avoid cycles.</li>
<li>Start at the root query and begin traversing the graph data structure.</li>
<li>For each field in the current node, check if it has a resolver and is not batched. We know if the node contains a resolver if that node has a <a href="https://tailcall.run/docs/http-directive/"><code>@http</code></a> or a <a href="https://tailcall.run/docs/grpc-directive/"><code>@grpc</code></a>. Tailcall supports powerful batching primitives and if a field uses a Batch API, then that resolver is whitelisted and dropped from the list of potential N+1 candidates.</li>
<li>If the field has a resolver and is not batched, and the current path contains a list, then the current path is added to the result.</li>
<li>Otherwise, we recursively traverse the graph data structure, updating the current path and visited fields as necessary.</li>
<li>If a cycle is detected, return the cached result instead of re-traversing the path.</li>
<li>Once the traversal is complete, return the result, which represents the identified N+1 issues.</li>
</ol>
<p>This algorithm allows Tailcall to efficiently identify potential N+1 issues across your entire GraphQL schema, even in complex, deeply nested structures.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</div><div class="admonitionContent_BuS1"><p>To see the actual implementation you can check out the <a href="https://github.com/tailcallhq/tailcall/blob/main/src/core/config/npo/tracker.rs" target="_blank" rel="noopener noreferrer">tracker.rs</a> implementation.</p></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="performance">Performance<a href="https://tailcall.run/blog/tailcall-n+1-identification-algorithm/#performance" class="hash-link" aria-label="Direct link to Performance" title="Direct link to Performance">​</a></h2>
<p>While starting, Tailcall automatically performs these validations and one of our users complained that it would take around 5 minutes to start the server for their configuration which was around 10,000 lines. This caught our attention! The thing is, finding N+1 issues is a complex dynamic-programming problem. All this while our team has been focused on <a href="https://github.com/tailcallhq/graphql-benchmarks" target="_blank" rel="noopener noreferrer">benchmarking</a> and optimizing the runtime performance of the server. This was the first time perhaps that we were surprised to see such a degradation in performance. We quickly realized that this is a dynamic programming problem and there are certain tricks to make such algorithms efficient. For us, it boiled down to two key optimizations:</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="1-memoization">1. Memoization<a href="https://tailcall.run/blog/tailcall-n+1-identification-algorithm/#1-memoization" class="hash-link" aria-label="Direct link to 1. Memoization" title="Direct link to 1. Memoization">​</a></h3>
<p>Our algorithm uses a cache to store the results of previous traversals. The cache is used to avoid re-traversing the same path multiple times. It's essentially memoization however is super critical if you have a huge configuration that you'd want to validate.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="2-chunk-data-structure">2. Chunk Data Structure<a href="https://tailcall.run/blog/tailcall-n+1-identification-algorithm/#2-chunk-data-structure" class="hash-link" aria-label="Direct link to 2. Chunk Data Structure" title="Direct link to 2. Chunk Data Structure">​</a></h3>
<p>Let me introduce you to our secret weapon: a special yet simple data structure that we affectionately call "Chunk". It's a game-changer for storing and manipulating query paths. The chunk data structure is implemented as an enum with three variants:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-rust codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-rust codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">enum</span><span class="token plain"> </span><span class="token type-definition class-name" style="color:#C586C0">Chunk</span><span class="token operator" style="color:#8DFFF8">&lt;</span><span class="token class-name" style="color:#C586C0">A</span><span class="token operator" style="color:#8DFFF8">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token class-name" style="color:#C586C0">Empty</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token class-name" style="color:#C586C0">Append</span><span class="token punctuation" style="color:#fff">(</span><span class="token class-name" style="color:#C586C0">A</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Rc</span><span class="token operator" style="color:#8DFFF8">&lt;</span><span class="token class-name" style="color:#C586C0">Chunk</span><span class="token operator" style="color:#8DFFF8">&lt;</span><span class="token class-name" style="color:#C586C0">A</span><span class="token operator" style="color:#8DFFF8">&gt;&gt;</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token class-name" style="color:#C586C0">Concat</span><span class="token punctuation" style="color:#fff">(</span><span class="token class-name" style="color:#C586C0">Rc</span><span class="token operator" style="color:#8DFFF8">&lt;</span><span class="token class-name" style="color:#C586C0">Chunk</span><span class="token operator" style="color:#8DFFF8">&lt;</span><span class="token class-name" style="color:#C586C0">A</span><span class="token operator" style="color:#8DFFF8">&gt;&gt;</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Rc</span><span class="token operator" style="color:#8DFFF8">&lt;</span><span class="token class-name" style="color:#C586C0">Chunk</span><span class="token operator" style="color:#8DFFF8">&lt;</span><span class="token class-name" style="color:#C586C0">A</span><span class="token operator" style="color:#8DFFF8">&gt;&gt;</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">impl</span><span class="token operator" style="color:#8DFFF8">&lt;</span><span class="token class-name" style="color:#C586C0">A</span><span class="token operator" style="color:#8DFFF8">&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Chunk</span><span class="token operator" style="color:#8DFFF8">&lt;</span><span class="token class-name" style="color:#C586C0">A</span><span class="token operator" style="color:#8DFFF8">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#FDEA2F">new</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">-&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">Self</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">Self</span><span class="token punctuation" style="color:#fff">::</span><span class="token class-name" style="color:#C586C0">Empty</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#FDEA2F">is_null</span><span class="token punctuation" style="color:#fff">(</span><span class="token operator" style="color:#8DFFF8">&amp;</span><span class="token keyword" style="color:#C586C0">self</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">-&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">bool</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token macro property" style="color:#C586C0">matches!</span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">self</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Chunk</span><span class="token punctuation" style="color:#fff">::</span><span class="token class-name" style="color:#C586C0">Empty</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#FDEA2F">append</span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">self</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> a</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">A</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">-&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">Self</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token class-name" style="color:#C586C0">Chunk</span><span class="token punctuation" style="color:#fff">::</span><span class="token class-name" style="color:#C586C0">Append</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Rc</span><span class="token punctuation" style="color:#fff">::</span><span class="token function" style="color:#FDEA2F">new</span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">self</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#FDEA2F">concat</span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">self</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> other</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Chunk</span><span class="token operator" style="color:#8DFFF8">&lt;</span><span class="token class-name" style="color:#C586C0">A</span><span class="token operator" style="color:#8DFFF8">&gt;</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">-&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">Self</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">self</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">is_null</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> other</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> other</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">is_null</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">self</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">Self</span><span class="token punctuation" style="color:#fff">::</span><span class="token class-name" style="color:#C586C0">Concat</span><span class="token punctuation" style="color:#fff">(</span><span class="token class-name" style="color:#C586C0">Rc</span><span class="token punctuation" style="color:#fff">::</span><span class="token function" style="color:#FDEA2F">new</span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">self</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Rc</span><span class="token punctuation" style="color:#fff">::</span><span class="token function" style="color:#FDEA2F">new</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">other</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#FDEA2F">as_vec</span><span class="token punctuation" style="color:#fff">(</span><span class="token operator" style="color:#8DFFF8">&amp;</span><span class="token keyword" style="color:#C586C0">self</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">-&gt;</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Vec</span><span class="token operator" style="color:#8DFFF8">&lt;</span><span class="token operator" style="color:#8DFFF8">&amp;</span><span class="token class-name" style="color:#C586C0">A</span><span class="token operator" style="color:#8DFFF8">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token comment" style="color:#30C26D;font-style:italic">// ... converts the chunk into a vec</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<table><thead><tr><th><strong>Variant</strong></th><th></th></tr></thead><tbody><tr><td><strong>Nil</strong></td><td>Represents an empty chunk</td></tr><tr><td><strong>Append</strong></td><td>Represents an append operation performed on an existing chunk</td></tr><tr><td><strong>Concat</strong></td><td>Represents the concatenation of two chunks</td></tr></tbody></table>
<p>The chunk data structure has the following properties:</p>
<ul>
<li><code>O(1)</code> complexity for append and concat operations.</li>
<li>Uses Reference Counting instead of Boxing to make cloning faster.</li>
<li>Can be converted to a vector of references to the elements in the chunk.</li>
</ul>
<p>You can clearly see that we don't actually perform an append or a concat operation instead we store a representation of that operation. This is a significant optimization because while performing the DFS, we create a lot of temporary query paths. However with the chunk data structure we don't need to allocate any additional memory on the heap or perform any form of wasted computation for paths that don't produce an N+1 query.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion">Conclusion<a href="https://tailcall.run/blog/tailcall-n+1-identification-algorithm/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>Lastly to ensure that we are always correct and no N+1 issues go unidentified we perform tests with actual configurations.</p>
<p><img decoding="async" loading="lazy" alt="Source Code Screenshot" src="https://tailcall.run/assets/images/github-npo-screenshot-5e40d335542b593af7cd038ab6814fb7.png" width="1318" height="1148" class="img_ev3q"></p>
<p>Hopefully, this peek behind the curtain gives you some insight into how Tailcall identifies N+1 issues in your GraphQL configuration. Pretty cool, right?</p>
<ul>
<li>If you think we can make our N+1 detection faster or better in some other way, please help us improve by <a href="https://github.com/tailcallhq/tailcall" target="_blank" rel="noopener noreferrer">contributing</a> 🙏</li>
<li>If you find this interesting please spread the word 🙌</li>
</ul>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[GraphQL in Vue: 5 Best Approaches for Data Fetching]]></title>
            <link>https://tailcall.run/blog/graphql-vue-client/</link>
            <guid>https://tailcall.run/blog/graphql-vue-client/</guid>
            <pubDate>Thu, 01 Aug 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Unleash the power of GraphQL in your Vue applications! Explore the top 5 methods for seamless data fetching, including in-depth comparisons and error handling strategies.]]></description>
            <content:encoded><![CDATA[<p>Are you tired of wrestling with complex data fetching logic in your Vue applications? If you've ever felt like you're battling an octopus to retrieve the data you need, then GraphQL is here to be your data fetching hero!</p>
<p>GraphQL empowers you to take control of your data requests in Vue.js, ensuring you receive only the specific data your application requires. This translates to cleaner code, faster performance, and a more delightful developer experience.</p>
<p>In this comprehensive guide, we'll unveil the top 5 approaches to seamlessly integrate GraphQL into your Vue projects. It's like opening a treasure chest overflowing with powerful data fetching techniques!</p>
<p>Whether you're a GraphQL novice or a seasoned pro, this blog post caters to all skill levels. We'll delve into each method, providing in-depth explanations, clear comparisons, and practical error handling strategies. Buckle up and prepare to transform into a data-fetching superhero with the power of GraphQL!</p>
<p>Ready to elevate your Vue development experience? Let's dive in!</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="️-project-setup">🛠️ Project Setup<a href="https://tailcall.run/blog/graphql-vue-client/#%EF%B8%8F-project-setup" class="hash-link" aria-label="Direct link to 🛠️ Project Setup" title="Direct link to 🛠️ Project Setup">​</a></h2>
<p>Let's start by setting up our Vue project with Vite, which provides a faster and leaner development experience:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">npm create vite@latest vue-graphql-tailcall-showcase -- --template vue-ts</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">cd vue-graphql-tailcall-showcase</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">npm install</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This creates a new Vue 3 project with TypeScript support. Now, let's install the necessary dependencies for our GraphQL experiments:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">npm install @apollo/client @vue/apollo-composable graphql</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">npm install @urql/vue</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">npm install axios</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">npm install villus</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>These installations will allow us to explore different GraphQL client options in our Vue application.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="-tailcall-backend-configuration">🔧 Tailcall Backend Configuration<a href="https://tailcall.run/blog/graphql-vue-client/#-tailcall-backend-configuration" class="hash-link" aria-label="Direct link to 🔧 Tailcall Backend Configuration" title="Direct link to 🔧 Tailcall Backend Configuration">​</a></h3>
<p>Now, let's set up our Tailcall backend that will wrap the JSONPlaceholder API, providing a GraphQL interface to RESTful data.</p>
<p>First, create a <code>tailcall</code> directory in the project root:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">mkdir tailcall</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Then, create a <code>jsonplaceholder.graphql</code> file in this directory:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token comment" style="color:#30C26D;font-style:italic"># File: tailcall/jsonplaceholder.graphql</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">schema</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token directive function" style="color:#FDEA2F">@server</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">port</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">8000</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token attr-name" style="color:#8DFFF8">hostname</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"0.0.0.0"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token directive function" style="color:#FDEA2F">@upstream</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">httpCache</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">42</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">query</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Query</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">posts</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">Post</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token directive function" style="color:#FDEA2F">@http</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">url</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"http://jsonplaceholder.typicode.com/posts"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">user</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token directive function" style="color:#FDEA2F">@http</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token attr-name" style="color:#8DFFF8">url</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"http://jsonplaceholder.typicode.com/users/{{.args.id}}"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">username</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">email</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">phone</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">website</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">userId</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">title</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">body</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">user</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token directive function" style="color:#FDEA2F">@http</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token attr-name" style="color:#8DFFF8">url</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"http://jsonplaceholder.typicode.com/users/{{.value.userId}}"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This GraphQL schema defines our API structure, mapping RESTful endpoints to GraphQL types and queries.</p>
<p>To start the Tailcall server, you'll need to have Tailcall installed. If you haven't installed it yet, follow the installation instructions from the Tailcall documentation. Once installed, you can start the server with:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">tailcall start ./tailcall/jsonplaceholder.graphql</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This command starts a GraphQL server on <code>http://localhost:8000</code>, which will act as a bridge between our Vue application and the JSONPlaceholder API.</p>
<p>With this setup, we're ready to dive into the exciting world of GraphQL in Vue! 🚀 Our Tailcall backend provides a perfect playground for exploring different GraphQL client approaches, allowing us to fetch posts and user data with the flexibility and power of GraphQL queries. In the following sections, we'll explore how to leverage this backend with various GraphQL clients in our Vue application. Get ready for some data-fetching magic! ✨</p>
<p>Alright, let's dive into our first approach: Apollo Client! 🚀</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="apollo-client---the-swiss-army-knife-of-graphql">Apollo Client - The Swiss Army Knife of GraphQL<a href="https://tailcall.run/blog/graphql-vue-client/#apollo-client---the-swiss-army-knife-of-graphql" class="hash-link" aria-label="Direct link to Apollo Client - The Swiss Army Knife of GraphQL" title="Direct link to Apollo Client - The Swiss Army Knife of GraphQL">​</a></h2>
<p>Apollo Client stands out in the GraphQL ecosystem due to its comprehensive feature set, including intelligent caching, real-time updates, and optimistic UI rendering. For Vue developers working on data-intensive applications, Apollo Client provides a sophisticated approach to state management and data fetching.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="1-setting-up-apollo-client-in-a-vuejs-project">1. Setting Up Apollo Client in a Vue.js Project<a href="https://tailcall.run/blog/graphql-vue-client/#1-setting-up-apollo-client-in-a-vuejs-project" class="hash-link" aria-label="Direct link to 1. Setting Up Apollo Client in a Vue.js Project" title="Direct link to 1. Setting Up Apollo Client in a Vue.js Project">​</a></h3>
<p>Begin by installing the necessary packages:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">npm install @apollo/client @vue/apollo-composable graphql</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="configuration">Configuration<a href="https://tailcall.run/blog/graphql-vue-client/#configuration" class="hash-link" aria-label="Direct link to Configuration" title="Direct link to Configuration">​</a></h4>
<p>Set up Apollo Client in your Vue application:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token comment" style="color:#30C26D;font-style:italic">// src/apollo.ts</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  ApolloClient</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  InMemoryCache</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  createHttpLink</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@apollo/client/core"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> httpLink </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">createHttpLink</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  uri</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"https://your-graphql-endpoint.com/graphql"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">export</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> apolloClient </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">ApolloClient</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  link</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> httpLink</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  cache</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">InMemoryCache</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  defaultOptions</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    watchQuery</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      fetchPolicy</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"cache-and-network"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token comment" style="color:#30C26D;font-style:italic">// main.ts</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">createApp</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> provide</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> h</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"vue"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">DefaultApolloClient</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@vue/apollo-composable"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> App </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"./App.vue"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">apolloClient</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"./apollo"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> app </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">createApp</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token function" style="color:#FDEA2F">setup</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token function" style="color:#FDEA2F">provide</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">DefaultApolloClient</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> apolloClient</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token function-variable function" style="color:#FDEA2F">render</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">h</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">App</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">app</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">mount</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">"#app"</span><span class="token punctuation" style="color:#fff">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This configuration creates an Apollo Client instance with a default in-memory cache and provides it to the entire Vue application.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="2-executing-queries-with-apollo-client">2. Executing Queries with Apollo Client<a href="https://tailcall.run/blog/graphql-vue-client/#2-executing-queries-with-apollo-client" class="hash-link" aria-label="Direct link to 2. Executing Queries with Apollo Client" title="Direct link to 2. Executing Queries with Apollo Client">​</a></h3>
<p>Apollo Client provides the <code>useQuery</code> composable for executing GraphQL queries. Here's an example of fetching a list of posts:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">script</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">setup</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">lang</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">ts</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports punctuation" style="color:#fff">{</span><span class="token script language-javascript imports" style="color:#fff">useQuery</span><span class="token script language-javascript imports punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"@vue/apollo-composable"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports" style="color:#fff">gql</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"graphql-tag"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports punctuation" style="color:#fff">{</span><span class="token script language-javascript imports" style="color:#fff">computed</span><span class="token script language-javascript imports punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"vue"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">interface</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript class-name" style="color:#C586C0">Post</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">id</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> number</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">title</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">body</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">user</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript literal-property property" style="color:#C586C0">name</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript constant" style="color:#C586C0">GET_POSTS</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> gql</span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">    query GetPosts($limit: Int!) {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">      posts(limit: $limit) {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">        id</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">        title</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">        body</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">        user {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">          name</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">        }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">      }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">    }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">  </span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff">result</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> loading</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> error</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> refetch</span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> useQuery</span><span class="token script language-javascript operator" style="color:#8DFFF8">&lt;</span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">posts</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript maybe-class-name" style="color:#fff">Post</span><span class="token script language-javascript punctuation" style="color:#fff">[</span><span class="token script language-javascript punctuation" style="color:#fff">]</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript operator" style="color:#8DFFF8">&gt;</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript constant" style="color:#C586C0">GET_POSTS</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">limit</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript number" style="color:#C586C0">10</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> posts </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">computed</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token script language-javascript" style="color:#fff"> result</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript operator" style="color:#8DFFF8">?.</span><span class="token script language-javascript" style="color:#fff">posts </span><span class="token script language-javascript operator" style="color:#8DFFF8">||</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">[</span><span class="token script language-javascript punctuation" style="color:#fff">]</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function-variable function" style="color:#FDEA2F">fetchPosts</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript function" style="color:#FDEA2F">refetch</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff"></span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">script</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">template</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">button</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">@click</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">fetchPosts</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">:disabled</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">loading</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      Fetch Posts</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">button</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-if</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">loading</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain">Loading...</span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">ul</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-else-if</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">posts.length</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">li</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-for</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">post in posts</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">:key</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">post.id</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        {{ post.title }} by {{ post.user.name }}</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">li</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">ul</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-else-if</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">error</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain">Error: {{ error.message }}</span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">template</span><span class="token tag punctuation" style="color:#fff">&gt;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This example demonstrates:</p>
<ol>
<li>Defining a GraphQL query using <code>gql</code> tag</li>
<li>Using the <code>useQuery</code> composable to manage the query execution</li>
<li>Handling loading, error, and success states</li>
<li>Implementing a refetch mechanism for manual query execution</li>
</ol>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="3-mutations-and-optimistic-updates">3. Mutations and Optimistic Updates<a href="https://tailcall.run/blog/graphql-vue-client/#3-mutations-and-optimistic-updates" class="hash-link" aria-label="Direct link to 3. Mutations and Optimistic Updates" title="Direct link to 3. Mutations and Optimistic Updates">​</a></h3>
<p>Apollo Client supports GraphQL mutations with optimistic updates for responsive UIs:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">script</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">setup</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">lang</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">ts</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports punctuation" style="color:#fff">{</span><span class="token script language-javascript imports" style="color:#fff">useMutation</span><span class="token script language-javascript imports punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"@vue/apollo-composable"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports" style="color:#fff">gql</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"graphql-tag"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports punctuation" style="color:#fff">{</span><span class="token script language-javascript imports" style="color:#fff">ref</span><span class="token script language-javascript imports punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"vue"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript constant" style="color:#C586C0">CREATE_POST</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> gql</span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">    mutation CreatePost($title: String!, $body: String!) {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">      createPost(input: {title: $title, body: $body}) {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">        id</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">        title</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">        body</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">      }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">    }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">  </span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">mutate</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> createPost</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    loading</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    error</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">useMutation</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript constant" style="color:#C586C0">CREATE_POST</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> title </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">ref</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript string" style="color:#FDB869">""</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> body </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">ref</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript string" style="color:#FDB869">""</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function-variable function" style="color:#FDEA2F">submitPost</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword" style="color:#C586C0">async</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">try</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff">data</span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">await</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">createPost</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">          </span><span class="token script language-javascript literal-property property" style="color:#C586C0">title</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> title</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">          </span><span class="token script language-javascript literal-property property" style="color:#C586C0">body</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> body</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">          </span><span class="token script language-javascript literal-property property" style="color:#C586C0">optimisticResponse</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">            </span><span class="token script language-javascript literal-property property" style="color:#C586C0">createPost</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">              </span><span class="token script language-javascript literal-property property" style="color:#C586C0">__typename</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"Post"</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">              </span><span class="token script language-javascript literal-property property" style="color:#C586C0">id</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"temp-id"</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">              </span><span class="token script language-javascript literal-property property" style="color:#C586C0">title</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> title</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">              </span><span class="token script language-javascript literal-property property" style="color:#C586C0">body</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> body</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">            </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">          </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">          </span><span class="token script language-javascript function-variable function" style="color:#FDEA2F">update</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript parameter" style="color:#953800">cache</span><span class="token script language-javascript parameter punctuation" style="color:#fff">,</span><span class="token script language-javascript parameter" style="color:#953800"> </span><span class="token script language-javascript parameter punctuation" style="color:#fff">{</span><span class="token script language-javascript parameter" style="color:#953800">data</span><span class="token script language-javascript parameter punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">            </span><span class="token script language-javascript comment" style="color:#30C26D;font-style:italic">// Update cache logic here</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">          </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript console class-name" style="color:#C586C0">console</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript method function property-access" style="color:#FDEA2F">log</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript string" style="color:#FDB869">"Post created:"</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> data</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">createPost</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript comment" style="color:#30C26D;font-style:italic">// Reset form</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      title</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">""</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      body</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">""</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">catch</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff">e</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript console class-name" style="color:#C586C0">console</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript method function property-access" style="color:#FDEA2F">error</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript string" style="color:#FDB869">"Error creating post:"</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> e</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff"></span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">script</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">template</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">form</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">@submit.prevent</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">submitPost</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">input</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-model</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">title</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">placeholder</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">Title</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">required</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag punctuation" style="color:#fff">/&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">textarea</span><span class="token tag" style="color:#b76b01"></span><br></span><span class="token-line" style="color:#fff"><span class="token tag" style="color:#b76b01">      </span><span class="token tag attr-name" style="color:#8DFFF8">v-model</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">body</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"></span><br></span><span class="token-line" style="color:#fff"><span class="token tag" style="color:#b76b01">      </span><span class="token tag attr-name" style="color:#8DFFF8">placeholder</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">Body</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"></span><br></span><span class="token-line" style="color:#fff"><span class="token tag" style="color:#b76b01">      </span><span class="token tag attr-name" style="color:#8DFFF8">required</span><span class="token tag" style="color:#b76b01"></span><br></span><span class="token-line" style="color:#fff"><span class="token tag" style="color:#b76b01">    </span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">textarea</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">button</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">type</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">submit</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">:disabled</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">loading</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      Create Post</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">button</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-if</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">error</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain">Error: {{ error.message }}</span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">form</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">template</span><span class="token tag punctuation" style="color:#fff">&gt;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This example showcases:</p>
<ol>
<li>Defining a GraphQL mutation</li>
<li>Using the <code>useMutation</code> composable</li>
<li>Implementing optimistic updates for immediate UI feedback</li>
<li>Handling form submission and mutation execution</li>
</ol>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="4-advanced-apollo-client-features">4. Advanced Apollo Client Features<a href="https://tailcall.run/blog/graphql-vue-client/#4-advanced-apollo-client-features" class="hash-link" aria-label="Direct link to 4. Advanced Apollo Client Features" title="Direct link to 4. Advanced Apollo Client Features">​</a></h3>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="caching-and-normalization">Caching and Normalization<a href="https://tailcall.run/blog/graphql-vue-client/#caching-and-normalization" class="hash-link" aria-label="Direct link to Caching and Normalization" title="Direct link to Caching and Normalization">​</a></h3>
<p>Apollo Client's normalized cache is a powerful feature for efficient data management:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">InMemoryCache</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> makeVar</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@apollo/client/core"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">export</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> cache </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">InMemoryCache</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  typePolicies</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    Query</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      fields</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        posts</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token function" style="color:#FDEA2F">merge</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">existing</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> incoming</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> incoming</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    Post</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      fields</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        isLiked</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token function" style="color:#FDEA2F">read</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">likedPostsVar</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">includes</span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">id</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">export</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> likedPostsVar </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token generic-function function" style="color:#FDEA2F">makeVar</span><span class="token generic-function generic class-name operator" style="color:#8DFFF8">&lt;</span><span class="token generic-function generic class-name builtin" style="color:#C586C0">number</span><span class="token generic-function generic class-name punctuation" style="color:#fff">[</span><span class="token generic-function generic class-name punctuation" style="color:#fff">]</span><span class="token generic-function generic class-name operator" style="color:#8DFFF8">&gt;</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">[</span><span class="token punctuation" style="color:#fff">]</span><span class="token punctuation" style="color:#fff">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This setup demonstrates:</p>
<ol>
<li>Custom merge functions for query results</li>
<li>Computed fields based on reactive variables</li>
<li>Using reactive variables for local state management</li>
</ol>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="error-handling-and-retry-logic">Error Handling and Retry Logic<a href="https://tailcall.run/blog/graphql-vue-client/#error-handling-and-retry-logic" class="hash-link" aria-label="Direct link to Error Handling and Retry Logic" title="Direct link to Error Handling and Retry Logic">​</a></h4>
<p>Implement robust error handling and retry logic:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">ApolloLink</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@apollo/client/core"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">onError</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@apollo/client/link/error"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">RetryLink</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@apollo/client/link/retry"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> errorLink </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">onError</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">graphQLErrors</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> networkError</span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">graphQLErrors</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      graphQLErrors</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">forEach</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">message</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> locations</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> path</span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token builtin">console</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">log</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869">[GraphQL error]: Message: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation">message</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string string" style="color:#FDB869">, Location: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation">locations</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string string" style="color:#FDB869">, Path: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation">path</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">networkError</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token builtin">console</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">log</span><span class="token punctuation" style="color:#fff">(</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869">[Network error]: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation">networkError</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> retryLink </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">RetryLink</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  delay</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    initial</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">300</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    max</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">Infinity</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    jitter</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">true</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  attempts</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    max</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">5</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token function-variable function" style="color:#FDEA2F">retryIf</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> _operation</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">!</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> link </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> ApolloLink</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">from</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  errorLink</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  retryLink</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  httpLink</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">]</span><span class="token punctuation" style="color:#fff">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This configuration adds comprehensive error logging and automatic retry for failed requests.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="5-performance-optimization">5. Performance Optimization<a href="https://tailcall.run/blog/graphql-vue-client/#5-performance-optimization" class="hash-link" aria-label="Direct link to 5. Performance Optimization" title="Direct link to 5. Performance Optimization">​</a></h3>
<p>To optimize performance when using Apollo Client with Vue:</p>
<ol>
<li>
<p><strong>Implement pagination</strong> for large datasets:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">script</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">setup</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">lang</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">ts</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports punctuation" style="color:#fff">{</span><span class="token script language-javascript imports" style="color:#fff">useQuery</span><span class="token script language-javascript imports punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"@vue/apollo-composable"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports" style="color:#fff">gql</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"graphql-tag"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports punctuation" style="color:#fff">{</span><span class="token script language-javascript imports" style="color:#fff">ref</span><span class="token script language-javascript imports punctuation" style="color:#fff">,</span><span class="token script language-javascript imports" style="color:#fff"> computed</span><span class="token script language-javascript imports punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"vue"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript constant" style="color:#C586C0">GET_POSTS</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> gql</span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">    query GetPosts($offset: Int!, $limit: Int!) {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">      posts(offset: $offset, limit: $limit) {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">        id</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">        title</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">      }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">    }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string embedded-code graphql" style="color:#fff">  </span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> limit </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">ref</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript number" style="color:#C586C0">10</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> offset </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">ref</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript number" style="color:#C586C0">0</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff">result</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> loading</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> fetchMore</span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">useQuery</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript constant" style="color:#C586C0">GET_POSTS</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript literal-property property" style="color:#C586C0">offset</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> offset</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript literal-property property" style="color:#C586C0">limit</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> limit</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> posts </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">computed</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token script language-javascript" style="color:#fff"> result</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript operator" style="color:#8DFFF8">?.</span><span class="token script language-javascript" style="color:#fff">posts </span><span class="token script language-javascript operator" style="color:#8DFFF8">||</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">[</span><span class="token script language-javascript punctuation" style="color:#fff">]</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function-variable function" style="color:#FDEA2F">loadMore</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    offset</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">+=</span><span class="token script language-javascript" style="color:#fff"> limit</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript function" style="color:#FDEA2F">fetchMore</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript literal-property property" style="color:#C586C0">variables</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        </span><span class="token script language-javascript literal-property property" style="color:#C586C0">offset</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> offset</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        </span><span class="token script language-javascript literal-property property" style="color:#C586C0">limit</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> limit</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff"></span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">script</span><span class="token tag punctuation" style="color:#fff">&gt;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
</li>
<li>
<p><strong>Use fragments</strong> for reusable query parts:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> gql </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"graphql-tag"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">export</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> </span><span class="token constant" style="color:#C586C0">POST_FRAGMENT</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> gql</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">  </span><span class="token template-string graphql language-graphql keyword" style="color:#C586C0">fragment</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql fragment function" style="color:#FDEA2F">PostDetails</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql keyword" style="color:#C586C0">on</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql class-name" style="color:#C586C0">Post</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">{</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">    </span><span class="token template-string graphql language-graphql property" style="color:#C586C0">id</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">    </span><span class="token template-string graphql language-graphql property" style="color:#C586C0">title</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">    </span><span class="token template-string graphql language-graphql property" style="color:#C586C0">body</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">    </span><span class="token template-string graphql language-graphql property" style="color:#C586C0">createdAt</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">  </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">}</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql"></span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">export</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> </span><span class="token constant" style="color:#C586C0">GET_POSTS</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> gql</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">  </span><span class="token template-string graphql language-graphql property interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string graphql language-graphql property interpolation constant" style="color:#C586C0">POST_FRAGMENT</span><span class="token template-string graphql language-graphql property interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">  </span><span class="token template-string graphql language-graphql keyword" style="color:#C586C0">query</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql definition-query function" style="color:#FDEA2F">GetPosts</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">{</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">    </span><span class="token template-string graphql language-graphql object">posts</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">{</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">      </span><span class="token template-string graphql language-graphql operator" style="color:#8DFFF8">...</span><span class="token template-string graphql language-graphql fragment function" style="color:#FDEA2F">PostDetails</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">    </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">}</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">  </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">}</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql"></span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
</li>
<li>
<p><strong>Leverage Apollo Client DevTools</strong> for performance monitoring and cache inspection.</p>
</li>
</ol>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion">Conclusion<a href="https://tailcall.run/blog/graphql-vue-client/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h3>
<p>Apollo Client provides a powerful and flexible solution for integrating GraphQL into Vue.js applications. Its advanced features like normalized caching, optimistic updates, and comprehensive error handling make it an excellent choice for complex, data-intensive applications.</p>
<p>Key takeaways:</p>
<ul>
<li>Apollo Client offers a robust caching system that optimizes data fetching and management</li>
<li>The <code>useQuery</code> and <code>useMutation</code> composables provide a clean API for GraphQL operations</li>
<li>Optimistic updates enable responsive UIs even before server responses</li>
<li>Advanced features like custom cache policies and reactive variables offer fine-grained control over data management</li>
<li>Performance optimization techniques such as pagination and fragments are crucial for scalable applications</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="urql---a-lightweight-graphql-client-for-modern-web-development">URQL - A Lightweight GraphQL Client for Modern Web Development<a href="https://tailcall.run/blog/graphql-vue-client/#urql---a-lightweight-graphql-client-for-modern-web-development" class="hash-link" aria-label="Direct link to URQL - A Lightweight GraphQL Client for Modern Web Development" title="Direct link to URQL - A Lightweight GraphQL Client for Modern Web Development">​</a></h2>
<p>URQL stands out for its simplicity and modularity, making it an excellent choice for Vue.js projects that require GraphQL integration without the overhead of more complex libraries. Its lightweight nature contributes to faster load times and improved performance, especially in resource-constrained environments.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="key-features-of-urql">Key Features of URQL:<a href="https://tailcall.run/blog/graphql-vue-client/#key-features-of-urql" class="hash-link" aria-label="Direct link to Key Features of URQL:" title="Direct link to Key Features of URQL:">​</a></h3>
<ul>
<li>Minimal bundle size</li>
<li>Built-in cache and normalized caching option</li>
<li>Easy to extend with custom exchanges</li>
<li>First-class TypeScript support</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="2-setting-up-urql-in-a-vuejs-project">2. Setting Up URQL in a Vue.js Project<a href="https://tailcall.run/blog/graphql-vue-client/#2-setting-up-urql-in-a-vuejs-project" class="hash-link" aria-label="Direct link to 2. Setting Up URQL in a Vue.js Project" title="Direct link to 2. Setting Up URQL in a Vue.js Project">​</a></h3>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="installation">Installation<a href="https://tailcall.run/blog/graphql-vue-client/#installation" class="hash-link" aria-label="Direct link to Installation" title="Direct link to Installation">​</a></h4>
<p>Begin by installing URQL and its Vue integration:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">npm install @urql/vue graphql</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="configuration-1">Configuration<a href="https://tailcall.run/blog/graphql-vue-client/#configuration-1" class="hash-link" aria-label="Direct link to Configuration" title="Direct link to Configuration">​</a></h4>
<p>Set up the URQL client in your Vue application:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">createApp</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"vue"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> urql</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">createClient</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@urql/vue"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> App </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"./App.vue"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> client </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">createClient</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  url</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"https://your-graphql-endpoint.com/graphql"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> app </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">createApp</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">App</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">app</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">use</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">urql</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> client</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">app</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">mount</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">"#app"</span><span class="token punctuation" style="color:#fff">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This configuration creates an URQL client and integrates it with Vue's plugin system, making it available throughout your application.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="3-executing-queries-with-urql">3. Executing Queries with URQL<a href="https://tailcall.run/blog/graphql-vue-client/#3-executing-queries-with-urql" class="hash-link" aria-label="Direct link to 3. Executing Queries with URQL" title="Direct link to 3. Executing Queries with URQL">​</a></h3>
<p>URQL provides a <code>useQuery</code> composable for executing GraphQL queries. Here's an example of fetching a list of posts:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">script</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">setup</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">lang</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">ts</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports punctuation" style="color:#fff">{</span><span class="token script language-javascript imports" style="color:#fff">useQuery</span><span class="token script language-javascript imports punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"@urql/vue"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports punctuation" style="color:#fff">{</span><span class="token script language-javascript imports" style="color:#fff">ref</span><span class="token script language-javascript imports punctuation" style="color:#fff">,</span><span class="token script language-javascript imports" style="color:#fff"> watch</span><span class="token script language-javascript imports punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"vue"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> postsQuery </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript template-string string" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">  query GetPosts {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">    posts {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">      id</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">      title</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">      body</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">      user {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">        name</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">      }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">    }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">  }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869"></span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff">executeQuery</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> fetching</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> error</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> data</span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">useQuery</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">query</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> postsQuery</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">pause</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript boolean" style="color:#C586C0">true</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript comment" style="color:#30C26D;font-style:italic">// Start paused to allow manual execution</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> posts </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">ref</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">[</span><span class="token script language-javascript punctuation" style="color:#fff">]</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function-variable function" style="color:#FDEA2F">fetchPosts</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript function" style="color:#FDEA2F">executeQuery</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript function" style="color:#FDEA2F">watch</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff">data</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript parameter" style="color:#953800">newData</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">if</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff">newData</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      posts</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> newData</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">posts</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff"></span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">script</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">template</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">button</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">@click</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">fetchPosts</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">:disabled</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">fetching</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      Fetch Posts</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">button</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-if</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">fetching</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain">Loading...</span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">ul</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-else-if</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">posts.length</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">li</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-for</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">post in posts</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">:key</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">post.id</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        {{ post.title }} by {{ post.user.name }}</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">li</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">ul</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-else-if</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">error</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain">Error: {{ error.message }}</span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">template</span><span class="token tag punctuation" style="color:#fff">&gt;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This example demonstrates how to:</p>
<ol>
<li>Define a GraphQL query</li>
<li>Use the <code>useQuery</code> composable to manage the query execution</li>
<li>Handle loading, error, and success states</li>
<li>Manually trigger the query execution</li>
</ol>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="4-mutations-and-state-updates">4. Mutations and State Updates<a href="https://tailcall.run/blog/graphql-vue-client/#4-mutations-and-state-updates" class="hash-link" aria-label="Direct link to 4. Mutations and State Updates" title="Direct link to 4. Mutations and State Updates">​</a></h3>
<p>URQL also supports GraphQL mutations for modifying data. Here's an example of creating a new post:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">script</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">setup</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">lang</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">ts</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports punctuation" style="color:#fff">{</span><span class="token script language-javascript imports" style="color:#fff">useMutation</span><span class="token script language-javascript imports punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"@urql/vue"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports punctuation" style="color:#fff">{</span><span class="token script language-javascript imports" style="color:#fff">ref</span><span class="token script language-javascript imports punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"vue"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> createPostMutation </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript template-string string" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">  mutation CreatePost($title: String!, $body: String!) {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">    createPost(input: { title: $title, body: $body }) {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">      id</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">      title</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">      body</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">    }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">  }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869"></span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff">executeMutation</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> fetching</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> error</span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">useMutation</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    createPostMutation</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> title </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">ref</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript string" style="color:#FDB869">""</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> body </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">ref</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript string" style="color:#FDB869">""</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function-variable function" style="color:#FDEA2F">createPost</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword" style="color:#C586C0">async</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> result </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">await</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">executeMutation</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript literal-property property" style="color:#C586C0">title</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> title</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript literal-property property" style="color:#C586C0">body</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> body</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">if</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff">result</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">data</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript console class-name" style="color:#C586C0">console</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript method function property-access" style="color:#FDEA2F">log</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript string" style="color:#FDB869">"Post created:"</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> result</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">data</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">createPost</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript comment" style="color:#30C26D;font-style:italic">// Reset form or update local state</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      title</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">""</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      body</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">""</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff"></span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">script</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">template</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">form</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">@submit.prevent</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">createPost</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">input</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-model</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">title</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">placeholder</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">Title</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">required</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag punctuation" style="color:#fff">/&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">textarea</span><span class="token tag" style="color:#b76b01"></span><br></span><span class="token-line" style="color:#fff"><span class="token tag" style="color:#b76b01">      </span><span class="token tag attr-name" style="color:#8DFFF8">v-model</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">body</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"></span><br></span><span class="token-line" style="color:#fff"><span class="token tag" style="color:#b76b01">      </span><span class="token tag attr-name" style="color:#8DFFF8">placeholder</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">Body</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"></span><br></span><span class="token-line" style="color:#fff"><span class="token tag" style="color:#b76b01">      </span><span class="token tag attr-name" style="color:#8DFFF8">required</span><span class="token tag" style="color:#b76b01"></span><br></span><span class="token-line" style="color:#fff"><span class="token tag" style="color:#b76b01">    </span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">textarea</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">button</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">type</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">submit</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">:disabled</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">fetching</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      Create Post</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">button</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-if</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">error</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain">Error: {{ error.message }}</span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">form</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">template</span><span class="token tag punctuation" style="color:#fff">&gt;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This example showcases:</p>
<ol>
<li>Defining a GraphQL mutation</li>
<li>Using the <code>useMutation</code> composable</li>
<li>Handling form submission and mutation execution</li>
<li>Managing loading and error states for the mutation</li>
</ol>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="5-advanced-urql-features-and-best-practices">5. Advanced URQL Features and Best Practices<a href="https://tailcall.run/blog/graphql-vue-client/#5-advanced-urql-features-and-best-practices" class="hash-link" aria-label="Direct link to 5. Advanced URQL Features and Best Practices" title="Direct link to 5. Advanced URQL Features and Best Practices">​</a></h3>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="caching-and-normalization-1">Caching and Normalization<a href="https://tailcall.run/blog/graphql-vue-client/#caching-and-normalization-1" class="hash-link" aria-label="Direct link to Caching and Normalization" title="Direct link to Caching and Normalization">​</a></h4>
<p>URQL provides a document cache by default, but for more complex applications, you might want to use the normalized cache:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  createClient</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  dedupExchange</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  cacheExchange</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  fetchExchange</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@urql/vue"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">normalizedCache</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@urql/exchange-graphcache"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> client </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">createClient</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  url</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"https://your-graphql-endpoint.com/graphql"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  exchanges</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    dedupExchange</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token function" style="color:#FDEA2F">normalizedCache</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      keys</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token function-variable function" style="color:#FDEA2F">Post</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">data</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> data</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">id</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      resolvers</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        Query</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token function-variable function" style="color:#FDEA2F">post</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">_</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> args</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            __typename</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"Post"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            id</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> args</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">id</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    fetchExchange</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">]</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This setup enables more efficient caching and automatic updates for related queries when mutations occur.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="error-handling-and-retry-logic-1">Error Handling and Retry Logic<a href="https://tailcall.run/blog/graphql-vue-client/#error-handling-and-retry-logic-1" class="hash-link" aria-label="Direct link to Error Handling and Retry Logic" title="Direct link to Error Handling and Retry Logic">​</a></h4>
<p>Implement robust error handling and retry logic:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">retry</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@urql/exchange-retry"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> client </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">createClient</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic">// ... other configuration</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  exchanges</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    dedupExchange</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    cacheExchange</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token function" style="color:#FDEA2F">retry</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token function-variable function" style="color:#FDEA2F">retryIf</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token operator" style="color:#8DFFF8">!</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">networkError </span><span class="token operator" style="color:#8DFFF8">||</span><span class="token plain"> error</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">graphQLErrors</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      maxNumberAttempts</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">3</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    fetchExchange</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">]</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This configuration adds automatic retry for network errors or GraphQL errors, improving the resilience of your application.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="6-performance-optimization">6. Performance Optimization<a href="https://tailcall.run/blog/graphql-vue-client/#6-performance-optimization" class="hash-link" aria-label="Direct link to 6. Performance Optimization" title="Direct link to 6. Performance Optimization">​</a></h3>
<p>To optimize performance when using URQL with Vue:</p>
<ol>
<li>
<p><strong>Leverage server-side rendering (SSR)</strong> for initial data loading:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">createClient</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> ssrExchange</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@urql/vue"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> ssr </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">ssrExchange</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  isClient</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">typeof</span><span class="token plain"> window </span><span class="token operator" style="color:#8DFFF8">!==</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"undefined"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> client </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">createClient</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  url</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"https://your-graphql-endpoint.com/graphql"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  exchanges</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    dedupExchange</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    cacheExchange</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    ssr</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    fetchExchange</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">]</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
</li>
<li>
<p><strong>Implement pagination</strong> for large datasets:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">script</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">setup</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">lang</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">ts</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports punctuation" style="color:#fff">{</span><span class="token script language-javascript imports" style="color:#fff">useQuery</span><span class="token script language-javascript imports punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"@urql/vue"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports punctuation" style="color:#fff">{</span><span class="token script language-javascript imports" style="color:#fff">ref</span><span class="token script language-javascript imports punctuation" style="color:#fff">,</span><span class="token script language-javascript imports" style="color:#fff"> computed</span><span class="token script language-javascript imports punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"vue"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> postsQuery </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript template-string string" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">  query GetPosts($limit: Int!, $offset: Int!) {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">    posts(limit: $limit, offset: $offset) {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">      id</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">      title</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">    }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">  }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869"></span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> limit </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">ref</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript number" style="color:#C586C0">10</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> offset </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">ref</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript number" style="color:#C586C0">0</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff">data</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> fetching</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> error</span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">useQuery</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">query</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> postsQuery</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">variables</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">computed</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript literal-property property" style="color:#C586C0">limit</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> limit</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript literal-property property" style="color:#C586C0">offset</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> offset</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function-variable function" style="color:#FDEA2F">loadMore</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    offset</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">+=</span><span class="token script language-javascript" style="color:#fff"> limit</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff"></span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">script</span><span class="token tag punctuation" style="color:#fff">&gt;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
</li>
<li>
<p><strong>Use fragments</strong> for reusable query parts:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> PostFragment </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">  fragment PostDetails on Post {</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    id</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    title</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    body</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    createdAt</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">  }</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869"></span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> postsQuery </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">  </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation">PostFragment</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string string" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">  query GetPosts {</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    posts {</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      ...PostDetails</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    }</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">  }</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869"></span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
</li>
</ol>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion-1">Conclusion<a href="https://tailcall.run/blog/graphql-vue-client/#conclusion-1" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h3>
<p>URQL provides a lightweight yet powerful solution for integrating GraphQL into Vue.js applications. Its simplicity, coupled with advanced features like normalized caching and SSR support, makes it an excellent choice for developers seeking efficiency and flexibility. By following the best practices and optimization techniques outlined in this tutorial, you can build performant, scalable Vue applications with GraphQL.</p>
<p>Key takeaways:</p>
<ul>
<li>URQL offers a minimal bundle size and easy integration with Vue.js</li>
<li>The <code>useQuery</code> and <code>useMutation</code> composables provide a clean API for GraphQL operations</li>
<li>Advanced features like normalized caching and SSR support enhance application performance</li>
<li>Proper error handling and retry logic improve application resilience</li>
<li>Performance optimization techniques such as pagination and fragments are crucial for scalable applications</li>
</ul>
<p>As you implement URQL in your Vue projects, remember to stay updated with the latest developments in both URQL and the GraphQL ecosystem to leverage new features and best practices as they emerge.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="fetch-api---the-diy-dynamo">Fetch API - The DIY Dynamo<a href="https://tailcall.run/blog/graphql-vue-client/#fetch-api---the-diy-dynamo" class="hash-link" aria-label="Direct link to Fetch API - The DIY Dynamo" title="Direct link to Fetch API - The DIY Dynamo">​</a></h2>
<p>In modern web development, effective data fetching is a cornerstone for building dynamic and responsive applications. While powerful libraries like Apollo and URQL offer extensive features for GraphQL integration, there are situations where a more hands-on approach is desirable. Enter the Fetch API: a versatile, built-in tool for making network requests, allowing developers to craft their GraphQL interactions from the ground up. This tutorial will guide you through using the Fetch API for GraphQL data fetching in Vue.js, providing a deep understanding of the process and its practical applications.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-by-step-instructions">Step-by-Step Instructions<a href="https://tailcall.run/blog/graphql-vue-client/#step-by-step-instructions" class="hash-link" aria-label="Direct link to Step-by-Step Instructions" title="Direct link to Step-by-Step Instructions">​</a></h3>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="installation-and-integration-steps">Installation and Integration Steps<a href="https://tailcall.run/blog/graphql-vue-client/#installation-and-integration-steps" class="hash-link" aria-label="Direct link to Installation and Integration Steps" title="Direct link to Installation and Integration Steps">​</a></h4>
<p>One of the key advantages of the Fetch API is its built-in availability in modern browsers. This means no additional package installations are required, simplifying the setup process.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="code-snippets">Code Snippets<a href="https://tailcall.run/blog/graphql-vue-client/#code-snippets" class="hash-link" aria-label="Direct link to Code Snippets" title="Direct link to Code Snippets">​</a></h4>
<p>Let's start by setting up a basic Vue component that uses the Fetch API to query a GraphQL endpoint.</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">template</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">fetch-example</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">h2</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain">Fetch API Example</span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">h2</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">button</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">@click</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">fetchPosts</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">:disabled</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">loading</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      Fetch Posts</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">button</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-if</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">networkError</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">error</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      Network Error: {{ networkError }}</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-if</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">graphqlError</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">error</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      GraphQL Error: {{ graphqlError }}</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-if</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">unexpectedError</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">error</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      Unexpected Error: {{ unexpectedError }}</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">ul</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">li</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-for</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">post in posts</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">:key</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">post.id</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        {{ post.title }} by {{ post.user.name }}</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">li</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">ul</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">template</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">script</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">setup</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">lang</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">ts</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports punctuation" style="color:#fff">{</span><span class="token script language-javascript imports" style="color:#fff">ref</span><span class="token script language-javascript imports punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"vue"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">interface</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript class-name" style="color:#C586C0">Post</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">id</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> number</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">title</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">body</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">user</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript literal-property property" style="color:#C586C0">name</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> posts </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> ref</span><span class="token script language-javascript operator" style="color:#8DFFF8">&lt;</span><span class="token script language-javascript maybe-class-name" style="color:#fff">Post</span><span class="token script language-javascript punctuation" style="color:#fff">[</span><span class="token script language-javascript punctuation" style="color:#fff">]</span><span class="token script language-javascript operator" style="color:#8DFFF8">&gt;</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">[</span><span class="token script language-javascript punctuation" style="color:#fff">]</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> loading </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">ref</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript boolean" style="color:#C586C0">false</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> networkError </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> ref</span><span class="token script language-javascript operator" style="color:#8DFFF8">&lt;</span><span class="token script language-javascript" style="color:#fff">string </span><span class="token script language-javascript operator" style="color:#8DFFF8">|</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript operator" style="color:#8DFFF8">&gt;</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> graphqlError </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> ref</span><span class="token script language-javascript operator" style="color:#8DFFF8">&lt;</span><span class="token script language-javascript" style="color:#fff">string </span><span class="token script language-javascript operator" style="color:#8DFFF8">|</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript operator" style="color:#8DFFF8">&gt;</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> unexpectedError </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> ref</span><span class="token script language-javascript operator" style="color:#8DFFF8">&lt;</span><span class="token script language-javascript" style="color:#fff">string </span><span class="token script language-javascript operator" style="color:#8DFFF8">|</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript operator" style="color:#8DFFF8">&gt;</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function-variable function" style="color:#FDEA2F">fetchPosts</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword" style="color:#C586C0">async</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    loading</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript boolean" style="color:#C586C0">true</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    networkError</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    graphqlError</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    unexpectedError</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">try</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> response </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">await</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">fetch</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript string" style="color:#FDB869">"/graphql"</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        </span><span class="token script language-javascript literal-property property" style="color:#C586C0">method</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"POST"</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        </span><span class="token script language-javascript literal-property property" style="color:#C586C0">headers</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript string-property property" style="color:#C586C0">"Content-Type"</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"application/json"</span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        </span><span class="token script language-javascript literal-property property" style="color:#C586C0">body</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript known-class-name class-name" style="color:#C586C0">JSON</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript method function property-access" style="color:#FDEA2F">stringify</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">          </span><span class="token script language-javascript literal-property property" style="color:#C586C0">query</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript template-string string" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">        query GetPosts {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">          posts {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">            id</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">            title</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">            body</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">            user {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">              name</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">            }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">          }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">        }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">      </span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">if</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript operator" style="color:#8DFFF8">!</span><span class="token script language-javascript" style="color:#fff">response</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">ok</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">throw</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword" style="color:#C586C0">new</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript class-name" style="color:#C586C0">Error</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">          </span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript template-string string" style="color:#FDB869">HTTP error! status: </span><span class="token script language-javascript template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token script language-javascript template-string interpolation" style="color:#fff">response</span><span class="token script language-javascript template-string interpolation punctuation" style="color:#fff">.</span><span class="token script language-javascript template-string interpolation property-access" style="color:#fff">status</span><span class="token script language-javascript template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        </span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> result </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">await</span><span class="token script language-javascript" style="color:#fff"> response</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript method function property-access" style="color:#FDEA2F">json</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">if</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff">result</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">errors</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">&amp;&amp;</span><span class="token script language-javascript" style="color:#fff"> result</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">errors</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">length</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">&gt;</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript number" style="color:#C586C0">0</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        graphqlError</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> result</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">errors</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">          </span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript method function property-access" style="color:#FDEA2F">map</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript parameter literal-property property" style="color:#C586C0">e</span><span class="token script language-javascript parameter operator" style="color:#8DFFF8">:</span><span class="token script language-javascript parameter" style="color:#953800"> any</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token script language-javascript" style="color:#fff"> e</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">message</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">          </span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript method function property-access" style="color:#FDEA2F">join</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript string" style="color:#FDB869">", "</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">else</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        posts</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> result</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">data</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">posts</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript method function property-access" style="color:#FDEA2F">slice</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript number" style="color:#C586C0">0</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript number" style="color:#C586C0">4</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">catch</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff">err</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> any</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">if</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff">err</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">message</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript method function property-access" style="color:#FDEA2F">startsWith</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript string" style="color:#FDB869">"HTTP error!"</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        networkError</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> err</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">message</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">else</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        unexpectedError</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> err</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">message</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">finally</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      loading</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript boolean" style="color:#C586C0">false</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff"></span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">script</span><span class="token tag punctuation" style="color:#fff">&gt;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="error-handling">Error Handling<a href="https://tailcall.run/blog/graphql-vue-client/#error-handling" class="hash-link" aria-label="Direct link to Error Handling" title="Direct link to Error Handling">​</a></h4>
<p>Handling errors effectively is crucial in any data-fetching scenario. The above code includes a robust error-handling system that categorizes errors into network errors, GraphQL errors, and unexpected errors.</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">try</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic">// ... fetch logic ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">err</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">message</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">startsWith</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">"HTTP error!"</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    networkError</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">value </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> err</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">message</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    unexpectedError</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">value </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> err</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">message</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">finally</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  loading</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">value </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This approach ensures that your application can gracefully handle and display errors, enhancing user experience.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="industry-best-practices-and-potential-technical-challenges">Industry Best Practices and Potential Technical Challenges<a href="https://tailcall.run/blog/graphql-vue-client/#industry-best-practices-and-potential-technical-challenges" class="hash-link" aria-label="Direct link to Industry Best Practices and Potential Technical Challenges" title="Direct link to Industry Best Practices and Potential Technical Challenges">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="best-practices">Best Practices<a href="https://tailcall.run/blog/graphql-vue-client/#best-practices" class="hash-link" aria-label="Direct link to Best Practices" title="Direct link to Best Practices">​</a></h3>
<ol>
<li><strong>Modular Code</strong>: Break down your Fetch API logic into reusable functions or composables to promote code reusability and maintainability.</li>
<li><strong>Error Handling</strong>: Implement comprehensive error handling to manage different types of errors (network, GraphQL, unexpected) effectively.</li>
<li><strong>Security</strong>: Always validate and sanitize input data, especially when constructing GraphQL queries dynamically.</li>
</ol>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="technical-challenges">Technical Challenges<a href="https://tailcall.run/blog/graphql-vue-client/#technical-challenges" class="hash-link" aria-label="Direct link to Technical Challenges" title="Direct link to Technical Challenges">​</a></h3>
<ol>
<li><strong>Verbose Error Handling</strong>: Handling errors manually can be verbose and requires meticulous coding to cover all edge cases.</li>
<li><strong>Scalability</strong>: For larger projects, the Fetch API might lack the convenience features offered by dedicated GraphQL clients, such as caching and automatic batching.</li>
<li><strong>State Management</strong>: Managing loading states and errors can become complex, especially as the application grows.</li>
</ol>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="real-world-applications">Real-World Applications<a href="https://tailcall.run/blog/graphql-vue-client/#real-world-applications" class="hash-link" aria-label="Direct link to Real-World Applications" title="Direct link to Real-World Applications">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="professional-development-scenarios">Professional Development Scenarios<a href="https://tailcall.run/blog/graphql-vue-client/#professional-development-scenarios" class="hash-link" aria-label="Direct link to Professional Development Scenarios" title="Direct link to Professional Development Scenarios">​</a></h3>
<ol>
<li><strong>Custom Solutions</strong>: In scenarios where fine-grained control over GraphQL requests is needed, such as specific headers or request configurations, the Fetch API shines.</li>
<li><strong>Learning and Prototyping</strong>: Using the Fetch API is a great way to learn the basics of GraphQL and network requests, making it suitable for educational purposes and prototyping.</li>
<li><strong>Lightweight Applications</strong>: For smaller applications or micro-frontends where adding a full-fledged GraphQL client is overkill, the Fetch API provides a lightweight alternative.</li>
</ol>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="comparison-to-alternative-technologies">Comparison to Alternative Technologies<a href="https://tailcall.run/blog/graphql-vue-client/#comparison-to-alternative-technologies" class="hash-link" aria-label="Direct link to Comparison to Alternative Technologies" title="Direct link to Comparison to Alternative Technologies">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="apollo-client">Apollo Client<a href="https://tailcall.run/blog/graphql-vue-client/#apollo-client" class="hash-link" aria-label="Direct link to Apollo Client" title="Direct link to Apollo Client">​</a></h3>
<ul>
<li><strong>Pros</strong>: Robust, feature-rich, automatic caching, extensive community support.</li>
<li><strong>Cons</strong>: Heavier bundle size, additional dependencies, potentially overkill for simple use cases.</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="urql">URQL<a href="https://tailcall.run/blog/graphql-vue-client/#urql" class="hash-link" aria-label="Direct link to URQL" title="Direct link to URQL">​</a></h3>
<ul>
<li><strong>Pros</strong>: Lightweight, flexible, built-in support for common GraphQL patterns.</li>
<li><strong>Cons</strong>: Less mature than Apollo, fewer built-in features.</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="axios">Axios<a href="https://tailcall.run/blog/graphql-vue-client/#axios" class="hash-link" aria-label="Direct link to Axios" title="Direct link to Axios">​</a></h3>
<ul>
<li><strong>Pros</strong>: Versatile HTTP client, can be used with GraphQL, additional features like request cancellation.</li>
<li><strong>Cons</strong>: Requires additional configuration for GraphQL, less intuitive compared to dedicated GraphQL clients.</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="summary-of-key-technical-insights">Summary of Key Technical Insights<a href="https://tailcall.run/blog/graphql-vue-client/#summary-of-key-technical-insights" class="hash-link" aria-label="Direct link to Summary of Key Technical Insights" title="Direct link to Summary of Key Technical Insights">​</a></h2>
<ol>
<li><strong>Control and Flexibility</strong>: The Fetch API offers unmatched control over GraphQL requests, making it ideal for custom solutions.</li>
<li><strong>Built-In Availability</strong>: No need for additional dependencies, simplifying the development and deployment process.</li>
<li><strong>Error Handling</strong>: Robust error handling is crucial to manage different types of errors effectively.</li>
<li><strong>Learning Opportunity</strong>: Using the Fetch API provides a deeper understanding of GraphQL and network requests, beneficial for both entry-level and intermediate developers.</li>
</ol>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion-2">Conclusion<a href="https://tailcall.run/blog/graphql-vue-client/#conclusion-2" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>The Fetch API serves as a powerful tool for developers looking to craft their GraphQL solutions with precision and control. While it may not offer the convenience and features of dedicated GraphQL clients, it provides a lightweight and versatile alternative. By following best practices and understanding potential challenges, developers can effectively leverage the Fetch API for various professional development scenarios, gaining valuable insights and experience in the process.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="axios---the-smooth-operator">Axios - The Smooth Operator<a href="https://tailcall.run/blog/graphql-vue-client/#axios---the-smooth-operator" class="hash-link" aria-label="Direct link to Axios - The Smooth Operator" title="Direct link to Axios - The Smooth Operator">​</a></h2>
<p>In the world of HTTP clients, Axios is like a sous chef in your kitchen, handling the tedious tasks and ensuring your GraphQL requests are prepared with finesse. Unlike the Fetch API, Axios simplifies and streamlines data fetching, making it an attractive option for developers seeking efficiency without sacrificing control. Let's dive into how Axios can enhance your Vue.js application with smooth and efficient GraphQL data fetching.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="1-installation-and-integration-steps">1. Installation and Integration Steps<a href="https://tailcall.run/blog/graphql-vue-client/#1-installation-and-integration-steps" class="hash-link" aria-label="Direct link to 1. Installation and Integration Steps" title="Direct link to 1. Installation and Integration Steps">​</a></h3>
<p>First, we need to install Axios in our Vue project. This can be done quickly via npm:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">npm install axios</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>That's it! Axios is now ready to use, providing a smooth and easy setup process.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="2-code-snippets">2. Code Snippets<a href="https://tailcall.run/blog/graphql-vue-client/#2-code-snippets" class="hash-link" aria-label="Direct link to 2. Code Snippets" title="Direct link to 2. Code Snippets">​</a></h3>
<p>Here's how you can use Axios to fetch data from a GraphQL endpoint in a Vue component:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">script</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">setup</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">lang</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">ts</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports punctuation" style="color:#fff">{</span><span class="token script language-javascript imports" style="color:#fff">ref</span><span class="token script language-javascript imports punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"vue"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports" style="color:#fff">axios</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"axios"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">interface</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript class-name" style="color:#C586C0">Post</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">id</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> number</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">title</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">body</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">user</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript literal-property property" style="color:#C586C0">name</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> posts </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> ref</span><span class="token script language-javascript operator" style="color:#8DFFF8">&lt;</span><span class="token script language-javascript maybe-class-name" style="color:#fff">Post</span><span class="token script language-javascript punctuation" style="color:#fff">[</span><span class="token script language-javascript punctuation" style="color:#fff">]</span><span class="token script language-javascript operator" style="color:#8DFFF8">&gt;</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">[</span><span class="token script language-javascript punctuation" style="color:#fff">]</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> loading </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">ref</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript boolean" style="color:#C586C0">false</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> networkError </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> ref</span><span class="token script language-javascript operator" style="color:#8DFFF8">&lt;</span><span class="token script language-javascript" style="color:#fff">string </span><span class="token script language-javascript operator" style="color:#8DFFF8">|</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript operator" style="color:#8DFFF8">&gt;</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> graphqlError </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> ref</span><span class="token script language-javascript operator" style="color:#8DFFF8">&lt;</span><span class="token script language-javascript" style="color:#fff">string </span><span class="token script language-javascript operator" style="color:#8DFFF8">|</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript operator" style="color:#8DFFF8">&gt;</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> unexpectedError </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> ref</span><span class="token script language-javascript operator" style="color:#8DFFF8">&lt;</span><span class="token script language-javascript" style="color:#fff">string </span><span class="token script language-javascript operator" style="color:#8DFFF8">|</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript operator" style="color:#8DFFF8">&gt;</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function-variable function" style="color:#FDEA2F">fetchPosts</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword" style="color:#C586C0">async</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    loading</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript boolean" style="color:#C586C0">true</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    networkError</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    graphqlError</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    unexpectedError</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">try</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> response </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">await</span><span class="token script language-javascript" style="color:#fff"> axios</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript method function property-access" style="color:#FDEA2F">post</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript string" style="color:#FDB869">"/graphql"</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        </span><span class="token script language-javascript literal-property property" style="color:#C586C0">query</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript template-string string" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">        query GetPosts {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">          posts {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">            id</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">            title</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">            body</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">            user {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">              name</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">            }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">          }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">        }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">      </span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">if</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff">response</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">status</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">!==</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript number" style="color:#C586C0">200</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">throw</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword" style="color:#C586C0">new</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript class-name" style="color:#C586C0">Error</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">          </span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript template-string string" style="color:#FDB869">HTTP error! status: </span><span class="token script language-javascript template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token script language-javascript template-string interpolation" style="color:#fff">response</span><span class="token script language-javascript template-string interpolation punctuation" style="color:#fff">.</span><span class="token script language-javascript template-string interpolation property-access" style="color:#fff">status</span><span class="token script language-javascript template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        </span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> result </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> response</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">data</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">if</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff">result</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">errors</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">&amp;&amp;</span><span class="token script language-javascript" style="color:#fff"> result</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">errors</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">length</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">&gt;</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript number" style="color:#C586C0">0</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        graphqlError</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> result</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">errors</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">          </span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript method function property-access" style="color:#FDEA2F">map</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript parameter literal-property property" style="color:#C586C0">e</span><span class="token script language-javascript parameter operator" style="color:#8DFFF8">:</span><span class="token script language-javascript parameter" style="color:#953800"> any</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token script language-javascript" style="color:#fff"> e</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">message</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">          </span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript method function property-access" style="color:#FDEA2F">join</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript string" style="color:#FDB869">", "</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">else</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        posts</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> result</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">data</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">posts</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript method function property-access" style="color:#FDEA2F">slice</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript number" style="color:#C586C0">0</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript number" style="color:#C586C0">4</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">catch</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff">err</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> any</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">if</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff">err</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">response</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        networkError</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript template-string string" style="color:#FDB869">HTTP error! status: </span><span class="token script language-javascript template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token script language-javascript template-string interpolation" style="color:#fff">err</span><span class="token script language-javascript template-string interpolation punctuation" style="color:#fff">.</span><span class="token script language-javascript template-string interpolation property-access" style="color:#fff">response</span><span class="token script language-javascript template-string interpolation punctuation" style="color:#fff">.</span><span class="token script language-javascript template-string interpolation property-access" style="color:#fff">status</span><span class="token script language-javascript template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">else</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        unexpectedError</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> err</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">message</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">finally</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      loading</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript boolean" style="color:#C586C0">false</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff"></span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">script</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">template</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">axios-example</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">h2</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain">Axios API Example</span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">h2</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">button</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">@click</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">fetchPosts</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">:disabled</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">loading</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      Fetch Posts</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">button</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-if</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">networkError</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">error</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      Network Error: {{ networkError }}</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-if</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">graphqlError</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">error</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      GraphQL Error: {{ graphqlError }}</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-if</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">unexpectedError</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">error</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      Unexpected Error: {{ unexpectedError }}</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">ul</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">li</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-for</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">post in posts</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">:key</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">post.id</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        {{ post.title }} by {{ post.user.name }}</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">li</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">ul</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">template</span><span class="token tag punctuation" style="color:#fff">&gt;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Axios simplifies the process of making GraphQL requests, handling much of the boilerplate code associated with Fetch API. This makes your code cleaner and easier to maintain.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="3-error-handling">3. Error Handling<a href="https://tailcall.run/blog/graphql-vue-client/#3-error-handling" class="hash-link" aria-label="Direct link to 3. Error Handling" title="Direct link to 3. Error Handling">​</a></h3>
<p>Axios provides robust error handling capabilities, making it easier to manage different types of errors:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">try</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic">// ... axios request ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">err</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">response</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    networkError</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">value </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869">HTTP error! status: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation">err</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">response</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">status</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    unexpectedError</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">value </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> err</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">message</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">finally</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  loading</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">value </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This error-handling structure allows you to neatly categorize and handle various error scenarios, ensuring your application remains robust and user-friendly.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="4-why-axios-rocks">4. Why Axios Rocks<a href="https://tailcall.run/blog/graphql-vue-client/#4-why-axios-rocks" class="hash-link" aria-label="Direct link to 4. Why Axios Rocks" title="Direct link to 4. Why Axios Rocks">​</a></h3>
<ol>
<li>
<p><strong>Automatic Transforms</strong>: Axios automatically transforms your response data, allowing for smoother data handling. It's like having a translator who speaks both JSON and JavaScript fluently.</p>
</li>
<li>
<p><strong>Request and Response Interceptors</strong>: Need to add an auth token to every request or log all responses? Axios interceptors handle these tasks effortlessly, acting like a gatekeeper for your requests.</p>
</li>
<li>
<p><strong>Browser and Node.js Support</strong>: Axios works seamlessly in both browser and Node.js environments, providing flexibility for different project requirements.</p>
</li>
<li>
<p><strong>Cancellation Support</strong>: Axios allows you to cancel requests, providing an "undo" button for your API calls. This is particularly useful for handling stale or unnecessary requests.</p>
</li>
</ol>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="industry-best-practices-and-potential-technical-challenges-1">Industry Best Practices and Potential Technical Challenges<a href="https://tailcall.run/blog/graphql-vue-client/#industry-best-practices-and-potential-technical-challenges-1" class="hash-link" aria-label="Direct link to Industry Best Practices and Potential Technical Challenges" title="Direct link to Industry Best Practices and Potential Technical Challenges">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="best-practices-1">Best Practices<a href="https://tailcall.run/blog/graphql-vue-client/#best-practices-1" class="hash-link" aria-label="Direct link to Best Practices" title="Direct link to Best Practices">​</a></h3>
<ol>
<li><strong>Use Interceptors</strong>: Leverage Axios interceptors to manage repetitive tasks like setting headers or logging requests and responses.</li>
<li><strong>Error Handling</strong>: Implement comprehensive error handling to ensure your application can gracefully recover from various error conditions.</li>
<li><strong>Modular Code</strong>: Organize your Axios requests into reusable functions or composables to keep your codebase clean and maintainable.</li>
</ol>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="technical-challenges-1">Technical Challenges<a href="https://tailcall.run/blog/graphql-vue-client/#technical-challenges-1" class="hash-link" aria-label="Direct link to Technical Challenges" title="Direct link to Technical Challenges">​</a></h3>
<ol>
<li><strong>Bundle Size</strong>: Although Axios is relatively lightweight, it's still an additional dependency that can increase your project's bundle size.</li>
<li><strong>Customization</strong>: While Axios is highly customizable, it may require additional setup compared to more specialized GraphQL clients.</li>
</ol>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="real-world-applications-1">Real-World Applications<a href="https://tailcall.run/blog/graphql-vue-client/#real-world-applications-1" class="hash-link" aria-label="Direct link to Real-World Applications" title="Direct link to Real-World Applications">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="professional-development-scenarios-1">Professional Development Scenarios<a href="https://tailcall.run/blog/graphql-vue-client/#professional-development-scenarios-1" class="hash-link" aria-label="Direct link to Professional Development Scenarios" title="Direct link to Professional Development Scenarios">​</a></h3>
<ol>
<li><strong>API Integration</strong>: Axios is ideal for integrating with RESTful and GraphQL APIs, providing a consistent and efficient approach for data fetching.</li>
<li><strong>Middleware Implementation</strong>: Use Axios interceptors to implement middleware for logging, authentication, or other cross-cutting concerns.</li>
<li><strong>Server-Side Rendering (SSR)</strong>: With its support for both browser and Node.js environments, Axios is well-suited for SSR applications, ensuring consistent data fetching across platforms.</li>
</ol>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="summary-of-key-technical-insights-1">Summary of Key Technical Insights<a href="https://tailcall.run/blog/graphql-vue-client/#summary-of-key-technical-insights-1" class="hash-link" aria-label="Direct link to Summary of Key Technical Insights" title="Direct link to Summary of Key Technical Insights">​</a></h2>
<ol>
<li><strong>Efficiency and Convenience</strong>: Axios offers a balance of control and convenience, making it easier to manage GraphQL requests with minimal boilerplate.</li>
<li><strong>Robust Error Handling</strong>: Built-in error handling features help manage network and unexpected errors effectively.</li>
<li><strong>Flexibility</strong>: With support for both browser and Node.js environments, Axios is versatile and adaptable to various project needs.</li>
<li><strong>Interceptors and Cancellation</strong>: Advanced features like request/response interceptors and request cancellation provide additional control and flexibility.</li>
</ol>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion-3">Conclusion<a href="https://tailcall.run/blog/graphql-vue-client/#conclusion-3" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>Axios stands out as a versatile and efficient tool for handling GraphQL requests in Vue.js applications. Its combination of automatic data transformation, robust error handling, and advanced features like interceptors and cancellation support make it a powerful choice for developers seeking a smooth and streamlined data-fetching experience. By incorporating best practices and understanding potential challenges, developers can leverage Axios to build robust and responsive applications, gaining valuable insights and experience in the process.</p>
<p>Stay tuned as we continue our journey through the world of GraphQL data fetching in Vue.js. Our final approach will bring everything together, providing the ultimate guide to mastering GraphQL in your Vue applications.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="villus---the-vue-native-virtuoso">Villus - The Vue-Native Virtuoso<a href="https://tailcall.run/blog/graphql-vue-client/#villus---the-vue-native-virtuoso" class="hash-link" aria-label="Direct link to Villus - The Vue-Native Virtuoso" title="Direct link to Villus - The Vue-Native Virtuoso">​</a></h2>
<p>For the grand finale of our GraphQL journey, let's introduce Villus! 🎭 If our previous approaches were a warm-up, Villus is the show-stopping final act. It's a Vue-native GraphQL client that makes your data fetching seamless and elegant, tailored perfectly for Vue.js applications.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="1-installation-and-integration-steps-1">1. Installation and Integration Steps<a href="https://tailcall.run/blog/graphql-vue-client/#1-installation-and-integration-steps-1" class="hash-link" aria-label="Direct link to 1. Installation and Integration Steps" title="Direct link to 1. Installation and Integration Steps">​</a></h3>
<p>First, let's set up Villus in your Vue project:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">npm install villus graphql</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Next, configure Villus in your <code>main.js</code> file:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">createApp</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"vue"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">createClient </span><span class="token keyword" style="color:#C586C0">as</span><span class="token plain"> createVillusClient</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"villus"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> App </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"./App.vue"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> villusClient </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">createVillusClient</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  url</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"/graphql"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> app </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">createApp</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">App</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">app</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">use</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">villusClient</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">app</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">mount</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">"#app"</span><span class="token punctuation" style="color:#fff">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="2-code-snippets-1">2. Code Snippets<a href="https://tailcall.run/blog/graphql-vue-client/#2-code-snippets-1" class="hash-link" aria-label="Direct link to 2. Code Snippets" title="Direct link to 2. Code Snippets">​</a></h3>
<p>Here's how to use Villus to fetch data from a GraphQL endpoint in a Vue component:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">script</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">setup</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">lang</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">ts</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports punctuation" style="color:#fff">{</span><span class="token script language-javascript imports" style="color:#fff">useQuery</span><span class="token script language-javascript imports punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"villus"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword module" style="color:#C586C0">import</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript imports punctuation" style="color:#fff">{</span><span class="token script language-javascript imports" style="color:#fff">ref</span><span class="token script language-javascript imports punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword module" style="color:#C586C0">from</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript string" style="color:#FDB869">"vue"</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">interface</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript class-name" style="color:#C586C0">Post</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">id</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> number</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">title</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">body</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">user</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript literal-property property" style="color:#C586C0">name</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">interface</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript class-name" style="color:#C586C0">QueryResult</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">posts</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript maybe-class-name" style="color:#fff">Post</span><span class="token script language-javascript punctuation" style="color:#fff">[</span><span class="token script language-javascript punctuation" style="color:#fff">]</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> posts </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> ref</span><span class="token script language-javascript operator" style="color:#8DFFF8">&lt;</span><span class="token script language-javascript maybe-class-name" style="color:#fff">Post</span><span class="token script language-javascript punctuation" style="color:#fff">[</span><span class="token script language-javascript punctuation" style="color:#fff">]</span><span class="token script language-javascript operator" style="color:#8DFFF8">&gt;</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">[</span><span class="token script language-javascript punctuation" style="color:#fff">]</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> loading </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function" style="color:#FDEA2F">ref</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript boolean" style="color:#C586C0">false</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> networkError </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> ref</span><span class="token script language-javascript operator" style="color:#8DFFF8">&lt;</span><span class="token script language-javascript" style="color:#fff">string </span><span class="token script language-javascript operator" style="color:#8DFFF8">|</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript operator" style="color:#8DFFF8">&gt;</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> graphqlError </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> ref</span><span class="token script language-javascript operator" style="color:#8DFFF8">&lt;</span><span class="token script language-javascript" style="color:#fff">string </span><span class="token script language-javascript operator" style="color:#8DFFF8">|</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript operator" style="color:#8DFFF8">&gt;</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> unexpectedError </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> ref</span><span class="token script language-javascript operator" style="color:#8DFFF8">&lt;</span><span class="token script language-javascript" style="color:#fff">string </span><span class="token script language-javascript operator" style="color:#8DFFF8">|</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript operator" style="color:#8DFFF8">&gt;</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> query </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> useQuery</span><span class="token script language-javascript operator" style="color:#8DFFF8">&lt;</span><span class="token script language-javascript maybe-class-name" style="color:#fff">QueryResult</span><span class="token script language-javascript operator" style="color:#8DFFF8">&gt;</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">query</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript template-string string" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">    query GetPosts {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">      posts {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">        id</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">        title</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">        body</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">        user {</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">          name</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">        }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">      }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">    }</span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript template-string string" style="color:#FDB869">  </span><span class="token script language-javascript template-string template-punctuation string" style="color:#FDB869">`</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript literal-property property" style="color:#C586C0">paused</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript boolean" style="color:#C586C0">true</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript function-variable function" style="color:#FDEA2F">fetchPosts</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword" style="color:#C586C0">async</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    loading</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript boolean" style="color:#C586C0">true</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    networkError</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    graphqlError</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    unexpectedError</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword null nil" style="color:#C586C0">null</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="display:inline-block;color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">try</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript keyword" style="color:#C586C0">const</span><span class="token script language-javascript" style="color:#fff"> result </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">await</span><span class="token script language-javascript" style="color:#fff"> query</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript method function property-access" style="color:#FDEA2F">execute</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">if</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff">result</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">error</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">throw</span><span class="token script language-javascript" style="color:#fff"> result</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">error</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">if</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff">result</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">data</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">&amp;&amp;</span><span class="token script language-javascript" style="color:#fff"> result</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">data</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">posts</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        posts</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> result</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">data</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">posts</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript method function property-access" style="color:#FDEA2F">slice</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript number" style="color:#C586C0">0</span><span class="token script language-javascript punctuation" style="color:#fff">,</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript number" style="color:#C586C0">4</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">else</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">throw</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword" style="color:#C586C0">new</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript class-name" style="color:#C586C0">Error</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript string" style="color:#FDB869">"Posts not found in query result"</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">catch</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff">e</span><span class="token script language-javascript operator" style="color:#8DFFF8">:</span><span class="token script language-javascript" style="color:#fff"> any</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">if</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff">e</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">message</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript method function property-access" style="color:#FDEA2F">startsWith</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript string" style="color:#FDB869">"Network Error"</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        networkError</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> e</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">message</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">else</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">if</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript" style="color:#fff">e</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">graphQLErrors</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        graphqlError</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> e</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">graphQLErrors</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">          </span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript method function property-access" style="color:#FDEA2F">map</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript parameter literal-property property" style="color:#C586C0">err</span><span class="token script language-javascript parameter operator" style="color:#8DFFF8">:</span><span class="token script language-javascript parameter" style="color:#953800"> any</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token script language-javascript" style="color:#fff"> err</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">message</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">          </span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript method function property-access" style="color:#FDEA2F">join</span><span class="token script language-javascript punctuation" style="color:#fff">(</span><span class="token script language-javascript string" style="color:#FDB869">", "</span><span class="token script language-javascript punctuation" style="color:#fff">)</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">else</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">        unexpectedError</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> e</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">message</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript keyword control-flow" style="color:#C586C0">finally</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript punctuation" style="color:#fff">{</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">      loading</span><span class="token script language-javascript punctuation" style="color:#fff">.</span><span class="token script language-javascript property-access" style="color:#fff">value</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript operator" style="color:#8DFFF8">=</span><span class="token script language-javascript" style="color:#fff"> </span><span class="token script language-javascript boolean" style="color:#C586C0">false</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">    </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff">  </span><span class="token script language-javascript punctuation" style="color:#fff">}</span><span class="token script language-javascript" style="color:#fff"></span><br></span><span class="token-line" style="color:#fff"><span class="token script language-javascript" style="color:#fff"></span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">script</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">template</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">container</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">h2</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain">Villus Example</span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">h2</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">button</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">@click</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">fetchPosts</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">:disabled</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">loading</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      Fetch Posts</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">button</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-if</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">networkError</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">error</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      Network Error: {{ networkError }}</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-if</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">graphqlError</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">error</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      GraphQL Error: {{ graphqlError }}</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-if</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">unexpectedError</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">error</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      Unexpected Error: {{ unexpectedError }}</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">ul</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag" style="color:#b76b01">li</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">v-for</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">post in posts</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">:key</span><span class="token tag attr-value punctuation attr-equals" style="color:#fff">=</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag attr-value" style="color:#FDB869">post.id</span><span class="token tag attr-value punctuation" style="color:#fff">"</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        {{ post.title }} by {{ post.user.name }}</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">li</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">ul</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">div</span><span class="token tag punctuation" style="color:#fff">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token tag punctuation" style="color:#fff">&lt;/</span><span class="token tag" style="color:#b76b01">template</span><span class="token tag punctuation" style="color:#fff">&gt;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Villus integrates seamlessly with Vue, providing a smooth and elegant way to handle GraphQL queries.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="3-error-handling-1">3. Error Handling<a href="https://tailcall.run/blog/graphql-vue-client/#3-error-handling-1" class="hash-link" aria-label="Direct link to 3. Error Handling" title="Direct link to 3. Error Handling">​</a></h3>
<p>Villus comes with robust error handling, making it easy to manage various error scenarios:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">try</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> result </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">await</span><span class="token plain"> query</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">execute</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">result</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">throw</span><span class="token plain"> result</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic">// ... handle successful result ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">e</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">message</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">startsWith</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">"Network Error"</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    networkError</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">value </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> e</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">message</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">e</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">graphQLErrors</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    graphqlError</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">value </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> e</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">graphQLErrors</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">map</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">err</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> err</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">message</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">join</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">", "</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    unexpectedError</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">value </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> e</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">message</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This error-handling structure ensures that your application can gracefully recover from various issues, providing a robust user experience.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="4-why-villus-rocks">4. Why Villus Rocks<a href="https://tailcall.run/blog/graphql-vue-client/#4-why-villus-rocks" class="hash-link" aria-label="Direct link to 4. Why Villus Rocks" title="Direct link to 4. Why Villus Rocks">​</a></h3>
<ol>
<li><strong>Vue-Native</strong>: Villus is built specifically for Vue, making it a perfect fit for Vue applications. It's like having a custom-tailored suit for your Vue app.</li>
<li><strong>Lightweight</strong>: Villus is lightweight and efficient, ensuring that your application remains fast and responsive.</li>
<li><strong>Composable</strong>: With its composition API support, Villus integrates seamlessly with Vue 3, enhancing the development experience.</li>
<li><strong>Smart Defaults</strong>: Villus comes with smart defaults that work out of the box, but it is also highly customizable to fit your specific needs.</li>
</ol>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="industry-best-practices-and-potential-technical-challenges-2">Industry Best Practices and Potential Technical Challenges<a href="https://tailcall.run/blog/graphql-vue-client/#industry-best-practices-and-potential-technical-challenges-2" class="hash-link" aria-label="Direct link to Industry Best Practices and Potential Technical Challenges" title="Direct link to Industry Best Practices and Potential Technical Challenges">​</a></h3>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="best-practices-2">Best Practices<a href="https://tailcall.run/blog/graphql-vue-client/#best-practices-2" class="hash-link" aria-label="Direct link to Best Practices" title="Direct link to Best Practices">​</a></h4>
<ol>
<li><strong>Use the Composition API</strong>: Leveraging Vue's composition API with Villus makes your code more modular and maintainable.</li>
<li><strong>Error Handling</strong>: Implement comprehensive error handling to ensure a robust application.</li>
<li><strong>Modular Code</strong>: Organize your Villus queries into reusable functions or composables to keep your codebase clean.</li>
</ol>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="technical-challenges-2">Technical Challenges<a href="https://tailcall.run/blog/graphql-vue-client/#technical-challenges-2" class="hash-link" aria-label="Direct link to Technical Challenges" title="Direct link to Technical Challenges">​</a></h4>
<ol>
<li><strong>Learning Curve</strong>: For developers new to GraphQL or the composition API, there might be a learning curve.</li>
<li><strong>Customization</strong>: While Villus is highly customizable, it may require additional setup for more complex use cases.</li>
</ol>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="real-world-applications-2">Real-World Applications<a href="https://tailcall.run/blog/graphql-vue-client/#real-world-applications-2" class="hash-link" aria-label="Direct link to Real-World Applications" title="Direct link to Real-World Applications">​</a></h3>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="professional-development-scenarios-2">Professional Development Scenarios<a href="https://tailcall.run/blog/graphql-vue-client/#professional-development-scenarios-2" class="hash-link" aria-label="Direct link to Professional Development Scenarios" title="Direct link to Professional Development Scenarios">​</a></h4>
<ol>
<li><strong>API Integration</strong>: Villus is perfect for integrating with GraphQL APIs in Vue applications, providing a seamless data fetching experience.</li>
<li><strong>State Management</strong>: Villus can be used alongside Vue's reactive state management, providing a powerful combination for managing application state.</li>
<li><strong>Server-Side Rendering (SSR)</strong>: With its support for both client-side and server-side rendering, Villus ensures consistent data fetching across platforms.</li>
</ol>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="summary-of-key-technical-insights-2">Summary of Key Technical Insights<a href="https://tailcall.run/blog/graphql-vue-client/#summary-of-key-technical-insights-2" class="hash-link" aria-label="Direct link to Summary of Key Technical Insights" title="Direct link to Summary of Key Technical Insights">​</a></h3>
<ol>
<li><strong>Efficiency and Convenience</strong>: Villus offers a balance of efficiency and convenience, making it easy to manage GraphQL requests in Vue applications.</li>
<li><strong>Robust Error Handling</strong>: Built-in error handling features help manage network and unexpected errors effectively.</li>
<li><strong>Vue-Native Integration</strong>: Villus is built specifically for Vue, providing seamless integration and enhancing the development experience.</li>
<li><strong>Lightweight and Composable</strong>: Villus is lightweight and leverages the composition API, making it a powerful tool for modern Vue development.</li>
</ol>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion-4">Conclusion<a href="https://tailcall.run/blog/graphql-vue-client/#conclusion-4" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h3>
<p>Villus stands out as a versatile and efficient tool for handling GraphQL requests in Vue.js applications. Its Vue-native design, robust error handling, and lightweight nature make it an excellent choice for developers seeking a seamless data-fetching experience. By incorporating best practices and understanding potential challenges, developers can leverage Villus to build robust and responsive applications, gaining valuable insights and experience in the process.</p>
<p>With this, we've completed our exploration of various data-fetching approaches in Vue. Each approach offers unique strengths and is suited for different scenarios, providing you with the tools and knowledge to choose the best solution for your projects. Happy coding! 🎉</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="comparison-table">Comparison Table<a href="https://tailcall.run/blog/graphql-vue-client/#comparison-table" class="hash-link" aria-label="Direct link to Comparison Table" title="Direct link to Comparison Table">​</a></h2>
<table><thead><tr><th>Feature</th><th>Apollo Client</th><th>URQL</th><th>Fetch API</th><th>Axios</th><th>Villus</th></tr></thead><tbody><tr><td>Bundle Size (Minified + Gzipped)*</td><td>47.8 kB</td><td>10.2 kB</td><td>2.8kB</td><td>13.2kB</td><td>4.6kB</td></tr><tr><td>Learning Curve</td><td>Steep</td><td>Moderate</td><td>Low</td><td>Low</td><td>Moderate</td></tr><tr><td>Caching Capabilities</td><td>Advanced</td><td>Good</td><td>Manual</td><td>Manual</td><td>Good</td></tr><tr><td>Community Support</td><td>Extensive</td><td>Growing</td><td>Widespread</td><td>Extensive</td><td>Limited</td></tr><tr><td>Additional Features</td><td>Rich ecosystem, dev tools, local state management</td><td>Lightweight, customizable</td><td>Native browser API</td><td>Request/response interceptors, automatic transforms</td><td>Vue-specific, lightweight</td></tr></tbody></table>
<p>*Bundle sizes culled from bundlephobia.com</p>
<p>Here's a brief explanation of the ratings:</p>
<ol>
<li>
<p>Learning Curve:</p>
<ul>
<li>Apollo Client: Steep due to its extensive features and concepts.</li>
<li>URQL: Moderate as it's simpler than Apollo but still has GraphQL-specific concepts.</li>
<li>Fetch API: Low as it's a basic browser API.</li>
<li>Axios: Low as it's straightforward to use for HTTP requests.</li>
<li>Villus: Moderate as it's Vue-specific but simpler than Apollo.</li>
</ul>
</li>
<li>
<p>Caching Capabilities:</p>
<ul>
<li>Apollo Client: Advanced with sophisticated normalization and cache policies.</li>
<li>URQL: Good built-in caching with customizable options.</li>
<li>Fetch API: Manual caching required.</li>
<li>Axios: Manual caching required.</li>
<li>Villus: Good basic caching capabilities.</li>
</ul>
</li>
<li>
<p>Community Support:</p>
<ul>
<li>Apollo Client: Extensive due to its popularity in the GraphQL ecosystem.</li>
<li>URQL: Growing community, but not as large as Apollo's.</li>
<li>Fetch API: Widespread as it's a web standard.</li>
<li>Axios: Extensive due to its popularity for HTTP requests.</li>
<li>Villus: Limited as it's a newer and more niche library.</li>
</ul>
</li>
<li>
<p>Additional Features:</p>
<ul>
<li>Apollo Client: Rich ecosystem with developer tools and local state management.</li>
<li>URQL: Lightweight and highly customizable.</li>
<li>Fetch API: Native browser API, no extra features.</li>
<li>Axios: Request/response interceptors, automatic transforms for data.</li>
<li>Villus: Vue-specific integration, lightweight alternative to Apollo.</li>
</ul>
</li>
</ol>
<p>This table provides a high-level comparison of the different approaches for GraphQL data fetching in Vue. Each approach has its strengths and may be more suitable depending on the specific requirements of a project.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="caching-capabilities">Caching Capabilities<a href="https://tailcall.run/blog/graphql-vue-client/#caching-capabilities" class="hash-link" aria-label="Direct link to Caching Capabilities" title="Direct link to Caching Capabilities">​</a></h3>
<ol>
<li>
<p>Apollo Client:</p>
<ul>
<li>Offers a sophisticated normalized cache</li>
<li>Supports various cache policies (cache-first, network-only, etc.)</li>
<li>Allows for fine-grained cache updates and invalidation</li>
<li>Provides optimistic UI updates</li>
</ul>
</li>
<li>
<p>URQL:</p>
<ul>
<li>Implements a document cache by default</li>
<li>Supports customizable caching strategies</li>
<li>Offers a normalized cache through the Normalized Cache exchange</li>
<li>Provides easy cache updates and invalidation</li>
</ul>
</li>
<li>
<p>Fetch API:</p>
<ul>
<li>No built-in caching mechanism</li>
<li>Requires manual implementation of caching logic</li>
<li>Can leverage browser's HTTP cache or custom in-memory/storage solutions</li>
</ul>
</li>
<li>
<p>Axios:</p>
<ul>
<li>No built-in caching mechanism for GraphQL</li>
<li>Requires manual implementation of caching logic</li>
<li>Can be combined with external caching libraries</li>
</ul>
</li>
<li>
<p>Villus:</p>
<ul>
<li>Provides a simple document cache</li>
<li>Supports cache policies similar to Apollo (cache-first, network-only)</li>
<li>Offers manual cache manipulation methods</li>
<li>Lighter weight caching compared to Apollo</li>
</ul>
</li>
</ol>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="common-issues-and-resolutions">Common Issues and Resolutions<a href="https://tailcall.run/blog/graphql-vue-client/#common-issues-and-resolutions" class="hash-link" aria-label="Direct link to Common Issues and Resolutions" title="Direct link to Common Issues and Resolutions">​</a></h2>
<ol>
<li>
<p>Apollo Client:</p>
<ul>
<li>Issue: Over-fetching data
Resolution: Use fragments and optimized queries</li>
<li>Issue: Cache inconsistencies
Resolution: Manually update cache or use refetchQueries</li>
<li>Issue: Performance with large datasets
Resolution: Implement pagination or infinite scrolling</li>
</ul>
</li>
<li>
<p>URQL:</p>
<ul>
<li>Issue: Lack of advanced caching features out-of-the-box
Resolution: Use additional exchanges like the Normalized Cache exchange</li>
<li>Issue: Limited dev tools compared to Apollo
Resolution: Rely on browser network tab or implement custom logging</li>
<li>Issue: Learning curve for exchanges concept
Resolution: Start with basic setup and gradually add exchanges as needed</li>
</ul>
</li>
<li>
<p>Fetch API:</p>
<ul>
<li>Issue: Verbose syntax for GraphQL requests
Resolution: Create utility functions to simplify request creation</li>
<li>Issue: No built-in error handling for GraphQL errors
Resolution: Implement custom error checking and handling logic</li>
<li>Issue: Manual caching and state management
Resolution: Use state management libraries like Vuex or Pinia alongside Fetch</li>
</ul>
</li>
<li>
<p>Axios:</p>
<ul>
<li>Issue: Not GraphQL-specific, requiring more boilerplate
Resolution: Create custom wrapper functions for GraphQL operations</li>
<li>Issue: Handling GraphQL errors separately from HTTP errors
Resolution: Implement middleware to check for and handle GraphQL-specific errors</li>
<li>Issue: No built-in caching for GraphQL queries
Resolution: Implement custom caching layer or use with a state management solution</li>
</ul>
</li>
<li>
<p>Villus:</p>
<ul>
<li>Issue: Limited ecosystem compared to Apollo
Resolution: Combine with other Vue libraries for missing features</li>
<li>Issue: Less community resources and examples
Resolution: Refer to official documentation and reach out to maintainers for support</li>
<li>Issue: Potential performance issues with larger applications
Resolution: Consider using more robust solutions like Apollo for very complex apps</li>
</ul>
</li>
</ol>
<p>Each approach has its own set of challenges, but also offers unique advantages. The choice between them often depends on the specific requirements of your project, the complexity of your GraphQL operations, and your team's familiarity with the tools.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-grand-finale">The Grand Finale<a href="https://tailcall.run/blog/graphql-vue-client/#the-grand-finale" class="hash-link" aria-label="Direct link to The Grand Finale" title="Direct link to The Grand Finale">​</a></h2>
<p>We've journeyed through the land of GraphQL in Vue, exploring five fantastic approaches:</p>
<ol>
<li>Apollo Client: The Swiss Army knife</li>
<li>URQL: The lightweight contender</li>
<li>Fetch API: The DIY dynamo</li>
<li>Axios: The smooth operator</li>
<li>Villus: The Vue-native virtuoso</li>
</ol>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Examples and Resources</div><div class="admonitionContent_BuS1"><p>Code snippets used in this article can be found in the <a href="https://github.com/onyedikachi-david/vue-graphql-multiapproach" target="_blank" rel="noopener noreferrer">GitHub repository</a>. Feel free to explore, experiment, and adapt them to your projects!</p></div></div>
<p>Each approach has its own strengths, like instruments in an orchestra. The choice depends on your project's needs, your team's expertise, and the symphony you want to create.</p>
<p>Remember, in the world of web development, there's no one-size-fits-all solution. It's about finding the right tool for your unique masterpiece. So go forth, experiment, and may your Vue apps be forever data-rich and performant!</p>
<p>And with that, we bring down the curtain on our GraphQL in Vue extravaganza. But don't worry, the show never really ends in the ever-evolving world of web development. Keep learning, keep coding, and most importantly, keep having fun! 🎭🚀</p>]]></content:encoded>
            <category>GraphQL</category>
            <category>Vue</category>
            <category>Apollo client</category>
            <category>URQL</category>
            <category>Fetch API</category>
            <category>Villus</category>
        </item>
        <item>
            <title><![CDATA[GraphQL vs OpenAPI: Part 3 of the API Comparison Series]]></title>
            <link>https://tailcall.run/blog/graphql-vs-openapi-part-3/</link>
            <guid>https://tailcall.run/blog/graphql-vs-openapi-part-3/</guid>
            <pubDate>Wed, 31 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[An exploration of the security, tooling, and future prospects of GraphQL and OpenAPI.]]></description>
            <content:encoded><![CDATA[<p>Welcome to Part 3 of our API comparison series! So far, we've discussed the basics and compared the performance and flexibility of GraphQL and OpenAPI. In this installment, we will focus on exploring their security features, tooling support, and future prospects.</p>
<p>Understanding the security implications and the available tools can significantly impact your decision when choosing between GraphQL and OpenAPI. We will also look at how these API specifications integrate with existing systems and their compatibility with various development tools, helping you effectively use them in your development workflow.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="integration-and-compatibility">Integration and Compatibility<a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/#integration-and-compatibility" class="hash-link" aria-label="Direct link to Integration and Compatibility" title="Direct link to Integration and Compatibility">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="integrating-with-existing-systems">Integrating with Existing Systems<a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/#integrating-with-existing-systems" class="hash-link" aria-label="Direct link to Integrating with Existing Systems" title="Direct link to Integrating with Existing Systems">​</a></h3>
<p>Integration capabilities are crucial for adopting new API specifications without disrupting existing systems.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="compatibility-with-legacy-systems">Compatibility with Legacy Systems<a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/#compatibility-with-legacy-systems" class="hash-link" aria-label="Direct link to Compatibility with Legacy Systems" title="Direct link to Compatibility with Legacy Systems">​</a></h4>
<ol>
<li>
<p><strong>GraphQL</strong>:</p>
<ul>
<li><strong>Integration Challenges</strong>: Integrating GraphQL with legacy systems may require significant changes, especially in how data is fetched and aggregated.</li>
<li><strong>Gateway Solutions</strong>: Using GraphQL gateways or proxies can help bridge the gap, allowing gradual migration without overhauling the entire system.</li>
</ul>
</li>
<li>
<p><strong>OpenAPI</strong>:</p>
<ul>
<li><strong>Seamless Integration</strong>: OpenAPI’s RESTful approach aligns well with existing systems, making it easier to integrate without major modifications.</li>
<li><strong>Backward Compatibility</strong>: The structured nature of OpenAPI allows for maintaining backward compatibility with legacy systems.</li>
</ul>
</li>
</ol>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="future-proofing-your-api-strategy">Future-Proofing Your API Strategy<a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/#future-proofing-your-api-strategy" class="hash-link" aria-label="Direct link to Future-Proofing Your API Strategy" title="Direct link to Future-Proofing Your API Strategy">​</a></h3>
<p>Ensuring your API remains adaptable to emerging technologies and trends is crucial for maintaining its relevance and efficiency in the long term.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="adapting-to-emerging-tech-trends">Adapting to Emerging Tech Trends<a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/#adapting-to-emerging-tech-trends" class="hash-link" aria-label="Direct link to Adapting to Emerging Tech Trends" title="Direct link to Adapting to Emerging Tech Trends">​</a></h4>
<ol>
<li>
<p><strong>GraphQL:</strong></p>
<ul>
<li><strong>Flexibility and Evolution:</strong> GraphQL’s flexibility and its ability to handle complex queries make it an excellent choice for modern applications, microservices, and evolving business requirements. Its schema-first approach allows for rapid iterations and modifications without breaking existing functionalities, making it future-proof as your business needs change.</li>
<li><strong>Real-Time Capabilities:</strong> GraphQL's subscription feature is designed for real-time applications, enabling a steady connection between the client and server. This is essential for applications that require real-time updates, such as live sports scores, stock trading, or social media feeds. For example, a live-updating stock trading application can use GraphQL subscriptions to push stock price updates to the client:</li>
</ul>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">subscription</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property-query">stockPriceUpdate</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">symbol</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"AAPL"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">price</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">change</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">lastUpdated</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This setup is more efficient than repeatedly polling an endpoint, as it reduces unnecessary network traffic and server load. Combining subscriptions with queries and mutations allows for a seamless user experience, integrating real-time data updates with other operations within the same endpoint.</p>
</li>
<li>
<p><strong>OpenAPI:</strong></p>
<ul>
<li>
<p><strong>Standardization and Stability:</strong> OpenAPI’s adherence to REST principles and its standardized approach ensure long-term stability and interoperability. This makes it a reliable choice for enterprises looking to maintain consistency and clarity in their API documentation and interactions.</p>
</li>
<li>
<p><strong>Adoption of New Features:</strong> OpenAPI continuously evolves with regular updates to its specification. These updates incorporate enhancements that align with industry best practices, such as improved support for asynchronous APIs, better integration with modern security protocols, and more detailed documentation capabilities. By keeping up with these updates, you can ensure your API remains up-to-date with the latest technological advancements.</p>
<p><strong>Example:</strong></p>
</li>
</ul>
<p>An enterprise financial services provider can use OpenAPI to ensure their API remains compliant with evolving regulatory standards and security requirements. By utilizing OpenAPI’s robust validation features, they can enforce strict data schemas and authentication mechanisms, ensuring secure and reliable data exchanges across systems.</p>
</li>
</ol>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="industry-adoption-and-case-studies">Industry Adoption and Case Studies<a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/#industry-adoption-and-case-studies" class="hash-link" aria-label="Direct link to Industry Adoption and Case Studies" title="Direct link to Industry Adoption and Case Studies">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="industry-leaders-and-their-choices">Industry Leaders and Their Choices<a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/#industry-leaders-and-their-choices" class="hash-link" aria-label="Direct link to Industry Leaders and Their Choices" title="Direct link to Industry Leaders and Their Choices">​</a></h3>
<p>Examining the choices of industry leaders provides valuable insights into the practical applications of GraphQL and OpenAPI.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="examples-from-tech-giants">Examples from Tech Giants<a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/#examples-from-tech-giants" class="hash-link" aria-label="Direct link to Examples from Tech Giants" title="Direct link to Examples from Tech Giants">​</a></h4>
<ol>
<li>
<p><strong>GraphQL</strong>:</p>
<ul>
<li><strong>Facebook</strong>: The creator and primary user of GraphQL, leveraging its flexibility to power complex, real-time data interactions.</li>
<li><strong>GitHub</strong>: Adopted GraphQL to provide a more efficient and flexible API for developers.</li>
<li><strong>Shopify</strong>: Uses GraphQL to handle complex e-commerce data queries and real-time updates.</li>
</ul>
</li>
<li>
<p><strong>OpenAPI</strong>:</p>
<ul>
<li><strong>Microsoft</strong>: Utilizes OpenAPI for its Azure services, providing clear and standardized API definitions.</li>
<li><strong>IBM</strong>: Implements OpenAPI for its cloud services, ensuring robust and reliable API interactions.</li>
<li><strong>Google</strong>: Adopts OpenAPI for its various APIs, emphasizing clear documentation and ease of use.</li>
</ul>
</li>
</ol>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="real-world-case-studies">Real-World Case Studies<a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/#real-world-case-studies" class="hash-link" aria-label="Direct link to Real-World Case Studies" title="Direct link to Real-World Case Studies">​</a></h3>
<p>Exploring real-world case studies illustrates the practical benefits and challenges of using GraphQL and OpenAPI.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="success-stories-and-lessons-learned">Success Stories and Lessons Learned<a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/#success-stories-and-lessons-learned" class="hash-link" aria-label="Direct link to Success Stories and Lessons Learned" title="Direct link to Success Stories and Lessons Learned">​</a></h4>
<ol>
<li>
<p><strong>GraphQL:</strong></p>
<ul>
<li><strong>Case Study 1:</strong> LinkedIn transitioned from its homegrown Deco library to GraphQL to improve data fetching efficiency and developer experience. The company faced challenges with Deco's schema-less nature, which led to production issues and a poor developer experience. GraphQL offered a more standardized approach, <a href="https://www.linkedin.com/blog/engineering/architecture/how-linkedin-adopted-a-graphql-architecture-for-product-developm" target="_blank" rel="noopener noreferrer">Read more here</a>.</li>
<li><strong>Case Study 2:</strong> At Shopify, GraphQL has been utilized to overcome the limitations of REST APIs in mobile application development. Unlike REST, GraphQL provides a strongly typed, self-documented contract between clients and servers, eliminating the need for manual type casting and JSON mapping. More details on <a href="https://shopify.engineering/using-graphql-for-high-performing-mobile-applications" target="_blank" rel="noopener noreferrer">Shopify's Blog</a>.</li>
</ul>
</li>
<li>
<p><strong>OpenAPI:</strong></p>
<ul>
<li><strong>Case Study 1:</strong> A Spanish banking giant utilized OpenAPI to build an open-source security product. By standardizing their API documentation and using OpenAPI's robust validation features, they enhanced security and compliance across their digital services. For more information, visit their <a href="https://www.bbva.com/en/bbva-launches-open-banking-business/" target="_blank" rel="noopener noreferrer">website</a>.</li>
<li><strong>Case Study 2:</strong> A global agricultural solutions provider accelerated the development of their digital hub using OpenAPI. The clear structure and validation provided by OpenAPI ensured reliable data exchange and integration across their systems, streamlining operations and improving service delivery. See their implementation on their <a href="https://developer.nutrien.com/apis" target="_blank" rel="noopener noreferrer">website</a>.</li>
</ul>
</li>
</ol>
<p>These case studies illustrate how companies from various industries have successfully implemented GraphQL and OpenAPI to enhance their operations, streamline development processes, and improve overall efficiency.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="migration-guide">Migration Guide<a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/#migration-guide" class="hash-link" aria-label="Direct link to Migration Guide" title="Direct link to Migration Guide">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="transitioning-from-rest-to-graphql-using-tailcall">Transitioning from REST to GraphQL using Tailcall<a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/#transitioning-from-rest-to-graphql-using-tailcall" class="hash-link" aria-label="Direct link to Transitioning from REST to GraphQL using Tailcall" title="Direct link to Transitioning from REST to GraphQL using Tailcall">​</a></h3>
<p>Migrating from a RESTful API to GraphQL can significantly enhance your application's performance and flexibility. Tailcall offers a streamlined approach to manage this transition effectively.</p>
<p><strong>Read More:</strong></p>
<ul>
<li><a href="https://tailcall.run/docs/" target="_blank" rel="noopener noreferrer">Tailcall's GraphQL Getting Started</a></li>
<li><a href="https://tailcall.run/docs/graphql-configuration-generation-with-tailcall/#effortless-rest-integration" target="_blank" rel="noopener noreferrer">Tailcall's Config Generator</a></li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion">Conclusion<a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>In this third part of our series, we've examined the security features, tooling support, and future prospects of GraphQL and OpenAPI. We've seen how each specification handles security, the variety of tools available to support their implementation, and their potential for future growth and adaptation.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="final-thoughts-on-choosing-between-graphql-and-openapi">Final Thoughts on Choosing Between GraphQL and OpenAPI<a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/#final-thoughts-on-choosing-between-graphql-and-openapi" class="hash-link" aria-label="Direct link to Final Thoughts on Choosing Between GraphQL and OpenAPI" title="Direct link to Final Thoughts on Choosing Between GraphQL and OpenAPI">​</a></h3>
<p>After following this 3 part Series selecting the appropriate API specification for your project is crucial and should be based on a thorough evaluation of your specific needs, constraints, and long-term objectives. Here are some final considerations to guide your decision:</p>
<ol>
<li>
<p><strong>Project Requirements</strong>:</p>
<ul>
<li>Assess the complexity of your data retrieval needs. If your application requires complex, nested queries or real-time updates, GraphQL might be more suitable.</li>
<li>For standardized operations with well-defined endpoints, OpenAPI offers a more straightforward and reliable approach.</li>
</ul>
</li>
<li>
<p><strong>Development Resources</strong>:</p>
<ul>
<li>Consider the expertise of your development team. If they are more familiar with RESTful principles, OpenAPI can be easier to adopt. Conversely, if your team is open to learning and working with flexible query languages, GraphQL provides significant advantages.</li>
</ul>
</li>
<li>
<p><strong>Performance and Scalability</strong>:</p>
<ul>
<li>Evaluate the performance requirements and scalability challenges of your application. GraphQL's efficient data fetching can reduce response times, but optimizing complex queries may require additional effort. OpenAPI's structured endpoints may be easier to scale in high-traffic scenarios.</li>
</ul>
</li>
<li>
<p><strong>Security Considerations</strong>:</p>
<ul>
<li>Determine the security requirements of your API. OpenAPI's built-in mechanisms offer robust security options out of the box. GraphQL requires a more hands-on approach to ensure secure data access and mitigate potential risks.</li>
</ul>
</li>
<li>
<p><strong>Long-term Goals</strong>:</p>
<ul>
<li>Think about the future direction of your API strategy. GraphQL's flexibility makes it well-suited for evolving and modern applications, particularly in microservices architectures. OpenAPI's standardization ensures long-term stability and compliance with industry standards.</li>
</ul>
</li>
</ol>
<p>By carefully weighing these factors, you can make an informed decision that aligns with your project's unique needs and goals, ultimately leading to a more successful and efficient API implementation.</p>
<p>The future of APIs is looking bright! With GraphQL pushing the boundaries of flexibility and OpenAPI continually evolving, we're in for some exciting developments. Whether you need the dynamic, precise data fetching capabilities of GraphQL or the structured, standardized approach of OpenAPI, both tools have their unique strengths and can significantly enhance your API development process.</p>
<p>GraphQL is like a Swiss Army knife for your API needs, offering unmatched flexibility and efficiency, especially when dealing with complex, interconnected data. On the other hand, OpenAPI provides a well-organized and robust framework, perfect for creating clear, consistent, and scalable APIs.</p>
<p>In the end, the choice between GraphQL and OpenAPI often comes down to your specific project requirements and team preferences. By understanding the strengths and potential challenges of each, you can make an informed decision that will best serve your development goals.</p>
<p>So, which one will you choose for your next project? Whatever your choice, happy coding!</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="faqs">FAQs<a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/#faqs" class="hash-link" aria-label="Direct link to FAQs" title="Direct link to FAQs">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="1-what-are-the-cost-implications-of-adopting-graphql-vs-openapi">1. What are the cost implications of adopting GraphQL vs OpenAPI?<a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/#1-what-are-the-cost-implications-of-adopting-graphql-vs-openapi" class="hash-link" aria-label="Direct link to 1. What are the cost implications of adopting GraphQL vs OpenAPI?" title="Direct link to 1. What are the cost implications of adopting GraphQL vs OpenAPI?">​</a></h3>
<p><strong>GraphQL</strong>: Initial setup and training can be costly, but it improves development efficiency and can lower long-term operational costs.</p>
<p><a href="https://tailcall.run/" target="_blank" rel="noopener noreferrer">Tailcall</a> offers a cost-effective solution for migrating to GraphQL.</p>
<p><strong>OpenAPI</strong>: Easier and cheaper to adopt initially due to familiarity and extensive tooling, with reduced maintenance costs through auto-generated documentation.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="2-how-do-graphql-and-openapi-handle-versioning-and-api-changes">2. How do GraphQL and OpenAPI handle versioning and API changes?<a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/#2-how-do-graphql-and-openapi-handle-versioning-and-api-changes" class="hash-link" aria-label="Direct link to 2. How do GraphQL and OpenAPI handle versioning and API changes?" title="Direct link to 2. How do GraphQL and OpenAPI handle versioning and API changes?">​</a></h3>
<p><strong>GraphQL</strong>: Encourages backward-compatible changes and schema evolution, with clear documentation for deprecated fields.</p>
<p><strong>OpenAPI</strong>: Supports versioning through URL paths or query parameters, making it easy to manage and document changes while maintaining backward compatibility.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="3-what-are-the-main-challenges-in-implementing-graphql-vs-openapi">3. What are the main challenges in implementing GraphQL vs OpenAPI?<a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/#3-what-are-the-main-challenges-in-implementing-graphql-vs-openapi" class="hash-link" aria-label="Direct link to 3. What are the main challenges in implementing GraphQL vs OpenAPI?" title="Direct link to 3. What are the main challenges in implementing GraphQL vs OpenAPI?">​</a></h3>
<p><strong>GraphQL</strong>: Complexity in queries, steep learning curve, and choosing the right tools can be challenging.</p>
<p><strong>OpenAPI</strong>: Managing over-fetching/under-fetching, handling multiple API versions, and maintaining up-to-date documentation can be labor-intensive.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="4-how-do-graphql-and-openapi-impact-frontend-development-workflows">4. How do GraphQL and OpenAPI impact frontend development workflows?<a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/#4-how-do-graphql-and-openapi-impact-frontend-development-workflows" class="hash-link" aria-label="Direct link to 4. How do GraphQL and OpenAPI impact frontend development workflows?" title="Direct link to 4. How do GraphQL and OpenAPI impact frontend development workflows?">​</a></h3>
<p><strong>GraphQL</strong>: Simplifies data fetching, state management, and supports real-time updates through a single endpoint.</p>
<p><strong>OpenAPI</strong>: Provides predictable endpoints, auto-generated client SDKs, and leverages standard REST practices for easier frontend development.</p>]]></content:encoded>
            <category>GraphQL</category>
            <category>API</category>
            <category>OpenAPI</category>
            <category>Security</category>
            <category>Tooling</category>
        </item>
        <item>
            <title><![CDATA[GraphQL vs OpenAPI: Part 2 of the API Comparison Series]]></title>
            <link>https://tailcall.run/blog/graphql-vs-openapi-part-2/</link>
            <guid>https://tailcall.run/blog/graphql-vs-openapi-part-2/</guid>
            <pubDate>Tue, 30 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[A detailed comparison of the performance, flexibility, and ecosystems of GraphQL and OpenAPI.]]></description>
            <content:encoded><![CDATA[<p>Welcome back to our API comparison series! In <a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/">Part 1</a>, we covered the fundamentals of GraphQL and OpenAPI, focusing on their core concepts, type systems, and schema definitions. Now, in Part 2, we will dive deeper into the performance, flexibility, and ecosystems of these API specifications.</p>
<p>We'll examine how each fares in different development environments, how they cater to the needs of developers and businesses, and their practical applications. This part will provide a detailed comparison of their real-world use cases, performance implications, scalability challenges, and the overall developer experience.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="practical-application-scenarios">Practical Application Scenarios<a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/#practical-application-scenarios" class="hash-link" aria-label="Direct link to Practical Application Scenarios" title="Direct link to Practical Application Scenarios">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="real-world-use-cases-for-graphql-and-openapi">Real-World Use Cases for GraphQL and OpenAPI<a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/#real-world-use-cases-for-graphql-and-openapi" class="hash-link" aria-label="Direct link to Real-World Use Cases for GraphQL and OpenAPI" title="Direct link to Real-World Use Cases for GraphQL and OpenAPI">​</a></h3>
<p>Understanding the practical applications of GraphQL and OpenAPI is crucial for selecting the right tool for your API development needs. Let's explore some real-world scenarios where each excels.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="graphql-ideal-for-complex-real-time-data-requirements">GraphQL: Ideal for Complex, Real-Time Data Requirements<a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/#graphql-ideal-for-complex-real-time-data-requirements" class="hash-link" aria-label="Direct link to GraphQL: Ideal for Complex, Real-Time Data Requirements" title="Direct link to GraphQL: Ideal for Complex, Real-Time Data Requirements">​</a></h3>
<p><strong>E-Commerce Platforms:</strong></p>
<p>GraphQL is particularly well-suited for e-commerce platforms where the client needs to fetch various data types in a single request. For example, displaying product details, user reviews, and related items on a single page can be efficiently managed with GraphQL. The ability to request only the required data fields reduces the payload size and enhances performance.</p>
<p><strong>Social Media Applications:</strong></p>
<p>Social media platforms benefit from GraphQL's real-time data capabilities. Features like live updates on posts, comments, and user activities can be seamlessly integrated using GraphQL subscriptions. This ensures that users always see the most up-to-date information without the need for constant page refreshes.</p>
<p><strong>Custom Dashboards:</strong></p>
<p>For applications that require dynamic and customizable dashboards, GraphQL offers the flexibility to fetch specific data points needed by the user. This reduces the complexity of managing multiple endpoints and allows for more efficient data retrieval.</p>
<p><strong>Example:</strong></p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property-query">product</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"123"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">price</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token object">reviews</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">rating</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">comment</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token object">relatedProducts</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">id</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="openapi-best-for-standardized-well-defined-services">OpenAPI: Best for Standardized, Well-Defined Services<a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/#openapi-best-for-standardized-well-defined-services" class="hash-link" aria-label="Direct link to OpenAPI: Best for Standardized, Well-Defined Services" title="Direct link to OpenAPI: Best for Standardized, Well-Defined Services">​</a></h3>
<p><strong>Financial Services:</strong></p>
<p>In the financial sector, regulatory compliance and security are paramount. OpenAPI supports various authentication methods such as OAuth2, API keys, and mutual TLS, which are essential for secure API development. Detailed schema definitions in OpenAPI facilitate clear documentation and consistent implementation, which are crucial for maintaining compliance with financial regulations.</p>
<p><strong>Healthcare Applications:</strong></p>
<p>Healthcare systems benefit from OpenAPI's ability to clearly define and validate data structures, ensuring reliable data exchange between different systems. This is crucial for maintaining data integrity and complying with healthcare regulations.</p>
<p><strong>Example:</strong></p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token key atrule" style="color:#b76b01">openapi</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> 3.0.0</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token key atrule" style="color:#b76b01">info</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token key atrule" style="color:#b76b01">title</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> Healthcare API</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token key atrule" style="color:#b76b01">version</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> 1.0.0</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token key atrule" style="color:#b76b01">paths</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  /patients/</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">id</span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token key atrule" style="color:#b76b01">get</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">summary</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> Get patient details</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">parameters</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#b76b01">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> id</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">in</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> path</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">required</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token boolean important" style="color:#C586C0">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">schema</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">responses</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">"200"</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">description</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> A patient object</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">content</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token key atrule" style="color:#b76b01">application/json</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">              </span><span class="token key atrule" style="color:#b76b01">schema</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">                </span><span class="token key atrule" style="color:#b76b01">$ref</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"#/components/schemas/Patient"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token key atrule" style="color:#b76b01">components</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token key atrule" style="color:#b76b01">schemas</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token key atrule" style="color:#b76b01">Patient</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> object</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">properties</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">age</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> integer</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">medicalHistory</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> array</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">items</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>By understanding the strengths and practical applications of GraphQL and OpenAPI, developers can make informed decisions that align with their project's specific needs. GraphQL excels in scenarios requiring real-time updates and flexible data retrieval, while OpenAPI shines in environments where standardization, security, and extensive documentation are crucial.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="performance-and-scalability">Performance and Scalability<a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/#performance-and-scalability" class="hash-link" aria-label="Direct link to Performance and Scalability" title="Direct link to Performance and Scalability">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="performance-considerations">Performance Considerations<a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/#performance-considerations" class="hash-link" aria-label="Direct link to Performance Considerations" title="Direct link to Performance Considerations">​</a></h3>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="response-time-and-data-fetching-efficiency">Response Time and Data Fetching Efficiency<a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/#response-time-and-data-fetching-efficiency" class="hash-link" aria-label="Direct link to Response Time and Data Fetching Efficiency" title="Direct link to Response Time and Data Fetching Efficiency">​</a></h4>
<p>Let's dive deeper into the performance implications of GraphQL vs OpenAPI.</p>
<p>With GraphQL, the ability to request only needed fields can significantly reduce payload sizes. For example, if you're building a mobile app that displays a list of products, you might only need the product name, price, and thumbnail image. In a REST API, you might get all product details including lengthy descriptions, inventory data, etc. This extra data increases the payload size and parsing time on mobile devices.</p>
<p>Here's a concrete example:</p>
<p><strong>REST API response (over-fetching):</strong></p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property" style="color:#C586C0">"id"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">1</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property" style="color:#C586C0">"name"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"Smartphone X"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property" style="color:#C586C0">"price"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">999.99</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property" style="color:#C586C0">"description"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"A very long description..."</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property" style="color:#C586C0">"inventory"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">500</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property" style="color:#C586C0">"categoryId"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">5</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property" style="color:#C586C0">"brandId"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">3</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property" style="color:#C586C0">"specs"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"> ... </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property" style="color:#C586C0">"reviews"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token plain"> ... </span><span class="token punctuation" style="color:#fff">]</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property" style="color:#C586C0">"relatedProducts"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token plain"> ... </span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>GraphQL query and response (precise data):</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property-query">product</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">1</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">price</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">thumbnailUrl</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property" style="color:#C586C0">"data"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">"product"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">"name"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"Smartphone X"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">"price"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">999.99</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">"thumbnailUrl"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"https://example.com/thumb.jpg"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>The GraphQL response is much smaller, leading to faster load times, especially on slower networks.</p>
<p>However, it's not all roses for GraphQL. Complex queries can put a heavier load on your database. For instance, a deeply nested query fetching users, their posts, comments on those posts, and information about the comment authors could result in multiple joins or separate database queries. This is where techniques like DataLoader (for batching and caching) become crucial in GraphQL implementations.</p>
<p>On the OpenAPI side, while over-fetching can be an issue, it also allows for easier caching at the network level (CDNs, reverse proxies) because the responses for a given URL are consistent. Additionally, for simple CRUD operations, the RESTful approach can be more straightforward to implement and may perform better out of the box.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="scalability-challenges">Scalability Challenges<a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/#scalability-challenges" class="hash-link" aria-label="Direct link to Scalability Challenges" title="Direct link to Scalability Challenges">​</a></h3>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="handling-high-traffic-and-data-complexity">Handling High Traffic and Data Complexity<a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/#handling-high-traffic-and-data-complexity" class="hash-link" aria-label="Direct link to Handling High Traffic and Data Complexity" title="Direct link to Handling High Traffic and Data Complexity">​</a></h4>
<p>GraphQL's flexibility is both a blessing and a curse. While it allows for precise data retrieval, it can lead to complex queries that are tough to optimize. Think of it like asking for a custom sandwich with 20 specific ingredients at a busy deli – it can bog down the line. On the other hand, OpenAPI's structured endpoints are more like standard menu items – easier to prepare and scale but might require more trips to get everything you want.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="security-implications">Security Implications<a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/#security-implications" class="hash-link" aria-label="Direct link to Security Implications" title="Direct link to Security Implications">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="security-challenges-in-graphql">Security Challenges in GraphQL<a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/#security-challenges-in-graphql" class="hash-link" aria-label="Direct link to Security Challenges in GraphQL" title="Direct link to Security Challenges in GraphQL">​</a></h3>
<p>GraphQL, with its dynamic nature, brings unique security challenges and opportunities for enhancement. Let's explore these and see how to keep our APIs safe.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="challenges-and-mitigation-strategies">Challenges and Mitigation Strategies<a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/#challenges-and-mitigation-strategies" class="hash-link" aria-label="Direct link to Challenges and Mitigation Strategies" title="Direct link to Challenges and Mitigation Strategies">​</a></h4>
<ol>
<li>
<p><strong>Exposure of Sensitive Data</strong>: GraphQL's power can also be its Achilles' heel if sensitive data isn't properly protected.</p>
<ul>
<li><strong>Field-Level Authorization</strong>: Just like a VIP section in a club, only certain users should have access to specific data fields. Implement fine-grained access controls based on user roles and permissions.</li>
<li><strong>Schema Introspection Control</strong>: Imagine giving a burglar a map of your house. To prevent attackers from discovering your schema, restrict or disable introspection in production environments. Read more about <a href="https://tailcall.run/blog/graphql-introspection-security/" target="_blank" rel="noopener noreferrer">securing GraphQL APIs</a>.</li>
</ul>
</li>
<li>
<p><strong>Query Complexity and Abuse</strong>: GraphQL queries can become deeply nested, leading to performance issues and potential denial-of-service attacks. It's like a never-ending story that overloads your server.</p>
<ul>
<li><strong>Query Complexity Analysis</strong>: Use tools to analyze and limit query complexity, ensuring they don't overload the server. Think of it as having a bouncer who stops overly complicated orders.</li>
<li><strong>Rate Limiting</strong>: Implement rate limiting to control the number of queries a client can execute within a given timeframe. It's like having a doorman who ensures not too many guests enter at once.</li>
</ul>
</li>
<li>
<p><strong>Injection Attacks</strong>: GraphQL is vulnerable to injection attacks if inputs aren't properly sanitized.</p>
<ul>
<li><strong>Input Validation and Sanitization</strong>: Always validate and sanitize all user inputs to prevent injection attacks. It's akin to screening all guests before letting them into the party.</li>
<li><strong>Use of Parameterized Queries</strong>: Where applicable, use parameterized queries to avoid injection vulnerabilities. This ensures the data is handled safely and securely.</li>
</ul>
</li>
</ol>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="security-features-in-openapi">Security Features in OpenAPI<a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/#security-features-in-openapi" class="hash-link" aria-label="Direct link to Security Features in OpenAPI" title="Direct link to Security Features in OpenAPI">​</a></h3>
<p>OpenAPI comes with a range of built-in mechanisms to bolster security. Let's dive into these robust features.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="built-in-mechanisms-and-enhancements">Built-in Mechanisms and Enhancements<a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/#built-in-mechanisms-and-enhancements" class="hash-link" aria-label="Direct link to Built-in Mechanisms and Enhancements" title="Direct link to Built-in Mechanisms and Enhancements">​</a></h4>
<ol>
<li>
<p><strong>Authentication and Authorization</strong>: OpenAPI supports various authentication methods out of the box, ensuring secure access to your APIs.</p>
<ul>
<li><strong>OAuth2</strong>: A robust and flexible framework for authentication and authorization, akin to having a secure, multi-factor locked door.</li>
<li><strong>API Keys</strong>: Simple and effective for identifying and authenticating API consumers. Think of it as a personal access card.</li>
<li><strong>Basic and Bearer Auth</strong>: Standard methods for securing API endpoints, much like having a key to a specific room.</li>
</ul>
</li>
<li>
<p><strong>Data Validation</strong>: OpenAPI uses JSON Schema for defining request and response structures, ensuring data integrity.</p>
<ul>
<li><strong>Schema Validation</strong>: All incoming and outgoing data adheres to predefined schemas, reducing the risk of malformed requests and responses. It's like having a quality control check before anything leaves the factory.</li>
</ul>
</li>
<li>
<p><strong>Security Definitions and Requirements</strong>: OpenAPI allows you to define security requirements at both global and individual operation levels, ensuring consistent enforcement of security policies across your API.</p>
</li>
</ol>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="developer-experience">Developer Experience<a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/#developer-experience" class="hash-link" aria-label="Direct link to Developer Experience" title="Direct link to Developer Experience">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="learning-curve-and-accessibility">Learning Curve and Accessibility<a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/#learning-curve-and-accessibility" class="hash-link" aria-label="Direct link to Learning Curve and Accessibility" title="Direct link to Learning Curve and Accessibility">​</a></h3>
<p>The developer experience difference between GraphQL and OpenAPI goes beyond just the initial learning curve. Let's break this down:</p>
<p><strong>GraphQL:</strong></p>
<ul>
<li>
<p><strong>Learning Curve:</strong> While GraphQL concepts like schemas, resolvers, and the query language itself take time to master, tools like GraphiQL provide an interactive playground that significantly eases the learning process. Developers can explore the API, auto-complete queries, and see instant results.</p>
<p><a href="https://tailcall.run/" target="_blank" rel="noopener noreferrer">Tailcall</a> offers a cost-effective solution for migrating to GraphQL. Which easily integrates with your existing REST/gRPC APIs and provides a seamless transition to GraphQL, smoothing the learning curve for developers.</p>
</li>
<li>
<p><strong>Tooling:</strong> The GraphQL ecosystem has evolved rapidly. Tools like Apollo Client not only help with querying but also provide powerful caching mechanisms, state management, and optimistic UI updates. Here's a quick example of how Apollo Client simplifies data fetching in React:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> </span><span class="token constant" style="color:#C586C0">GET_USER</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> gql</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">  </span><span class="token template-string graphql language-graphql keyword" style="color:#C586C0">query</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql definition-query function" style="color:#FDEA2F">GetUser</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">(</span><span class="token template-string graphql language-graphql variable" style="color:#E36209">$id</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">:</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql scalar" style="color:#8DFFF8">ID</span><span class="token template-string graphql language-graphql operator" style="color:#8DFFF8">!</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">)</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">{</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">    </span><span class="token template-string graphql language-graphql property-query">user</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">(</span><span class="token template-string graphql language-graphql attr-name" style="color:#8DFFF8">id</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">:</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql variable" style="color:#E36209">$id</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">)</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">{</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">      </span><span class="token template-string graphql language-graphql property" style="color:#C586C0">name</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">      </span><span class="token template-string graphql language-graphql property" style="color:#C586C0">email</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">    </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">}</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">  </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">}</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql"></span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">function</span><span class="token plain"> </span><span class="token function maybe-class-name" style="color:#FDEA2F">UserProfile</span><span class="token punctuation" style="color:#fff">(</span><span class="token parameter punctuation" style="color:#fff">{</span><span class="token parameter" style="color:#953800">userId</span><span class="token parameter punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">loading</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> error</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> data</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">useQuery</span><span class="token punctuation" style="color:#fff">(</span><span class="token constant" style="color:#C586C0">GET_USER</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token literal-property property" style="color:#C586C0">variables</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token literal-property property" style="color:#C586C0">id</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> userId</span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">loading</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">&lt;</span><span class="token plain">p</span><span class="token operator" style="color:#8DFFF8">&gt;</span><span class="token maybe-class-name">Loading</span><span class="token spread operator" style="color:#8DFFF8">...</span><span class="token operator" style="color:#8DFFF8">&lt;</span><span class="token operator" style="color:#8DFFF8">/</span><span class="token plain">p</span><span class="token operator" style="color:#8DFFF8">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">&lt;</span><span class="token plain">p</span><span class="token operator" style="color:#8DFFF8">&gt;</span><span class="token known-class-name class-name" style="color:#C586C0">Error</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">:</span><span class="token punctuation" style="color:#fff">(</span><span class="token operator" style="color:#8DFFF8">&lt;</span><span class="token operator" style="color:#8DFFF8">/</span><span class="token plain">p</span><span class="token operator" style="color:#8DFFF8">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">&lt;</span><span class="token plain">h1</span><span class="token operator" style="color:#8DFFF8">&gt;</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">data</span><span class="token punctuation" style="color:#fff">.</span><span class="token property-access">user</span><span class="token punctuation" style="color:#fff">.</span><span class="token property-access">name</span><span class="token punctuation" style="color:#fff">}</span><span class="token operator" style="color:#8DFFF8">&lt;</span><span class="token operator" style="color:#8DFFF8">/</span><span class="token plain">h1</span><span class="token operator" style="color:#8DFFF8">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
</li>
</ul>
<p>This declarative approach to data fetching can significantly simplify frontend code.</p>
<ul>
<li><strong>Type Safety:</strong> GraphQL's strong typing, when combined with tools like TypeScript, can provide end-to-end type safety from your API to your frontend code, catching errors at compile time.</li>
</ul>
<p><strong>OpenAPI:</strong></p>
<ul>
<li>
<p><strong>Familiarity:</strong> For developers already versed in REST principles, OpenAPI feels like a natural extension. Its structure mirrors typical REST endpoints, making it easier to adopt in existing projects.</p>
</li>
<li>
<p><strong>Code Generation:</strong> One of OpenAPI's strengths is the ability to generate both server and client code. For example, using a tool like Swagger Codegen, you can generate a fully functional API client in multiple languages from your OpenAPI spec. This can dramatically speed up development and reduce inconsistencies between API documentation and implementation.</p>
</li>
<li>
<p><strong>Standardization:</strong> OpenAPI's widespread adoption means that many cloud platforms and API gateways natively support OpenAPI specifications. For instance, Azure API Management can import an OpenAPI spec and automatically set up routing, request validation, and even mock responses for testing.</p>
</li>
</ul>
<p>In practice, the choice often comes down to the specific needs of your project and team. GraphQL shines in scenarios with complex, interconnected data and when you need a flexible, powerful query language. OpenAPI excels in scenarios where you need a clear, standards-based approach, especially when working with external partners or in highly regulated environments.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="comparing-the-ease-of-adoption">Comparing the Ease of Adoption<a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/#comparing-the-ease-of-adoption" class="hash-link" aria-label="Direct link to Comparing the Ease of Adoption" title="Direct link to Comparing the Ease of Adoption">​</a></h4>
<ol>
<li>
<p><strong>GraphQL</strong>:</p>
<ul>
<li><strong>Flexibility and Complexity</strong>: GraphQL’s flexibility in querying data can be initially overwhelming for developers accustomed to REST. Learning to structure queries, manage resolvers, and handle errors can take time.</li>
<li><strong>Resources</strong>: Extensive resources, tutorials, and documentation are available, but hands-on experience is crucial for mastering GraphQL.</li>
</ul>
</li>
<li>
<p><strong>OpenAPI</strong>:</p>
<ul>
<li><strong>Structured and Predictable</strong>: OpenAPI’s structured approach is familiar to developers experienced with REST APIs. The clear definition of endpoints, methods, and data models makes it easier to understand and implement.</li>
<li><strong>Tooling</strong>: The extensive tooling and auto-generation capabilities for documentation and client SDKs streamline the development process.</li>
</ul>
</li>
</ol>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion">Conclusion<a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>Having explored the performance and flexibility of GraphQL and OpenAPI, you now have a clearer understanding of their strengths and limitations in different scenarios. GraphQL shines in situations requiring complex, real-time data interactions, while OpenAPI excels in environments where standardization and extensive documentation are paramount. In the next installment, <a href="https://tailcall.run/blog/graphql-vs-openapi-part-3/">Part 3</a>, we will delve into the security aspects, tooling support, and future prospects of GraphQL and OpenAPI, providing a comprehensive overview of how they integrate with existing systems and their compatibility with various development tools.</p>]]></content:encoded>
            <category>GraphQL</category>
            <category>API</category>
            <category>OpenAPI</category>
            <category>Performance</category>
            <category>Flexibility</category>
        </item>
        <item>
            <title><![CDATA[GraphQL vs OpenAPI: Part 1 of the API Comparison Series]]></title>
            <link>https://tailcall.run/blog/graphql-vs-openapi-part-1/</link>
            <guid>https://tailcall.run/blog/graphql-vs-openapi-part-1/</guid>
            <pubDate>Mon, 29 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[An Introduction to GraphQL and OpenAPI, outlining their core concepts and initial setup.]]></description>
            <content:encoded><![CDATA[<p>In today's ever-evolving technological landscape, APIs play a crucial role in enabling software systems to communicate with each other. Among the myriad of API specifications available, GraphQL and OpenAPI stand out as prominent choices, each offering unique advantages and addressing different needs.</p>
<p>This article is the first part of a comprehensive series aimed at comparing these two powerful specifications. By delving into their origins, core concepts, and key features, we aim to provide a clear understanding of what makes GraphQL and OpenAPI distinct and help you make an informed decision when choosing the right API specification for your project. We will explore their approach to data retrieval, type system and validation, schema definition, API documentation, and development ecosystem.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="overview-of-graphql-and-openapi">Overview of GraphQL and OpenAPI<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#overview-of-graphql-and-openapi" class="hash-link" aria-label="Direct link to Overview of GraphQL and OpenAPI" title="Direct link to Overview of GraphQL and OpenAPI">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="graphql">GraphQL<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#graphql" class="hash-link" aria-label="Direct link to GraphQL" title="Direct link to GraphQL">​</a></h3>
<p>Imagine having a magical tool that can fetch exactly what you need, no more, no less—GraphQL is just that! Developed by Facebook in 2012 and open-sourced in 2015, GraphQL is your go-to for flexible, precise API queries. It's like a Swiss Army knife for your data needs, making it a favorite among developers.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="openapi">OpenAPI<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#openapi" class="hash-link" aria-label="Direct link to OpenAPI" title="Direct link to OpenAPI">​</a></h3>
<p>If OpenAPI were a tool, it would be a precisely engineered blueprint for a complex machine, where every part (or API endpoint) is clearly defined and meticulously documented. Initially known as Swagger, OpenAPI was created by SmartBear in 2010 and has since become the gold standard for defining RESTful APIs. This structured approach provided clarity and consistency in several of my projects, making the development process smooth and predictable</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="importance-of-choosing-the-right-api-specification">Importance of Choosing the Right API Specification<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#importance-of-choosing-the-right-api-specification" class="hash-link" aria-label="Direct link to Importance of Choosing the Right API Specification" title="Direct link to Importance of Choosing the Right API Specification">​</a></h3>
<p>Choosing between GraphQL and OpenAPI? Buckle up, because this decision will steer your development workflow, performance, scalability, and ultimately, the success of your project. Let's dive into their differences and find out which one suits your needs best!</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="quick-comparison-table-graphql-vs-openapi-at-a-glance">Quick Comparison Table: GraphQL vs OpenAPI at a Glance<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#quick-comparison-table-graphql-vs-openapi-at-a-glance" class="hash-link" aria-label="Direct link to Quick Comparison Table: GraphQL vs OpenAPI at a Glance" title="Direct link to Quick Comparison Table: GraphQL vs OpenAPI at a Glance">​</a></h3>
<table><thead><tr><th>Feature</th><th>GraphQL</th><th>OpenAPI</th></tr></thead><tbody><tr><td>Data Retrieval</td><td>Query Language</td><td>REST Endpoints</td></tr><tr><td>Schema Definition</td><td>SDL</td><td>Swagger</td></tr><tr><td>API Documentation</td><td>Self-Documenting</td><td>Manual/Auto-Generated</td></tr><tr><td>Typing</td><td>Strong Typing at Runtime</td><td>Schema Validation</td></tr><tr><td>Performance</td><td>Efficient Data Fetching</td><td>Standardized Operations</td></tr><tr><td>Scalability</td><td>Handles Complex Queries</td><td>Reliable for High Traffic</td></tr><tr><td>Security</td><td>Custom Security Measures</td><td>Built-in Mechanisms</td></tr></tbody></table>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="understanding-the-fundamentals">Understanding the Fundamentals<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#understanding-the-fundamentals" class="hash-link" aria-label="Direct link to Understanding the Fundamentals" title="Direct link to Understanding the Fundamentals">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="a-what-is-graphql">A. What is GraphQL?<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#a-what-is-graphql" class="hash-link" aria-label="Direct link to A. What is GraphQL?" title="Direct link to A. What is GraphQL?">​</a></h3>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="definition-and-core-features">Definition and Core Features<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#definition-and-core-features" class="hash-link" aria-label="Direct link to Definition and Core Features" title="Direct link to Definition and Core Features">​</a></h4>
<p>Think of GraphQL as a master chef who takes your order (query) and prepares exactly what you want, without any extras. It's a flexible query language for APIs, allowing clients to request precise data and get exactly what they need. <a href="https://tailcall.run/graphql/what-is-graphql/">Read More!"</a></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="b-what-is-openapi">B. What is OpenAPI?<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#b-what-is-openapi" class="hash-link" aria-label="Direct link to B. What is OpenAPI?" title="Direct link to B. What is OpenAPI?">​</a></h3>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="definition-and-core-features-1">Definition and Core Features<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#definition-and-core-features-1" class="hash-link" aria-label="Direct link to Definition and Core Features" title="Direct link to Definition and Core Features">​</a></h4>
<p>Initially known as Swagger, OpenAPI was crafted by SmartBear in 2010 and has since become the go-to standard for defining RESTful APIs. It provides a comprehensive framework for defining APIs, allowing both humans and machines to understand the capabilities of a service without accessing its source code.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="key-differences">Key Differences<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#key-differences" class="hash-link" aria-label="Direct link to Key Differences" title="Direct link to Key Differences">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="a-approach-to-data-retrieval">A. Approach to Data Retrieval<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#a-approach-to-data-retrieval" class="hash-link" aria-label="Direct link to A. Approach to Data Retrieval" title="Direct link to A. Approach to Data Retrieval">​</a></h3>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="graphql-query-language-vs-openapi-rest-endpoints">GraphQL Query Language vs OpenAPI REST Endpoints<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#graphql-query-language-vs-openapi-rest-endpoints" class="hash-link" aria-label="Direct link to GraphQL Query Language vs OpenAPI REST Endpoints" title="Direct link to GraphQL Query Language vs OpenAPI REST Endpoints">​</a></h4>
<p>GraphQL allows clients to define the structure of the response, making it highly flexible. OpenAPI, on the other hand, relies on predefined endpoints for data retrieval.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="graphql-query-flexibility">GraphQL: Query Flexibility<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#graphql-query-flexibility" class="hash-link" aria-label="Direct link to GraphQL: Query Flexibility" title="Direct link to GraphQL: Query Flexibility">​</a></h4>
<p>GraphQL's query flexibility is a game-changer for frontend developers. Imagine you're building a user profile page that needs to display a user's name, email, recent posts, and follower count. With a REST API, you might need to make multiple requests to different endpoints (/user, /posts, /followers) to gather all this data. But with GraphQL, you can request all this information in a single query:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property-query">user</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"123"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">email</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property-query">recentPosts</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">limit</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">5</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">title</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">date</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">followerCount</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This not only reduces the number of network requests but also eliminates over-fetching of data. If you only need the user's name and email, you simply omit the other fields from your query. This flexibility allows frontend developers to iterate quickly without waiting for backend changes, significantly speeding up development cycles.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="openapi-defined-endpoints">OpenAPI: Defined Endpoints<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#openapi-defined-endpoints" class="hash-link" aria-label="Direct link to OpenAPI: Defined Endpoints" title="Direct link to OpenAPI: Defined Endpoints">​</a></h4>
<p>OpenAPI follows the REST architecture, where each endpoint corresponds to a specific resource or action, providing a clear structure but less flexibility.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="b-type-system-and-validation">B. Type System and Validation<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#b-type-system-and-validation" class="hash-link" aria-label="Direct link to B. Type System and Validation" title="Direct link to B. Type System and Validation">​</a></h3>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="graphql-strong-typing-at-runtime">GraphQL: Strong Typing at Runtime<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#graphql-strong-typing-at-runtime" class="hash-link" aria-label="Direct link to GraphQL: Strong Typing at Runtime" title="Direct link to GraphQL: Strong Typing at Runtime">​</a></h4>
<p>GraphQL uses a robust type system to validate queries at runtime, ensuring clients only request valid data and fields. This strong typing mechanism helps prevent errors before they occur by enforcing a strict schema that defines the types of data that can be queried and the relationships between different data entities. By validating queries against this schema, GraphQL ensures that clients can only access the data they are permitted to and that they do so in a predictable manner. This type safety not only improves the reliability of the API but also enhances developer productivity by providing clear, self-documenting APIs.</p>
<p>Example GraphQL Schema:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">email</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">posts</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">Post</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">title</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">content</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">author</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">user</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">allUsers</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">User</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">post</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Post</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">allPosts</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">Post</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Mutation</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">createUser</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token attr-name" style="color:#8DFFF8">email</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">createPost</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">title</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">content</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">authorId</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Post</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Example GraphQL Query:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property-query">user</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"123"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">id</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">email</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token object">posts</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">id</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">title</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">content</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token object">allPosts</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">id</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">title</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">content</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token object">author</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">id</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>In this example, the schema defines User and Post types, their fields, and the relationships between them. The Query type includes operations for fetching users and posts, and the Mutation type includes operations for creating users and posts. The query fetches a specific user and their posts, as well as all posts and their authors.</p>
<p>For a deeper dive into GraphQL schemas and types, you can explore <a href="https://tailcall.run/graphql/schemas-and-types/">this resource</a>.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="openapi-schema-validation">OpenAPI: Schema Validation<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#openapi-schema-validation" class="hash-link" aria-label="Direct link to OpenAPI: Schema Validation" title="Direct link to OpenAPI: Schema Validation">​</a></h4>
<p>OpenAPI's use of JSON/YAML Schema for validation is more powerful than it might initially appear. Let's break this down with an example. Suppose you're building an e-commerce API. You could define a product schema like this:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token key atrule" style="color:#b76b01">components</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token key atrule" style="color:#b76b01">schemas</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token key atrule" style="color:#b76b01">Product</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> object</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">required</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">-</span><span class="token plain"> id</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">-</span><span class="token plain"> name</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">-</span><span class="token plain"> price</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">properties</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> integer</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">minLength</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">maxLength</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">100</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">price</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> number</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">minimum</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">0</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">description</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">categories</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> array</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">items</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This schema does more than just define the structure. It enforces business rules:</p>
<ul>
<li>
<p>Products must have an id, name, and price (required fields)</p>
</li>
<li>
<p>Product names must be between 1 and 100 characters</p>
</li>
<li>
<p>Prices can't be negative</p>
</li>
</ul>
<p>By defining these constraints in the OpenAPI spec, you're not just documenting your API - you're creating a contract that can be enforced by API gateways, automatically validated in tests, and used to generate accurate client SDKs. This level of detail at the design stage catches errors early, improves API consistency, and significantly reduces the likelihood of bugs in production.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="c-schema-definition">C. Schema Definition<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#c-schema-definition" class="hash-link" aria-label="Direct link to C. Schema Definition" title="Direct link to C. Schema Definition">​</a></h3>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="graphql-sdl-vs-openapi-swagger">GraphQL SDL vs OpenAPI Swagger<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#graphql-sdl-vs-openapi-swagger" class="hash-link" aria-label="Direct link to GraphQL SDL vs OpenAPI Swagger" title="Direct link to GraphQL SDL vs OpenAPI Swagger">​</a></h4>
<p>GraphQL and OpenAPI use different approaches to define and document their APIs.</p>
<p><strong>GraphQL: Schema Definition Language (SDL)</strong></p>
<p>GraphQL uses the Schema Definition Language (SDL) to define the types and relationships within an API. SDL is a human-readable language that allows developers to describe the data structures and operations available on the GraphQL server. This schema acts as a contract between the client and server, ensuring that all queries and mutations adhere to the defined types and structures.</p>
<p><strong>Example of GraphQL SDL:</strong></p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">email</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">posts</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">Post</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">title</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">content</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">author</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">user</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">allUsers</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">User</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">post</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Post</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">allPosts</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">Post</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Mutation</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">createUser</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token attr-name" style="color:#8DFFF8">email</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">createPost</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">title</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">content</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">authorId</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Post</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>In this example, the schema defines <code>User</code> and <code>Post</code> types, their fields, and the relationships between them. It also defines queries to fetch users and posts, and mutations to create new users and posts.</p>
<p><strong>OpenAPI: Swagger</strong></p>
<p>OpenAPI uses JSON or YAML to describe endpoints, parameters, and responses. This specification format allows for detailed documentation of RESTful APIs, including request and response formats, authentication methods, and error handling. OpenAPI specifications can be used to generate API documentation, client SDKs, and server stubs, making it a comprehensive tool for API development.</p>
<p><strong>Example of OpenAPI Swagger (YAML format):</strong></p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token key atrule" style="color:#b76b01">openapi</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> 3.0.0</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token key atrule" style="color:#b76b01">info</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token key atrule" style="color:#b76b01">title</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> Example API</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token key atrule" style="color:#b76b01">version</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> 1.0.0</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token key atrule" style="color:#b76b01">paths</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token key atrule" style="color:#b76b01">/users</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token key atrule" style="color:#b76b01">get</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">summary</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> Get a list of users</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">responses</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">"200"</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">description</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> A list of users</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">content</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token key atrule" style="color:#b76b01">application/json</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">              </span><span class="token key atrule" style="color:#b76b01">schema</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">                </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> array</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">                </span><span class="token key atrule" style="color:#b76b01">items</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">                  </span><span class="token key atrule" style="color:#b76b01">$ref</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"#/components/schemas/User"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  /users/</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">id</span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token key atrule" style="color:#b76b01">get</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">summary</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> Get a user by ID</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">parameters</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#b76b01">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> id</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">in</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> path</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">required</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token boolean important" style="color:#C586C0">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">schema</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">responses</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">"200"</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">description</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> A user object</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">content</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token key atrule" style="color:#b76b01">application/json</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">              </span><span class="token key atrule" style="color:#b76b01">schema</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">                </span><span class="token key atrule" style="color:#b76b01">$ref</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"#/components/schemas/User"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token key atrule" style="color:#b76b01">/posts</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token key atrule" style="color:#b76b01">post</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">summary</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> Create a new post</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">requestBody</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">required</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token boolean important" style="color:#C586C0">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">content</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">application/json</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token key atrule" style="color:#b76b01">schema</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">              </span><span class="token key atrule" style="color:#b76b01">$ref</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"#/components/schemas/Post"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">responses</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">"201"</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">description</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> The created post</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">content</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token key atrule" style="color:#b76b01">application/json</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">              </span><span class="token key atrule" style="color:#b76b01">schema</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">                </span><span class="token key atrule" style="color:#b76b01">$ref</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"#/components/schemas/Post"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token key atrule" style="color:#b76b01">components</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token key atrule" style="color:#b76b01">schemas</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token key atrule" style="color:#b76b01">User</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> object</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">properties</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">email</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token key atrule" style="color:#b76b01">Post</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> object</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">properties</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">title</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">content</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">authorId</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>In this OpenAPI example, the specification defines paths for fetching users and creating posts, along with the necessary parameters and responses. It also defines the <code>User</code> and <code>Post</code> schemas used in the API.</p>
<p>By using these tools, both GraphQL and OpenAPI provide clear, structured ways to define and document APIs, each with their own strengths and use cases.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="d-api-documentation">D. API Documentation<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#d-api-documentation" class="hash-link" aria-label="Direct link to D. API Documentation" title="Direct link to D. API Documentation">​</a></h3>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="graphql-self-documenting">GraphQL: Self-Documenting<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#graphql-self-documenting" class="hash-link" aria-label="Direct link to GraphQL: Self-Documenting" title="Direct link to GraphQL: Self-Documenting">​</a></h4>
<p>GraphQL schemas are inherently self-documenting, allowing clients to introspect the schema and understand available operations. Tools like GraphiQL provide an interactive environment where developers can explore the schema, view available types and fields, and see the relationships between different data entities. This self-documenting feature of GraphQL significantly enhances the developer experience by providing built-in API documentation.</p>
<p><strong>Example: GraphiQL Interface</strong></p>
<p>To demonstrate, let's use the Star Wars API (SWAPI) GraphiQL endpoint <a href="https://graphql.github.io/swapi-graphql/" target="_blank" rel="noopener noreferrer">here</a>. By navigating to the SWAPI GraphQL interface, you can interact with the API and see how the schema is documented.</p>
<p>Example Query:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token object">allFilms</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token object">films</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">title</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">director</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">releaseDate</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token object">allPeople</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token object">people</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">birthYear</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token object">homeworld</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This query fetches details about films and characters from the Star Wars universe. The GraphiQL interface allows you to see the available types, queries, and fields in the documentation tab.</p>
<p>GraphiQL Documentation Snapshot:</p>
<p>In this snapshot of the GraphiQL interface, you can see the documentation tab open, displaying the schema with types and fields such as Film and Person, with fields like title, director, releaseDate, name, birthYear, and homeworld. This clean and professional interface reflects the self-documenting nature of GraphQL schemas, making it easy for developers to understand and use the API effectively.</p>
<p>By using the introspection capabilities of GraphQL and tools like GraphiQL, developers can quickly get up to speed with the API and explore its capabilities interactively.</p>
<p><img decoding="async" loading="lazy" alt="snapshot-graphiql" src="https://tailcall.run/assets/images/snapshot-graphiql-27e9d889571a2aec8f3066b1e185bd05.png" width="1874" height="923" class="img_ev3q"></p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="openapi-manual-and-auto-generated-options">OpenAPI: Manual and Auto-Generated Options<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#openapi-manual-and-auto-generated-options" class="hash-link" aria-label="Direct link to OpenAPI: Manual and Auto-Generated Options" title="Direct link to OpenAPI: Manual and Auto-Generated Options">​</a></h4>
<p>OpenAPI supports both manual and auto-generated documentation, which enhances the ease of sharing API details. Tools like Swagger UI allow developers to create interactive API documentation that can be explored and tested directly from the browser. This makes it easier for both developers and non-developers to understand and interact with the API.</p>
<p><strong>Example: Spotify API Documentation</strong></p>
<p>Spotify uses OpenAPI to provide comprehensive and interactive API documentation. Their public-facing documentation, which can be accessed <a href="https://developer.spotify.com/documentation/web-api/" target="_blank" rel="noopener noreferrer">here</a>, showcases the power of auto-generated documentation. With detailed descriptions of endpoints, parameters, and response formats, along with interactive features to test the API, Spotify's documentation serves as an excellent example of how OpenAPI can streamline the process of API development and consumption.</p>
<p><strong>Swagger UI Example:</strong></p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token key atrule" style="color:#b76b01">openapi</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> 3.0.0</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token key atrule" style="color:#b76b01">info</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token key atrule" style="color:#b76b01">title</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> Spotify API</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token key atrule" style="color:#b76b01">version</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> 1.0.0</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token key atrule" style="color:#b76b01">paths</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  /tracks/</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">id</span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token key atrule" style="color:#b76b01">get</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">summary</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> Get a track</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">parameters</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#b76b01">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> id</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">in</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> path</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">required</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token boolean important" style="color:#C586C0">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">schema</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">responses</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">"200"</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">description</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> A track object</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">content</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token key atrule" style="color:#b76b01">application/json</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">              </span><span class="token key atrule" style="color:#b76b01">schema</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">                </span><span class="token key atrule" style="color:#b76b01">$ref</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"#/components/schemas/Track"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token key atrule" style="color:#b76b01">components</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token key atrule" style="color:#b76b01">schemas</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token key atrule" style="color:#b76b01">Track</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> object</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">properties</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">artist</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">album</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>With Swagger UI, this specification can be rendered into a fully interactive API documentation interface, where users can explore different endpoints, see example requests and responses, and even try out API calls directly from the documentation page. This approach not only improves the developer experience but also helps in maintaining up-to-date and accessible API documentation.</p>
<p>Below, we have a snapshot of the Spotify OpenAPI documentation:</p>
<p><img decoding="async" loading="lazy" alt="spotify-swagger" src="https://tailcall.run/assets/images/snapshot-spotifyOpenAPI-0e1435664ff654f5cd99f242189794a4.png" width="1600" height="799" class="img_ev3q"></p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="openapi-manual-and-auto-generated-options-1">OpenAPI: Manual and Auto-Generated Options<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#openapi-manual-and-auto-generated-options-1" class="hash-link" aria-label="Direct link to OpenAPI: Manual and Auto-Generated Options" title="Direct link to OpenAPI: Manual and Auto-Generated Options">​</a></h4>
<p>OpenAPI supports both manual and auto-generated documentation through tools like Swagger UI, making it easier to share API details.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="e-development-ecosystem">E. Development Ecosystem<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#e-development-ecosystem" class="hash-link" aria-label="Direct link to E. Development Ecosystem" title="Direct link to E. Development Ecosystem">​</a></h3>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="comparison-of-tooling-and-community-support">Comparison of Tooling and Community Support<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#comparison-of-tooling-and-community-support" class="hash-link" aria-label="Direct link to Comparison of Tooling and Community Support" title="Direct link to Comparison of Tooling and Community Support">​</a></h4>
<p>Both GraphQL and OpenAPI have extensive ecosystems with robust tooling and strong community support, each catering to different aspects of API development.</p>
<p><strong>GraphQL:</strong></p>
<p>GraphQL has a vibrant and rapidly growing ecosystem. Some of the most popular tools include:</p>
<ul>
<li><strong>Apollo:</strong> Apollo provides a suite of tools for building, querying, and managing GraphQL APIs. Apollo Client simplifies data fetching in frontend applications by providing features like caching, state management, and real-time updates through subscriptions. Apollo Server helps in creating a GraphQL server with minimal setup and integrates well with various data sources and services.</li>
</ul>
<p><strong>Example:</strong></p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token comment" style="color:#30C26D;font-style:italic">// Apollo Client setup</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword module" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#fff">{</span><span class="token imports"></span><br></span><span class="token-line" style="color:#fff"><span class="token imports">  </span><span class="token imports maybe-class-name">ApolloClient</span><span class="token imports punctuation" style="color:#fff">,</span><span class="token imports"></span><br></span><span class="token-line" style="color:#fff"><span class="token imports">  </span><span class="token imports maybe-class-name">InMemoryCache</span><span class="token imports punctuation" style="color:#fff">,</span><span class="token imports"></span><br></span><span class="token-line" style="color:#fff"><span class="token imports">  gql</span><span class="token imports punctuation" style="color:#fff">,</span><span class="token imports"></span><br></span><span class="token-line" style="color:#fff"><span class="token imports"></span><span class="token imports punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@apollo/client"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> client </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">ApolloClient</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token literal-property property" style="color:#C586C0">uri</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"https://example.com/graphql"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token literal-property property" style="color:#C586C0">cache</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">InMemoryCache</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">client</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">.</span><span class="token method function property-access" style="color:#FDEA2F">query</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token literal-property property" style="color:#C586C0">query</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> gql</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">      </span><span class="token template-string graphql language-graphql keyword" style="color:#C586C0">query</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql definition-query function" style="color:#FDEA2F">GetUsers</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">{</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">        </span><span class="token template-string graphql language-graphql object">users</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">{</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">          </span><span class="token template-string graphql language-graphql property" style="color:#C586C0">id</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">          </span><span class="token template-string graphql language-graphql property" style="color:#C586C0">name</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">        </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">}</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">      </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">}</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">    </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">.</span><span class="token method function property-access" style="color:#FDEA2F">then</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">(</span><span class="token parameter" style="color:#953800">result</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> </span><span class="token console class-name" style="color:#C586C0">console</span><span class="token punctuation" style="color:#fff">.</span><span class="token method function property-access" style="color:#FDEA2F">log</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">result</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<ul>
<li><strong>Relay:</strong> Developed by Facebook, Relay is a JavaScript framework for building data-driven React applications with GraphQL. It focuses on efficient data fetching, minimizing the amount of data sent over the network, and ensuring that the data fetched is always up to date.</li>
</ul>
<p><strong>Example:</strong></p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token comment" style="color:#30C26D;font-style:italic">// Relay setup</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword module" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#fff">{</span><span class="token imports"></span><br></span><span class="token-line" style="color:#fff"><span class="token imports">  </span><span class="token imports maybe-class-name">Environment</span><span class="token imports punctuation" style="color:#fff">,</span><span class="token imports"></span><br></span><span class="token-line" style="color:#fff"><span class="token imports">  </span><span class="token imports maybe-class-name">Network</span><span class="token imports punctuation" style="color:#fff">,</span><span class="token imports"></span><br></span><span class="token-line" style="color:#fff"><span class="token imports">  </span><span class="token imports maybe-class-name">RecordSource</span><span class="token imports punctuation" style="color:#fff">,</span><span class="token imports"></span><br></span><span class="token-line" style="color:#fff"><span class="token imports">  </span><span class="token imports maybe-class-name">Store</span><span class="token imports punctuation" style="color:#fff">,</span><span class="token imports"></span><br></span><span class="token-line" style="color:#fff"><span class="token imports"></span><span class="token imports punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"relay-runtime"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#FDEA2F">fetchQuery</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token parameter" style="color:#953800">operation</span><span class="token parameter punctuation" style="color:#fff">,</span><span class="token parameter" style="color:#953800"> variables</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">fetch</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">"https://example.com/graphql"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token literal-property property" style="color:#C586C0">method</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"POST"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token literal-property property" style="color:#C586C0">headers</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token string-property property" style="color:#C586C0">"Content-Type"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"application/json"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token literal-property property" style="color:#C586C0">body</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token known-class-name class-name" style="color:#C586C0">JSON</span><span class="token punctuation" style="color:#fff">.</span><span class="token method function property-access" style="color:#FDEA2F">stringify</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token literal-property property" style="color:#C586C0">query</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> operation</span><span class="token punctuation" style="color:#fff">.</span><span class="token property-access">text</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      variables</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">.</span><span class="token method function property-access" style="color:#FDEA2F">then</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">(</span><span class="token parameter" style="color:#953800">response</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> response</span><span class="token punctuation" style="color:#fff">.</span><span class="token method function property-access" style="color:#FDEA2F">json</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> environment </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Environment</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token literal-property property" style="color:#C586C0">network</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token maybe-class-name">Network</span><span class="token punctuation" style="color:#fff">.</span><span class="token method function property-access" style="color:#FDEA2F">create</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">fetchQuery</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token literal-property property" style="color:#C586C0">store</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Store</span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">RecordSource</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>The community around GraphQL is active and supportive, with numerous tutorials, documentation, and forums available to help developers at all levels.</p>
<p><strong>OpenAPI:</strong></p>
<p>OpenAPI has a well-established community and a mature ecosystem. Some of the most prominent tools include:</p>
<ul>
<li><strong>Swagger:</strong> Swagger is a suite of tools that helps design, build, document, and consume RESTful web services. Swagger Editor allows you to design APIs in a user-friendly interface and generate interactive API documentation. Swagger Codegen can generate client SDKs and server stubs in various programming languages from an OpenAPI specification.</li>
</ul>
<p><strong>Example:</strong></p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token key atrule" style="color:#b76b01">openapi</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> 3.0.0</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token key atrule" style="color:#b76b01">info</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token key atrule" style="color:#b76b01">title</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> Sample API</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token key atrule" style="color:#b76b01">version</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> 1.0.0</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token key atrule" style="color:#b76b01">paths</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token key atrule" style="color:#b76b01">/users</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token key atrule" style="color:#b76b01">get</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">summary</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> Retrieves a list of users</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">responses</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">"200"</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">description</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> A list of users</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">content</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token key atrule" style="color:#b76b01">application/json</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">              </span><span class="token key atrule" style="color:#b76b01">schema</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">                </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> array</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">                </span><span class="token key atrule" style="color:#b76b01">items</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">                  </span><span class="token key atrule" style="color:#b76b01">$ref</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"#/components/schemas/User"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token key atrule" style="color:#b76b01">components</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token key atrule" style="color:#b76b01">schemas</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token key atrule" style="color:#b76b01">User</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> object</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token key atrule" style="color:#b76b01">properties</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token key atrule" style="color:#b76b01">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token key atrule" style="color:#b76b01">type</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> string</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<ul>
<li><strong>Postman:</strong> Postman is a popular tool for API development and testing. It allows developers to create and test API requests, automate testing with scripts, and manage environments and variables. Postman can import OpenAPI specifications to quickly generate requests and document APIs.</li>
</ul>
<p><strong>Example:</strong></p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token string-property property" style="color:#C586C0">"info"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token string-property property" style="color:#C586C0">"name"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"Sample API"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token string-property property" style="color:#C586C0">"item"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token string-property property" style="color:#C586C0">"name"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"Get Users"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token string-property property" style="color:#C586C0">"request"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token string-property property" style="color:#C586C0">"method"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"GET"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token string-property property" style="color:#C586C0">"url"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token string-property property" style="color:#C586C0">"raw"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"https://example.com/users"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token string-property property" style="color:#C586C0">"protocol"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"https"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token string-property property" style="color:#C586C0">"host"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token string" style="color:#FDB869">"example"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"com"</span><span class="token punctuation" style="color:#fff">]</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token string-property property" style="color:#C586C0">"path"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token string" style="color:#FDB869">"users"</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<ul>
<li><strong>Insomnia:</strong> Insomnia is another powerful tool for API design and testing, supporting both REST and GraphQL. It provides features like environment variables, plugin support, and code generation from API definitions, making it a versatile choice for API development.</li>
</ul>
<p>The OpenAPI community has been around for a long time, providing extensive documentation, guides, and support forums. This mature ecosystem ensures that developers have access to a wealth of resources to help them design, document, and consume APIs effectively.</p>
<p>By leveraging these tools and community support, developers can streamline their API development processes, ensuring robust and well-documented APIs for their applications..</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion">Conclusion<a href="https://tailcall.run/blog/graphql-vs-openapi-part-1/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>As we wrap up this introduction to GraphQL and OpenAPI, it's clear that both have their unique advantages and use cases. GraphQL excels in offering flexible, precise data queries, while OpenAPI provides a structured, standardized approach to defining RESTful APIs. In the <a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/">next part</a> of our series, we will compare their performance, flexibility, and ease of use in greater detail, providing insights into how they fare in real-world scenarios.</p>
<p>Stay tuned for the <a href="https://tailcall.run/blog/graphql-vs-openapi-part-2/">next part</a> to learn more about how these API specifications can impact your development workflow and project success.</p>]]></content:encoded>
            <category>GraphQL</category>
            <category>API</category>
            <category>OpenAPI</category>
        </item>
        <item>
            <title><![CDATA[GraphQL vs gRPC: Which is Better? Uncover the Best Choice!]]></title>
            <link>https://tailcall.run/blog/graphql-vs-grpc/</link>
            <guid>https://tailcall.run/blog/graphql-vs-grpc/</guid>
            <pubDate>Fri, 26 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Discover the differences between GraphQL and gRPC. Learn which is better for your needs in this comprehensive guide. Find out now!]]></description>
            <content:encoded><![CDATA[<p>While REST has been the go-to for API development, gRPC and GraphQL are stepping in as game-changing contenders.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="introduction">Introduction<a href="https://tailcall.run/blog/graphql-vs-grpc/#introduction" class="hash-link" aria-label="Direct link to Introduction" title="Direct link to Introduction">​</a></h2>
<p>When it comes to choosing the tech stack for your application, it's never a straightforward task, especially when choosing between gRPC and graphQL - both backed by tech giants. Follow us as we discuss real world scenarios and perform a detailed feature-comparison on both, concluding exactly where each should be used.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-problem">The Problem<a href="https://tailcall.run/blog/graphql-vs-grpc/#the-problem" class="hash-link" aria-label="Direct link to The Problem" title="Direct link to The Problem">​</a></h2>
<p>Let’s say you are building a social app like Reddit, and you have screens like home and popular. You implement a simple REST API on the backend and everything looks fine:</p>
<ul>
<li>it wasn’t so challenging to setup</li>
<li>has tons of resources if anything goes wrong</li>
<li>seems like a perfect solution.</li>
</ul>
<p>Until the user base grows and there’s thousands of users - and disaster strikes: the loading times increase and the costs skyrocket, you begin to lose engagement of the users.</p>
<p>Deep down, the root cause of this problem is the slow nature of REST and over-fetching. What happens is that when a user opens the app, goes to the home screen, and the app fetches tons of unnecessary data from the backend: all pictures of a post, all comments and even related posts! Which is even worsened by the fact that the client has to call multiple endpoints to finally show the feed to the user. You are stuck in performance jargon, let’s rewind it. You use graphQL instead of REST, which has many advantages over the REST:</p>
<ul>
<li>thanks to its predefined schemas you don’t have to spend hours writing simple validation tests to check that a parameter is a number and not a string.</li>
<li>graphQL only serves what the client asks for, which means there’s no chance of over-fetching</li>
<li>not to mention that one endpoint of graphQL is more useful and comprehensive than 5 REST API routes.</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="knowing-grpc">Knowing gRPC<a href="https://tailcall.run/blog/graphql-vs-grpc/#knowing-grpc" class="hash-link" aria-label="Direct link to Knowing gRPC" title="Direct link to Knowing gRPC">​</a></h2>
<p>So what is behind the magic of gRPC ? Since Google open-sourced it in 2015, gRPC has been revolutionizing service-to-service communication with its robust, schema-driven framework. By harnessing the power of HTTP/2 and Protocol Buffers (Protobuf), gRPC unleashes high-performance, real-time data streaming and rock-solid typing - a winning combo that's made it a go-to tool for developers building scalable, efficient systems. No wonder tech titans like <a href="https://theirstack.com/en/technology/grpc" target="_blank" rel="noopener noreferrer">Tesla, Netflix, Coinbase and Dropbox</a> are all on board!</p>
<p>Read more about <a href="https://tailcall.run/blog/what-is-grpc/">What is gRPC</a>.</p>
<p><img decoding="async" loading="lazy" alt="companies using grpc" src="https://tailcall.run/assets/images/stack-grpc-45c00a79d8245dff061c371bd30a8ace.png" width="1127" height="402" class="img_ev3q"></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="unleashing-graphql-magic">Unleashing GraphQL Magic!<a href="https://tailcall.run/blog/graphql-vs-grpc/#unleashing-graphql-magic" class="hash-link" aria-label="Direct link to Unleashing GraphQL Magic!" title="Direct link to Unleashing GraphQL Magic!">​</a></h2>
<p>GraphQL, born at Facebook in 2012 and unleashed to the world in 2015, revolutionizes API queries. It’s a powerful and flexible alternative to REST APIs, featuring declarative data fetching that ensures you get just the data you need—no more, no less. With a single endpoint, GraphQL simplifies API structures, eliminating the hassle of managing multiple endpoints. This efficiency and flexibility have made it the darling of tech giants like <a href="https://landscape.graphql.org/borderless-mode?grouping=category" target="_blank" rel="noopener noreferrer">Github, Meta, Shopify and Microsoft </a>. With GraphQL, you can build more efficient and intuitive APIs that make data fetching a breeze!</p>
<p>Read more about <a href="https://tailcall.run/graphql/what-is-graphql/">What is GraphQL and How it works?</a>.</p>
<p><img decoding="async" loading="lazy" alt="companies using graphql" src="https://tailcall.run/assets/images/stack-graphql-7437c6d607951f46a04946b5289c54f2.png" width="974" height="249" class="img_ev3q"></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="feature-comparison">Feature Comparison<a href="https://tailcall.run/blog/graphql-vs-grpc/#feature-comparison" class="hash-link" aria-label="Direct link to Feature Comparison" title="Direct link to Feature Comparison">​</a></h2>
<table><thead><tr><th>Feature</th><th>gRPC</th><th>GraphQL</th></tr></thead><tbody><tr><td><strong>Message Format</strong></td><td>Binary</td><td>JSON</td></tr><tr><td><strong>Data Fetching</strong></td><td>Fixed endpoints and methods</td><td>Flexible queries, specified by clients</td></tr><tr><td><strong>Real-Time</strong></td><td>Supports streaming via server-side push</td><td>Supports real-time updates via subscriptions</td></tr><tr><td><strong>Type Safety</strong></td><td>Strongly typed with Protocol Buffers</td><td>Strongly typed with schema definition</td></tr><tr><td><strong>Introspection</strong></td><td>No built-in introspection</td><td>Built-in schema introspection</td></tr><tr><td><strong>Code Generation</strong></td><td>Automatic code generation from .proto files</td><td>Code generation tools available, but not automatic</td></tr><tr><td><strong>Tooling and Browser Support</strong></td><td>Limited browser support, requires proxies for web use</td><td>Strong tooling support, works natively in browsers</td></tr><tr><td><strong>Community</strong></td><td>currently nascent</td><td>Growing rapidly, strong in web and mobile development</td></tr><tr><td><strong>Adoption</strong></td><td>widely in microservices</td><td>mostly in mobile app development and <a href="https://en.wikipedia.org/wiki/Progressive_web_app" target="_blank" rel="noopener noreferrer">PWA</a>s</td></tr><tr><td><strong>Performance</strong></td><td>High performance with low latency</td><td>Generally efficient, schemas defined correctly</td></tr><tr><td><strong>Debugging and Troubleshooting</strong></td><td>non-human-readable format, require tools for debugging.</td><td>JSON response is easier to read and debug</td></tr></tbody></table>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="scenarios-for-using-grpc">Scenarios for Using gRPC<a href="https://tailcall.run/blog/graphql-vs-grpc/#scenarios-for-using-grpc" class="hash-link" aria-label="Direct link to Scenarios for Using gRPC" title="Direct link to Scenarios for Using gRPC">​</a></h2>
<p>The ideal scenario for gRPC? When microservices need to communicate at lightning speed and with top-notch efficiency! Think of gRPC as the ultimate express lane for data—perfect when you need swift, reliable interactions and don’t need to be super flexible. It’s like having a fast track for your information, keeping everything running smoothly and quickly!</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="scenario-1-a-social-media-app-backend">Scenario 1: A social media app backend<a href="https://tailcall.run/blog/graphql-vs-grpc/#scenario-1-a-social-media-app-backend" class="hash-link" aria-label="Direct link to Scenario 1: A social media app backend" title="Direct link to Scenario 1: A social media app backend">​</a></h3>
<p><img decoding="async" loading="lazy" alt="sm app example" src="https://tailcall.run/assets/images/services-4a44138776f5d5ceb658195b481afee7.png" width="1176" height="561" class="img_ev3q"></p>
<p>Imagine a social media app where everything works like clockwork. Here’s how gRPC fits in:
The Cast:</p>
<ul>
<li>Media-Scanner: Analyzes media files with precision.</li>
<li>Media-Tagger: Tags content accurately.</li>
<li>Jobs-Manager: Handles tasks efficiently.</li>
<li>Followers-Notifier: Sends timely updates to users.</li>
</ul>
<p>In this setup, gRPC’s Protocol Buffers ensure fast, efficient communication, cutting down on overhead and latency. Each service gets exactly what it needs, there's no risk of overfetching. It’s a perfect match for microservices, where speed and efficiency are key.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="scenario-2-a-movie-streaming-backend">Scenario 2: A movie streaming backend<a href="https://tailcall.run/blog/graphql-vs-grpc/#scenario-2-a-movie-streaming-backend" class="hash-link" aria-label="Direct link to Scenario 2: A movie streaming backend" title="Direct link to Scenario 2: A movie streaming backend">​</a></h3>
<p><img decoding="async" loading="lazy" alt="movie app example" src="https://tailcall.run/assets/images/services2-a55901f5189187f44c2b98357fdf3c12.png" width="1317" height="592" class="img_ev3q"></p>
<p>Imagine the backend of a movie-streaming app, where Content-Age-Rater, Relations-Builder, Subtitles-Generator, and Subtitles-Translator each have their own star roles. They rate movies, connect related content, create subtitles, and translate them with precision. With gRPC, these services chat efficiently, making sure data zips around quickly and smoothly. No extra baggage—just a slick, high-performance team working seamlessly together. It’s like having a top-notch crew behind the scenes, making sure everything runs smooth! 🎬🍿</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="scenarios-for-using-graphql">Scenarios for Using GraphQL<a href="https://tailcall.run/blog/graphql-vs-grpc/#scenarios-for-using-graphql" class="hash-link" aria-label="Direct link to Scenarios for Using GraphQL" title="Direct link to Scenarios for Using GraphQL">​</a></h2>
<p>GraphQL shines when you need to tailor data fetching to match your frontend's needs precisely. It allows for fetching exactly the data you need, nothing more, nothing less, which can be a game-changer for optimizing performance and reducing over-fetching. This flexibility can really streamline interactions between the frontend and backend, especially in complex applications, as we discuss below:</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="scenario-1-fetching-multiple-items">Scenario 1: Fetching Multiple Items<a href="https://tailcall.run/blog/graphql-vs-grpc/#scenario-1-fetching-multiple-items" class="hash-link" aria-label="Direct link to Scenario 1: Fetching Multiple Items" title="Direct link to Scenario 1: Fetching Multiple Items">​</a></h3>
<p>GitHub uses GraphQL to make fetching PR details a breeze. With gRPC, you'd have to set up different RPC methods for each data type—comments, commits, changed files—potentially resulting in several requests. Often, you just need the first and last comments right off the bat. GraphQL swoops in, pulling exactly those details with one neat query, cutting down on network strain and speeding things up.</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property-query">repository</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">owner</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"username"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"repository-name"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property-query">pullRequest</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">number</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">123</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">title</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">createdAt</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">updatedAt</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token object">author</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token property" style="color:#C586C0">login</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token property" style="color:#C586C0">avatarUrl</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property-query">comments</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">first</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">2</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token attr-name" style="color:#8DFFF8">orderBy</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token attr-name" style="color:#8DFFF8">field</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token constant" style="color:#C586C0">CREATED_AT</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token attr-name" style="color:#8DFFF8">direction</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token constant" style="color:#C586C0">ASC</span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token object">nodes</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token object">author</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token property" style="color:#C586C0">login</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token property" style="color:#C586C0">body</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token property" style="color:#C586C0">createdAt</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Instagram uses a smart approach to fetch just a handful of comments on a reel—those that show up right under the title without diving into the full comments section. It’d be a hassle to pull 10 or 20 comments when only 5 are needed. This is where GraphQL shines, perfectly tuned for getting just the right data without any extra fluff.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="scenario-2-ecommerce-app">Scenario 2: Ecommerce App<a href="https://tailcall.run/blog/graphql-vs-grpc/#scenario-2-ecommerce-app" class="hash-link" aria-label="Direct link to Scenario 2: Ecommerce App" title="Direct link to Scenario 2: Ecommerce App">​</a></h3>
<p><img decoding="async" loading="lazy" alt="graphql fetch" src="https://tailcall.run/assets/images/fetch-graphql-7654cf09b4e791d41abd96c3c505161d.png" width="631" height="498" class="img_ev3q"></p>
<p>Think about an ecommerce app with loads of products. On the explore page, users just want a quick snapshot—picture, name, and a brief description. But when they dive into a product page, they’re looking for more details like weight and extra images. With gRPC, you’d need separate calls for each view, which can be a bit clunky and might pull in extra data. GraphQL, on the other hand, lets you customize your queries to get just what you need for each page, cutting down on excess data and making everything run smoother:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token object">products</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">id</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">shortDescription</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">imageUrl</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>For the product details page:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property-query">product</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"product-id"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">id</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">description</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">weight</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token object">images</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">url</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This approach makes data retrieval a breeze and keeps performance top-notch, highlighting why GraphQL shines in dynamic content and ecommerce apps over gRPC. It’s all about getting exactly what you need, when you need it, and keeping things running smoothly!</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="integrating-grpc-and-graphql">Integrating gRPC and GraphQL<a href="https://tailcall.run/blog/graphql-vs-grpc/#integrating-grpc-and-graphql" class="hash-link" aria-label="Direct link to Integrating gRPC and GraphQL" title="Direct link to Integrating gRPC and GraphQL">​</a></h2>
<p><img decoding="async" loading="lazy" alt="integrating both" src="https://tailcall.run/assets/images/integration-c4e7414eb97c3a5cbe3932002583d021.png" width="1639" height="883" class="img_ev3q"></p>
<p>Picture a social media app where the backend whips up user feeds based on activity. The frontend needs different data for various screens—blogs or videos—so grabbing everything at once would be overkill. GraphQL steps in to save the day by letting the frontend fetch just what it needs, keeping things snappy and efficient.</p>
<p>Meanwhile, backend services like feed-generator and logs-handler are busy creating and analyzing feeds. They require steady input and don’t need much tweaking once live. For this, gRPC is perfect with its lightning-fast performance and low latency.</p>
<p>By mixing GraphQL on the frontend with gRPC on the backend, you get a dynamic, high-performance setup. GraphQL fine-tunes data requests while gRPC keeps backend communication smooth.</p>
<p>Read this guide explaining the challenges and details associated with integrating gRPC and graphQL: <a href="https://tailcall.run/docs/graphql-grpc-tailcall/">Building GraphQL over gRPC</a> .</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion">Conclusion<a href="https://tailcall.run/blog/graphql-vs-grpc/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>In summary, both gRPC and graphQL have numerous advantages over each other, where gRPC has:</p>
<ul>
<li>more boosted performance</li>
<li>Low payload sizes</li>
<li>Simple and intuitive API design</li>
</ul>
<p>On the other hand GraphQL takes the lead in:</p>
<ul>
<li>API flexibility</li>
<li>Friendly nature for web and mobile apps</li>
<li>Easier debugging</li>
</ul>
<p>It doesn’t matter which one is better, what truly matters is how good it is implemented, and how well it suits the use case. Remember - as Doug LInder likes to say -</p>
<p><strong><em>“A good programmer is someone who always looks both ways before crossing a one-way street”</em></strong></p>
<p>this simple concept can elevate you to the top tier of programmers.</p>]]></content:encoded>
            <category>GraphQL</category>
            <category>gRPC</category>
            <category>backend</category>
            <category>microservices</category>
        </item>
        <item>
            <title><![CDATA[Exploring GraphiQL: The In-Browser IDE for GraphQL]]></title>
            <link>https://tailcall.run/blog/exploring-graphiql/</link>
            <guid>https://tailcall.run/blog/exploring-graphiql/</guid>
            <pubDate>Wed, 24 Jul 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>Meet GraphiQL, a true life-saver for testing, debugging and having fun with your graphQL server.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="introduction">Introduction<a href="https://tailcall.run/blog/exploring-graphiql/#introduction" class="hash-link" aria-label="Direct link to Introduction" title="Direct link to Introduction">​</a></h2>
<p>Imagine you’re diving into GraphQL development and find yourself bogged down with setting up an entire environment just to see if an endpoint is functioning. It’s like preparing a full feast just to taste a single dish—server configurations, route setups, test queries, and more before you even get to interact with your data. Sounds overwhelming, right?</p>
<p>Enter <strong>GraphiQL</strong>, your development superhero. It swoops in to simplify the mess, turning that complicated setup into a breeze. Instead of juggling all those configurations, GraphiQL lets you quickly test and explore your endpoints with ease. It’s like having a magic wand that instantly brings your GraphQL queries to life, making development smoother and way more fun!</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="why-use-graphiql">Why Use GraphiQL?<a href="https://tailcall.run/blog/exploring-graphiql/#why-use-graphiql" class="hash-link" aria-label="Direct link to Why Use GraphiQL?" title="Direct link to Why Use GraphiQL?">​</a></h2>
<p>If you are here, you either know GraphQL too well and are looking for solutions to some GraphQL idiosyncrasy, or you have stumbled here while trying to learn more about GraphQL. If you are new to the GraphQL world, here’s some resources to help you get started with GraphQL:</p>
<ul>
<li>
<p><a href="https://www.tailcall.run/graphql/" target="_blank" rel="noopener noreferrer">Guide To GraphQL</a></p>
</li>
<li>
<p><a href="https://www.tailcall.run/blog/graphql-schema/" target="_blank" rel="noopener noreferrer">Designing GraphQL Schemas</a></p>
</li>
<li>
<p><a href="https://www.tailcall.run/blog/graphql-introspection-security/" target="_blank" rel="noopener noreferrer">Securing GraphQL Apis</a></p>
</li>
</ul>
<p>GraphiQL lets you test out server endpoints without setting up a whole environment. It shines on documentation websites, saving you from writing a playground from scratch, which can be a real time-saver.</p>
<p><img decoding="async" loading="lazy" alt="A gif showing color-coding and auto-suggest/complete" src="https://tailcall.run/assets/images/qry-ab63ce46df21a2fde56da1e741c68dc3.png" width="485" height="354" class="img_ev3q"></p>
<ul>
<li><strong>Interactive Interface</strong>: Provides a user-friendly interface to interact with your server. Features like auto-complete and syntax-highlighting help you write queries without needing to write the whole thing by hand.</li>
<li><strong>Real-time Feedback</strong>: Receive immediate responses and see results on the go, making debugging much faster.</li>
<li><strong>Built-in Documentation Explorer</strong>: No more switching tabs looking for documentation; the built-in explorer lets you see and interact with queries, types, and mutations all in one place.</li>
<li><strong>History Tracking</strong>: Access previous queries and results, making it easy to repeat, refine, and learn from past requests.</li>
<li><strong>Customizable</strong>: Tailor the GraphiQL setup to match your style. Adjust colors and options to blend with your website. For more information, see <a href="https://graphiql-test.netlify.app/typedoc/modules/graphiql.html#customize" target="_blank" rel="noopener noreferrer">Customization</a>.</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="accessing-graphiql">Accessing GraphiQL<a href="https://tailcall.run/blog/exploring-graphiql/#accessing-graphiql" class="hash-link" aria-label="Direct link to Accessing GraphiQL" title="Direct link to Accessing GraphiQL">​</a></h2>
<p>You can access GraphiQL using either of these methods:</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="directly-through-tailcall-playground">Directly through Tailcall Playground<a href="https://tailcall.run/blog/exploring-graphiql/#directly-through-tailcall-playground" class="hash-link" aria-label="Direct link to Directly through Tailcall Playground" title="Direct link to Directly through Tailcall Playground">​</a></h3>
<p>If you have a running GraphQL server and want to interact with it graphically, use <a href="https://tailcall.run/playground/" target="_blank" rel="noopener noreferrer">Tailcall Playground</a>. Open the playground and enter the root endpoint of your server:</p>
<p><img decoding="async" loading="lazy" alt="screenshot showing docs loading and endpoint entered" src="https://tailcall.run/assets/images/docs-0e82e45a5d672972c0872ec7a533d22b.png" width="396" height="511" class="img_ev3q"></p>
<p><strong>Note:</strong> Ensure your server's CORS policy allows requests from the Tailcall domain.</p>
<p>Once you enter the endpoint, the schema is automatically loaded, and you are good to go.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="by-starting-the-graphql-server-with-tailcall">By Starting the GraphQL Server with Tailcall<a href="https://tailcall.run/blog/exploring-graphiql/#by-starting-the-graphql-server-with-tailcall" class="hash-link" aria-label="Direct link to By Starting the GraphQL Server with Tailcall" title="Direct link to By Starting the GraphQL Server with Tailcall">​</a></h3>
<p>Or, if you use Tailcall for your GraphQL server, the playground URL is provided once you <a href="https://tailcall.run/docs/#starting-the-graphql-server" target="_blank" rel="noopener noreferrer">start the server</a>:</p>
<p><img decoding="async" loading="lazy" alt="screenshot showing the output in console" src="https://tailcall.run/assets/images/logoutput-c2bf8b173a6c2bc1059a4536ebb05b66.png" width="784" height="58" class="img_ev3q"></p>
<p>Simply click on the link, and it will open the Tailcall Playground with the endpoint already set up.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="exploring-the-graphiql-interface">Exploring the GraphiQL Interface<a href="https://tailcall.run/blog/exploring-graphiql/#exploring-the-graphiql-interface" class="hash-link" aria-label="Direct link to Exploring the GraphiQL Interface" title="Direct link to Exploring the GraphiQL Interface">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="query-editor">Query Editor<a href="https://tailcall.run/blog/exploring-graphiql/#query-editor" class="hash-link" aria-label="Direct link to Query Editor" title="Direct link to Query Editor">​</a></h3>
<p>Packed with handy features like autocomplete, syntax highlighting, error detection, and code folding, this editor keeps your code neat and saves you tons of time.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="variables-editor">Variables Editor<a href="https://tailcall.run/blog/exploring-graphiql/#variables-editor" class="hash-link" aria-label="Direct link to Variables Editor" title="Direct link to Variables Editor">​</a></h3>
<p>Easily edit variables with autocomplete based on the ones declared in your query—no more tedious copy-pasting of long variable names in complex queries.</p>
<p><img decoding="async" loading="lazy" alt="vars screenshot" src="https://tailcall.run/assets/images/vars-3cd1fd55119c93ecd79a86e65791384a.png" width="475" height="191" class="img_ev3q"></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="response-pane">Response Pane<a href="https://tailcall.run/blog/exploring-graphiql/#response-pane" class="hash-link" aria-label="Direct link to Response Pane" title="Direct link to Response Pane">​</a></h3>
<p>Check out the server's response here. It's super useful for handling lots of nested data, with built-in folding to keep things tidy and avoid getting lost in a sea of JSON.</p>
<p><img decoding="async" loading="lazy" alt="response pane" src="https://tailcall.run/assets/images/response-54405067183065357dfe0f38fa66d4a5.png" width="496" height="530" class="img_ev3q"></p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="setting-headers">Setting Headers<a href="https://tailcall.run/blog/exploring-graphiql/#setting-headers" class="hash-link" aria-label="Direct link to Setting Headers" title="Direct link to Setting Headers">​</a></h2>
<ol>
<li>Access the Headers Panel right beside the variables panel at the bottom</li>
</ol>
<p><img decoding="async" loading="lazy" alt="headers screenshot" src="https://tailcall.run/assets/images/header-90a3161e206d372e6b2c3017d966c448.png" width="482" height="202" class="img_ev3q"></p>
<ol start="2">
<li>Add Custom Headers</li>
</ol>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property" style="color:#C586C0">"Authorization"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"token myghtoken"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<ol start="3">
<li>Run Your Query!</li>
</ol>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="alternatives">Alternatives<a href="https://tailcall.run/blog/exploring-graphiql/#alternatives" class="hash-link" aria-label="Direct link to Alternatives" title="Direct link to Alternatives">​</a></h2>
<p>In case GraphiQL doesn’t quite work out for you and you want to try another IDE, here are some options:</p>
<p>Introspection with Postman
<img decoding="async" loading="lazy" alt="introspection with postman" src="https://tailcall.run/assets/images/postman2-d9c1f5ffddd789dc39ec9f85a66ec75b.png" width="1243" height="323" class="img_ev3q"></p>
<p>Querying with Postman</p>
<p><img decoding="async" loading="lazy" alt="querying with postman" src="https://tailcall.run/assets/images/postman1-8e64d3aef781fbebb5af0a2485839e4a.png" width="1232" height="485" class="img_ev3q"></p>
<ul>
<li><strong><a href="https://learning.postman.com/docs/sending-requests/graphql/graphql-overview/" target="_blank" rel="noopener noreferrer">Postman</a></strong></li>
<li><strong><a href="https://docs.insomnia.rest/insomnia/graphql-queries" target="_blank" rel="noopener noreferrer">Insomnia</a></strong></li>
<li><strong><a href="https://altairgraphql.dev/" target="_blank" rel="noopener noreferrer">Altair Client</a></strong></li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion">Conclusion<a href="https://tailcall.run/blog/exploring-graphiql/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>Wrapping up, we discussed how GraphiQL is an absolute life-saver, especially when you have a server with hundreds of queries returning hundreds of fields of response data. It also makes it super easy to set up a GraphQL playground, like the Tailcall Playground.
It’s relieving and exciting to see new open-source projects being launched that make our lives as programmers much easier:</p>
<ul>
<li>Tailcall absolutely boosts server speed and performance</li>
<li>GraphiQL is a total blessing for testing servers in the development stage</li>
<li>Voyager is the ultimate tool to graphically view and edit your complex schemas.</li>
</ul>
<p>Happy coding, and may your queries always be clean and your responses always be quick, see you in the next one! 🚀</p>]]></content:encoded>
            <category>GraphQL</category>
            <category>GraphiQL</category>
            <category>IDE</category>
            <category>debugging</category>
        </item>
        <item>
            <title><![CDATA[Design a GraphQL Schema So Good, It'll Make REST APIs Cry - Part 4]]></title>
            <link>https://tailcall.run/blog/graphql-schema-part-2-3/</link>
            <guid>https://tailcall.run/blog/graphql-schema-part-2-3/</guid>
            <pubDate>Tue, 23 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn how to remove schema elements without causing disruptions. Strategies to handle breaking changes and maintain backward compatibility.]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="what-do-you-already-know-">What Do You Already Know? 🧠💫<a href="https://tailcall.run/blog/graphql-schema-part-2-3/#what-do-you-already-know-" class="hash-link" aria-label="Direct link to What Do You Already Know? 🧠💫" title="Direct link to What Do You Already Know? 🧠💫">​</a></h2>
<div class="max-w-2xl mx-auto p-6 bg-gradient-to-r from-purple-100 to-blue-100 shadow-lg rounded-xl"><h2 class="text-3xl font-bold mb-6 text-center text-gray-800">GraphQL Schema Change<!-- --> Quiz!</h2><div><p class="mb-4 text-lg font-semibold text-gray-600">Question <!-- -->1<!-- -->/<!-- -->6</p><p class="text-xl font-bold mb-6 text-gray-800">What is a critical consideration before removing a field from a GraphQL schema?</p><div class="space-y-3"><button class="w-full text-left p-4 rounded-lg transition-all duration-300 bg-white hover:bg-gray-100 shadow-md"><span class="text-lg font-medium">Ensuring the field is no longer in use by any clients</span></button><button class="w-full text-left p-4 rounded-lg transition-all duration-300 bg-white hover:bg-gray-100 shadow-md"><span class="text-lg font-medium">Providing a detailed explanation in the schema documentation</span></button><button class="w-full text-left p-4 rounded-lg transition-all duration-300 bg-white hover:bg-gray-100 shadow-md"><span class="text-lg font-medium">Immediately notifying all clients via email</span></button><button class="w-full text-left p-4 rounded-lg transition-all duration-300 bg-white hover:bg-gray-100 shadow-md"><span class="text-lg font-medium">Replacing the field with a temporary placeholder</span></button></div></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="removing-without-breaking-the-subtraction-subterfuge">Removing Without Breaking: The Subtraction Subterfuge<a href="https://tailcall.run/blog/graphql-schema-part-2-3/#removing-without-breaking-the-subtraction-subterfuge" class="hash-link" aria-label="Direct link to Removing Without Breaking: The Subtraction Subterfuge" title="Direct link to Removing Without Breaking: The Subtraction Subterfuge">​</a></h2>
<p>In our <a href="https://tailcall.run/blog/graphql-schema-part-2-2/">previous post</a>, we explored how to modify existing schema elements without causing disruptions. Now, we'll tackle the most challenging part: removing schema elements and handling breaking changes.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="recap-of-additive-changes-and-modifications">Recap of Additive Changes and Modifications<a href="https://tailcall.run/blog/graphql-schema-part-2-3/#recap-of-additive-changes-and-modifications" class="hash-link" aria-label="Direct link to Recap of Additive Changes and Modifications" title="Direct link to Recap of Additive Changes and Modifications">​</a></h2>
<p>In <a href="https://tailcall.run/blog/graphql-schema-part-2-1/">Part 2</a>, we focused on additive changes, emphasizing the importance of expanding your schema's capabilities without disrupting existing clients. By adding new fields, types, and arguments, you can enhance your API while maintaining backward compatibility.</p>
<p>In <a href="https://tailcall.run/blog/graphql-schema-part-2-2/">Part 3</a>, we delved into modifying existing schema elements, discussing how to handle changes such as updating default values, transforming non-null fields to nullable, and changing field types. We highlighted the need for clear communication, providing transition paths, and leveraging schema design tools to minimize client disruptions.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="safe-dangerous-and-breaking-changes">Safe, Dangerous, and Breaking Changes<a href="https://tailcall.run/blog/graphql-schema-part-2-3/#safe-dangerous-and-breaking-changes" class="hash-link" aria-label="Direct link to Safe, Dangerous, and Breaking Changes" title="Direct link to Safe, Dangerous, and Breaking Changes">​</a></h3>
<ol>
<li><strong>Safe Changes:</strong> Additive changes such as adding new fields or types that do not affect existing queries or functionality.</li>
<li><strong>Dangerous Changes:</strong> Modifications that might not break the schema immediately but can cause subtle issues, such as changing default values or making non-nullable fields nullable.</li>
<li><strong>Breaking Changes:</strong> Changes that will definitely break existing queries and require clients to update their code, such as removing fields or changing field types.</li>
</ol>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-subtraction-subterfuge">The Subtraction Subterfuge<a href="https://tailcall.run/blog/graphql-schema-part-2-3/#the-subtraction-subterfuge" class="hash-link" aria-label="Direct link to The Subtraction Subterfuge" title="Direct link to The Subtraction Subterfuge">​</a></h2>
<p>Removing things from your schema is almost always a breaking change. If you remove a field, type, or argument, clients that depend on it will break. You can't just take things away without consequences.</p>
<p>But sometimes, it's necessary. Here's how to do it without causing a riot.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-field-farewell">The Field Farewell<a href="https://tailcall.run/blog/graphql-schema-part-2-3/#the-field-farewell" class="hash-link" aria-label="Direct link to The Field Farewell" title="Direct link to The Field Farewell">​</a></h3>
<p>Let's say we want to remove a field because it's causing performance issues. Here's the smart way to do it:</p>
<ol>
<li>Introduce a replacement</li>
<li>Deprecate the old field</li>
<li>Wait (patiently!)</li>
<li>Remove when usage has died down</li>
</ol>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-diff codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-diff codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">type Query {</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token deleted-sign deleted prefix deleted" style="color:#d73a49">-</span><span class="token deleted-sign deleted line" style="color:#d73a49">  products(first: Int!): [Product!]!</span><br></span><span class="token-line" style="color:#fff"><span class="token deleted-sign deleted line" style="color:#d73a49"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">  products(first: Int!): [Product!]! @deprecated(reason: “products is deprecated and is getting replaced by the field `topProducts`.”)</span><br></span><span class="token-line" style="color:#fff"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">  topProducts(first: Int!): [Product!]!</span><br></span><span class="token-line" style="color:#fff"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>By introducing <code>topProducts</code> and deprecating <code>products</code>, we give our clients time to adapt. And hey, we've even improved our API in the process!</p>
<p>The old field may be removed after a certain period and if the usage for it has gone down. Keep in mind you don’t necessarily have to make the change unless absolutely needed. Additive changes and deprecations are sometimes enough to keep evolving the API.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-argument-abandonment">The Argument Abandonment<a href="https://tailcall.run/blog/graphql-schema-part-2-3/#the-argument-abandonment" class="hash-link" aria-label="Direct link to The Argument Abandonment" title="Direct link to The Argument Abandonment">​</a></h3>
<p>Removing an argument is similar to removing a field. You can deprecate it and</p>
<p>introduce a new field with the desired behavior. Clients will have time to migrate to the new field before the old one is removed.</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-diff codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-diff codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">type Query {</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token deleted-sign deleted prefix deleted" style="color:#d73a49">-</span><span class="token deleted-sign deleted line" style="color:#d73a49">  products(first: Int!, featured: Boolean): String!</span><br></span><span class="token-line" style="color:#fff"><span class="token deleted-sign deleted line" style="color:#d73a49"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">  products(first: Int!, featured: Boolean): String! @deprecated(reason: “products is deprecated, use `allProducts` for products and `featuredProducts` to get products that are featured”)</span><br></span><span class="token-line" style="color:#fff"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">  allProducts(first: Int!): String!</span><br></span><span class="token-line" style="color:#fff"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">  featuredProducts(first: Int!): String!</span><br></span><span class="token-line" style="color:#fff"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>If you need to make a change to an existing field, because arguments can’t be deprecated just yet, you should indicate that the argument is deprecated through its description.</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-diff codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-diff codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">type Query {</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token deleted-sign deleted prefix deleted" style="color:#d73a49">-</span><span class="token deleted-sign deleted line" style="color:#d73a49"> products(first: Int!, featured: Boolean): String!</span><br></span><span class="token-line" style="color:#fff"><span class="token deleted-sign deleted line" style="color:#d73a49"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">  products(first: Int!,</span><br></span><span class="token-line" style="color:#fff"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">  # DEPRECATED: This argument will be removed. Use query `featuredProducts`.</span><br></span><span class="token-line" style="color:#fff"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">  featured: Boolean</span><br></span><span class="token-line" style="color:#fff"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">   ): String!</span><br></span><span class="token-line" style="color:#fff"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-type-deletion-dilemma">The Type Deletion Dilemma<a href="https://tailcall.run/blog/graphql-schema-part-2-3/#the-type-deletion-dilemma" class="hash-link" aria-label="Direct link to The Type Deletion Dilemma" title="Direct link to The Type Deletion Dilemma">​</a></h3>
<p>Sometimes, you need to remove an entire type from your schema. This is a major operation and requires careful planning.</p>
<ol>
<li>First, deprecate all fields that return this type:</li>
</ol>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">oldUser</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">OldUser</span><span class="token plain"> </span><span class="token directive function" style="color:#FDEA2F">@deprecated</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">reason</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"Use `user` query with new User type instead"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">user</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<ol start="2">
<li>If the type is part of a union or implements an interface, you'll need to be extra cautious. These can't be easily deprecated, so clear communication is key.</li>
<li>Finally, after a long deprecation period and when usage has dropped to zero, you can remove the type entirely.</li>
</ol>
<p>Note that you might want to deprecate using that type within your codebase to avoid developers to use that User type for new fields. Removing a type is even trickier when it’s part of union types or implements interfaces. Once again, union members and interface implementations cannot be marked as deprecated. This means that fields like node may stop working correctly if the type you’re removing was reachable through that field.</p>
<p>Your best bet in these cases are to either keep this type as part of unions and through interfaces or to communicate that change very carefully through descriptions and out of band communication like documentation and emails.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion">Conclusion<a href="https://tailcall.run/blog/graphql-schema-part-2-3/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>Removing schema elements is a delicate process that requires strategic planning and clear communication to avoid breaking changes. By following the principles and strategies outlined in this article, you can confidently remove fields, arguments, and types while minimizing disruption to your clients.</p>
<p>Remember these key takeaways:</p>
<ol>
<li><strong>Deprecate Cautiously</strong>: Use deprecation notices, schema descriptions, and out-of-band communication to keep your clients informed about upcoming changes.</li>
<li><strong>Provide Transition Paths</strong>: When breaking changes are necessary, offer clear migration paths. This might involve introducing new fields alongside deprecated ones or providing new query structures that achieve the same results.</li>
<li><strong>Monitor Usage</strong>: Keep an eye on usage metrics to determine when it's safe to remove deprecated elements. Don't rush the process – give your clients time to adapt.<!-- -->
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_BuS1"><p>Tailcall supports a variety of integrations with monitoring tools to help you track usage metrics and make informed decisions about schema changes. you can check out our <a href="https://tailcall.run/docs/graphql-data-dog-telemetry-tailcall/">documentation</a> for more information.</p></div></div>
</li>
</ol>
<p>By treating your GraphQL schema as a product with its own lifecycle and evolution strategy, you can build APIs that are both powerful and adaptable. This approach allows you to innovate rapidly while providing a stable and reliable service to your clients.</p>
<p>Remember, a great GraphQL schema is never truly finished – it's a living, breathing entity that grows and evolves with your application's needs. Embrace this continuous evolution, and you'll create APIs that stand the test of time.</p>]]></content:encoded>
            <category>GraphQL</category>
            <category>API</category>
            <category>Schema</category>
            <category>Design</category>
            <category>Best Practices</category>
        </item>
        <item>
            <title><![CDATA[Design a GraphQL Schema So Good, It'll Make REST APIs Cry - Part 3]]></title>
            <link>https://tailcall.run/blog/graphql-schema-part-2-2/</link>
            <guid>https://tailcall.run/blog/graphql-schema-part-2-2/</guid>
            <pubDate>Mon, 22 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn how to modify existing schema elements in GraphQL without causing disruptions.]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="what-do-you-already-know-">What Do You Already Know? 🧠💫<a href="https://tailcall.run/blog/graphql-schema-part-2-2/#what-do-you-already-know-" class="hash-link" aria-label="Direct link to What Do You Already Know? 🧠💫" title="Direct link to What Do You Already Know? 🧠💫">​</a></h2>
<div class="max-w-2xl mx-auto p-6 bg-gradient-to-r from-purple-100 to-blue-100 shadow-lg rounded-xl"><h2 class="text-3xl font-bold mb-6 text-center text-gray-800">GraphQL Schema Change<!-- --> Quiz!</h2><div><p class="mb-4 text-lg font-semibold text-gray-600">Question <!-- -->1<!-- -->/<!-- -->5</p><p class="text-xl font-bold mb-6 text-gray-800">Changing the default value of an argument is considered a:</p><div class="space-y-3"><button class="w-full text-left p-4 rounded-lg transition-all duration-300 bg-white hover:bg-gray-100 shadow-md"><span class="text-lg font-medium">Safe change</span></button><button class="w-full text-left p-4 rounded-lg transition-all duration-300 bg-white hover:bg-gray-100 shadow-md"><span class="text-lg font-medium">Dangerous change</span></button><button class="w-full text-left p-4 rounded-lg transition-all duration-300 bg-white hover:bg-gray-100 shadow-md"><span class="text-lg font-medium">Breaking change</span></button><button class="w-full text-left p-4 rounded-lg transition-all duration-300 bg-white hover:bg-gray-100 shadow-md"><span class="text-lg font-medium">Non-issue</span></button></div></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="modifying-without-breaking-navigating-the-modification-minefield">Modifying Without Breaking: Navigating the Modification Minefield<a href="https://tailcall.run/blog/graphql-schema-part-2-2/#modifying-without-breaking-navigating-the-modification-minefield" class="hash-link" aria-label="Direct link to Modifying Without Breaking: Navigating the Modification Minefield" title="Direct link to Modifying Without Breaking: Navigating the Modification Minefield">​</a></h2>
<p>In our <a href="https://tailcall.run/blog/graphql-schema-part-2-1/">previous post</a>, we explored how to make additive changes to your GraphQL schema without causing disruptions. Now, we'll dive into the tricky territory of modifying existing schema elements.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="recap-of-additive-changes">Recap of Additive Changes<a href="https://tailcall.run/blog/graphql-schema-part-2-2/#recap-of-additive-changes" class="hash-link" aria-label="Direct link to Recap of Additive Changes" title="Direct link to Recap of Additive Changes">​</a></h2>
<p>In <a href="https://tailcall.run/blog/graphql-schema-part-2-1/">Part 2</a>, we discussed the importance of making additive changes to your GraphQL schema to expand its capabilities while maintaining backward compatibility. By adding new fields, types, and arguments, you can enhance your API without causing disruptions to existing clients. We also emphasized the importance of providing transition paths to ensure a smooth adoption process.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="safe-dangerous-and-breaking-changes">Safe, Dangerous, and Breaking Changes<a href="https://tailcall.run/blog/graphql-schema-part-2-2/#safe-dangerous-and-breaking-changes" class="hash-link" aria-label="Direct link to Safe, Dangerous, and Breaking Changes" title="Direct link to Safe, Dangerous, and Breaking Changes">​</a></h3>
<ol>
<li><strong>Safe Changes:</strong> Additive changes such as adding new fields or types that do not affect existing queries or functionality.</li>
<li><strong>Dangerous Changes:</strong> Modifications that might not break the schema immediately but can cause subtle issues, such as changing default values or making non-nullable fields nullable.</li>
<li><strong>Breaking Changes:</strong> Changes that will definitely break existing queries and require clients to update their code, such as removing fields or changing field types.</li>
</ol>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-modification-minefield">The Modification Minefield<a href="https://tailcall.run/blog/graphql-schema-part-2-2/#the-modification-minefield" class="hash-link" aria-label="Direct link to The Modification Minefield" title="Direct link to The Modification Minefield">​</a></h2>
<p>Now, let's talk about modifying existing parts of your schema. This is where things can get really hairy. For example, changing a field’s type or changing the name of a type is a big-breaking change.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-default-value-dilemma">The Default Value Dilemma<a href="https://tailcall.run/blog/graphql-schema-part-2-2/#the-default-value-dilemma" class="hash-link" aria-label="Direct link to The Default Value Dilemma" title="Direct link to The Default Value Dilemma">​</a></h3>
<p>Changing default values might seem innocent, but it can cause some serious headaches. Consider this:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-diff codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-diff codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">type Query {</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token deleted-sign deleted prefix deleted" style="color:#d73a49">-</span><span class="token deleted-sign deleted line" style="color:#d73a49">  products(category: String, showOutOfStock: Boolean = False): [Product!]!</span><br></span><span class="token-line" style="color:#fff"><span class="token deleted-sign deleted line" style="color:#d73a49"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">  products(category: String, showOutOfStock: Boolean = True): [Product!]!</span><br></span><span class="token-line" style="color:#fff"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Changing the default value of an argument or input field is unlikely to be a breaking change in terms of the schema itself, but is very likely to cause issues at runtime if the default value affects the runtime behavior of the field.</p>
<p>Avoid this change in general, but it may be possible to achieve if the behavior of the field does not change.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-non-null-to-null-transformation">The Non-Null to Null Transformation<a href="https://tailcall.run/blog/graphql-schema-part-2-2/#the-non-null-to-null-transformation" class="hash-link" aria-label="Direct link to The Non-Null to Null Transformation" title="Direct link to The Non-Null to Null Transformation">​</a></h3>
<p>This is one of the trickiest changes to make. You thought making a field non-null was a good idea, but now you need to change it back. Here's how to handle it:</p>
<p>For scalar fields, you might be able to save your users from errors by returning the <code>default value</code> instead of null.</p>
<p>For object types, sometimes it’s possible to use a <code>Default Object</code> when the result is null.</p>
<p>This approach can help prevent null pointer exceptions on the client side.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="changing-a-field-type">Changing a Field Type<a href="https://tailcall.run/blog/graphql-schema-part-2-2/#changing-a-field-type" class="hash-link" aria-label="Direct link to Changing a Field Type" title="Direct link to Changing a Field Type">​</a></h3>
<p>Changing a field’s type is not a change we can make easily. Once again, approaching the change in an additive is often your best bet.</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-diff codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-diff codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">type User {</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token unchanged prefix unchanged"> </span><span class="token unchanged line"> bestFriend: String! @deprecated(reason: “Use `bestFriendObject` instead.”)</span><br></span><span class="token-line" style="color:#fff"><span class="token unchanged line"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa"> bestFriendObject: User!</span><br></span><span class="token-line" style="color:#fff"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>As you might have noticed, the downside of additive changes is that often the best names are already taken. If wanted, you may remove the original field and reintroduce it under the new object at that point.</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-diff codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-diff codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">type User {</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token deleted-sign deleted prefix deleted" style="color:#d73a49">-</span><span class="token deleted-sign deleted line" style="color:#d73a49"> bestFriend: String! @deprecated(reason: “Use `bestFriendObject` instead.”)</span><br></span><span class="token-line" style="color:#fff"><span class="token deleted-sign deleted line" style="color:#d73a49"></span><span class="token unchanged prefix unchanged"> </span><span class="token unchanged line"> bestFriendObject: User!</span><br></span><span class="token-line" style="color:#fff"><span class="token unchanged line"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa"> bestFriend: User!</span><br></span><span class="token-line" style="color:#fff"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="changing-description-or-deprecation">Changing Description or Deprecation<a href="https://tailcall.run/blog/graphql-schema-part-2-2/#changing-description-or-deprecation" class="hash-link" aria-label="Direct link to Changing Description or Deprecation" title="Direct link to Changing Description or Deprecation">​</a></h3>
<p>Changing the description of fields, types and any member is unlikely to cause any harm to clients. Clients should not depend on schema descriptions for runtime logic!</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion">Conclusion<a href="https://tailcall.run/blog/graphql-schema-part-2-2/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>Modifying existing schema elements requires careful planning and execution to avoid breaking changes. By following the principles and strategies outlined in this article, you can confidently make necessary modifications while minimizing disruption to your clients.</p>
<p>Remember these key takeaways:</p>
<ol>
<li><strong>Deprecate Cautiously</strong>: Use deprecation notices, schema descriptions, and out-of-band communication to keep your clients informed about upcoming changes.</li>
<li><strong>Provide Transition Paths</strong>: When breaking changes are necessary, offer clear migration paths. This might involve introducing new fields alongside deprecated ones or providing new query structures that achieve the same results.</li>
<li><strong>Leverage Schema Design Tools</strong>: Use schema comparison tools like <a href="https://github.com/graphql-editor/graphql-editor" target="_blank" rel="noopener noreferrer">GraphQL Editor</a>.</li>
</ol>
<p>By treating your GraphQL schema as a product with its own lifecycle and evolution strategy, you can build APIs that are both powerful and adaptable. This approach allows you to innovate rapidly while providing a stable and reliable service to your clients.</p>
<p>Stay tuned for the <a href="https://tailcall.run/blog/graphql-schema-part-2-3/">next part</a> of this series, where we will dive into removing schema elements and handling breaking changes!</p>]]></content:encoded>
            <category>GraphQL</category>
            <category>API</category>
            <category>Schema</category>
            <category>Design</category>
            <category>Best Practices</category>
        </item>
        <item>
            <title><![CDATA[Design a GraphQL Schema So Good, It'll Make REST APIs Cry - Part 2]]></title>
            <link>https://tailcall.run/blog/graphql-schema-part-2-1/</link>
            <guid>https://tailcall.run/blog/graphql-schema-part-2-1/</guid>
            <pubDate>Sun, 21 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn how to make additive changes to your GraphQL schema without causing disruptions.]]></description>
            <content:encoded><![CDATA[<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="what-do-you-already-know-">What Do You Already Know? 🧠💫<a href="https://tailcall.run/blog/graphql-schema-part-2-1/#what-do-you-already-know-" class="hash-link" aria-label="Direct link to What Do You Already Know? 🧠💫" title="Direct link to What Do You Already Know? 🧠💫">​</a></h2>
<div class="max-w-2xl mx-auto p-6 bg-gradient-to-r from-purple-100 to-blue-100 shadow-lg rounded-xl"><h2 class="text-3xl font-bold mb-6 text-center text-gray-800">GraphQL Schema Change<!-- --> Quiz!</h2><div><p class="mb-4 text-lg font-semibold text-gray-600">Question <!-- -->1<!-- -->/<!-- -->5</p><p class="text-xl font-bold mb-6 text-gray-800">Adding a new field to a GraphQL schema is generally a:</p><div class="space-y-3"><button class="w-full text-left p-4 rounded-lg transition-all duration-300 bg-white hover:bg-gray-100 shadow-md"><span class="text-lg font-medium">Safe change</span></button><button class="w-full text-left p-4 rounded-lg transition-all duration-300 bg-white hover:bg-gray-100 shadow-md"><span class="text-lg font-medium">Dangerous change</span></button><button class="w-full text-left p-4 rounded-lg transition-all duration-300 bg-white hover:bg-gray-100 shadow-md"><span class="text-lg font-medium">Breaking change</span></button><button class="w-full text-left p-4 rounded-lg transition-all duration-300 bg-white hover:bg-gray-100 shadow-md"><span class="text-lg font-medium">Requires deprecation</span></button></div></div></div>
<p>In our <a href="https://tailcall.run/blog/graphql-schema/">previous post</a>, we learned scalable GraphQL schema is critical for building production-ready APIs that can evolve with your application's needs.</p>
<p>In this post, we will dive deeper into how to <strong>continuously</strong> evolve your schema to meet your application's changing requirements without hard-coded versioning.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="adding-without-breaking-the-art-of-additive-changes">Adding Without Breaking: The Art of Additive Changes<a href="https://tailcall.run/blog/graphql-schema-part-2-1/#adding-without-breaking-the-art-of-additive-changes" class="hash-link" aria-label="Direct link to Adding Without Breaking: The Art of Additive Changes" title="Direct link to Adding Without Breaking: The Art of Additive Changes">​</a></h2>
<p>You know that feeling when you're working on a project, and suddenly you realize your schema needs to change? Maybe you need to add a new field, modify an existing one, or even remove something entirely. It's enough to make any developer break out in a cold sweat, right?</p>
<p>But fear not! I'm here to show you <strong>how to evolve your schema like a pro</strong>, keeping your API fresh and exciting without causing your clients to tear their hair out.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-good-the-bad-and-the-ugly-of-schema-changes">The Good, The Bad, and The Ugly of Schema Changes<a href="https://tailcall.run/blog/graphql-schema-part-2-1/#the-good-the-bad-and-the-ugly-of-schema-changes" class="hash-link" aria-label="Direct link to The Good, The Bad, and The Ugly of Schema Changes" title="Direct link to The Good, The Bad, and The Ugly of Schema Changes">​</a></h2>
<p>Not all changes are created equal. In this section, we’ll analyze a few different types of changes and what makes them safe or unsafe.</p>
<p>First things first, let's break down the types of changes we might make to our schema:</p>
<ol>
<li><strong>Safe Changes:</strong> These are the golden children of schema evolution. You can make these changes anytime, and your clients won't even bat an eyelash.</li>
<li><strong>Dangerous Changes:</strong> These are the sneaky ones. They might not break anything outright, but they can cause subtle issues that'll have your clients scratching their heads. We'll need to proceed carefully here.</li>
<li><strong>Breaking Changes:</strong> The name says it all. These changes will send your clients' applications crashing down faster than you can say "<strong>GraphQL</strong>". We want to avoid these like the plague, but sometimes they're necessary. Don't worry, I'll show you how to handle them like a pro.</li>
</ol>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="additive-changes">Additive Changes<a href="https://tailcall.run/blog/graphql-schema-part-2-1/#additive-changes" class="hash-link" aria-label="Direct link to Additive Changes" title="Direct link to Additive Changes">​</a></h2>
<p>Most of the time, these are safe as houses.</p>
<p>For example, adding fields &amp; adding types is unlikely to cause issues for clients. But, there are a few tricky scenarios to watch out for.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-optional-argument-conundrum">The Optional Argument Conundrum<a href="https://tailcall.run/blog/graphql-schema-part-2-1/#the-optional-argument-conundrum" class="hash-link" aria-label="Direct link to The Optional Argument Conundrum" title="Direct link to The Optional Argument Conundrum">​</a></h3>
<p>Adding optional arguments is generally safe - it's like offering your clients a shiny new toy without forcing them to play with it.</p>
<p>However, there's a catch. Check this out:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-diff codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-diff codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token unchanged prefix unchanged"> </span><span class="token unchanged line"> type Query {</span><br></span><span class="token-line" style="color:#fff"><span class="token unchanged line"></span><span class="token deleted-sign deleted prefix deleted" style="color:#d73a49">-</span><span class="token deleted-sign deleted line" style="color:#d73a49">   products(category: String): [Product!]!</span><br></span><span class="token-line" style="color:#fff"><span class="token deleted-sign deleted line" style="color:#d73a49"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">   products(category: String, inStock: Boolean): [Product!]!</span><br></span><span class="token-line" style="color:#fff"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token unchanged prefix unchanged"> </span><span class="token unchanged line"> }</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>See what we did there? We added an optional <code>inStock</code> argument. Seems harmless, right?</p>
<p>Let's dive deeper into why changing the behavior of a resolver when an optional argument isn't provided can be problematic:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">products</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">category</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token attr-name" style="color:#8DFFF8">inStock</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Boolean</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">Product</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">]</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Imagine you have clients that have been using this query:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property-query">products</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">category</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"Electronics"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">price</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>If your resolver suddenly starts filtering out out-of-stock products when <code>inStock</code> isn't provided, these clients will unexpectedly receive fewer results. This could break their UI or data processing logic.</p>
<p>To avoid this issue, you can implement a strategy to handle the absence of the <code>inStock</code> argument gracefully in your resolver, so that the behavior remains consistent for clients.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-required-argument-trap">The Required Argument Trap<a href="https://tailcall.run/blog/graphql-schema-part-2-1/#the-required-argument-trap" class="hash-link" aria-label="Direct link to The Required Argument Trap" title="Direct link to The Required Argument Trap">​</a></h3>
<p>Now, this is where things get spicy 🌶️.</p>
<p>Adding a required argument is almost always a <strong>breaking change</strong>.</p>
<p>But, fear not! There's a way out:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-diff codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-diff codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token unchanged prefix unchanged"> </span><span class="token unchanged line"> type Query {</span><br></span><span class="token-line" style="color:#fff"><span class="token unchanged line"></span><span class="token deleted-sign deleted prefix deleted" style="color:#d73a49">-</span><span class="token deleted-sign deleted line" style="color:#d73a49">   products(category: String): [Product!]!</span><br></span><span class="token-line" style="color:#fff"><span class="token deleted-sign deleted line" style="color:#d73a49"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">   products(category: String, sortBy: SortOption!): [Product!]!</span><br></span><span class="token-line" style="color:#fff"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token unchanged prefix unchanged"> </span><span class="token unchanged line"> }</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This change is <strong>breaking</strong>, but it doesn't have to be.</p>
<p>You can provide a <strong>default value</strong> for the new argument to keep your existing clients happy.</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-diff codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-diff codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">type Query {</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token deleted-sign deleted prefix deleted" style="color:#d73a49">-</span><span class="token deleted-sign deleted line" style="color:#d73a49">    products(category: String): [Product!]!</span><br></span><span class="token-line" style="color:#fff"><span class="token deleted-sign deleted line" style="color:#d73a49"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">    products(category: String, sortBy: SortOption! = POPULARITY): [Product!]!</span><br></span><span class="token-line" style="color:#fff"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>See that <code>= POPULARITY</code>? That's your get-out-of-jail-free card. By providing a default value, you've made this addition safe.</p>
<p>Existing clients will use the default, and new clients can take advantage of the sorting option.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-interface-and-union-twist">The Interface and Union Twist<a href="https://tailcall.run/blog/graphql-schema-part-2-1/#the-interface-and-union-twist" class="hash-link" aria-label="Direct link to The Interface and Union Twist" title="Direct link to The Interface and Union Twist">​</a></h3>
<p>Now, let's talk about some trickier additive changes that can catch you off guard if you're not careful.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="adding-new-interface-implementations">Adding New Interface Implementations<a href="https://tailcall.run/blog/graphql-schema-part-2-1/#adding-new-interface-implementations" class="hash-link" aria-label="Direct link to Adding New Interface Implementations" title="Direct link to Adding New Interface Implementations">​</a></h3>
<p>Adding a new type that implements an existing interface might seem harmless, but it can cause some unexpected behavior. Check this out:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">interface</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Node</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">implements</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Node</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Team</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">implements</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Node</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Organization</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">implements</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Node</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">employees</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">User</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">]</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>By adding the <code>Organization</code> type, we've expanded what could be returned by queries selecting for <code>Node</code>. This could break clients that aren't prepared to handle new types. Always encourage clients to use proper type checking.</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property-query">node</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"1"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token operator" style="color:#8DFFF8">...</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">on</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token operator" style="color:#8DFFF8">...</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">on</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Team</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token operator" style="color:#8DFFF8">...</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">on</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Organization</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token object">employees</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Without proper type checking, clients might encounter these issues:</p>
<ol>
<li><strong>Runtime Errors:</strong> If a client assumes all Node types have only a name field, they might try to access <code>employees</code> on a <code>User</code> or <code>Team</code>, causing errors.</li>
<li><strong>Missing Data:</strong> Clients might not display Organization-specific data if they're not prepared to handle it.</li>
<li><strong>Incorrect Data Processing:</strong> Business logic that assumes only <code>User</code> and <code>Team</code> types exist might produce incorrect results.</li>
</ol>
<p>To mitigate these issues:</p>
<ol>
<li>Use TypeScript or Flow on the client-side to catch type errors at compile-time.</li>
<li>Implement exhaustive type checking in your client code:</li>
</ol>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">function</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">handleNode</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">node</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> Node</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">switch</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">node</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">__typename</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">case</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"User"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">handleUser</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">node</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">case</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"Team"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">handleTeam</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">node</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">case</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"Organization"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">handleOrganization</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">node</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">default</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> _exhaustiveCheck</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">never</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> node</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Error</span><span class="token punctuation" style="color:#fff">(</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869">Unhandled node type: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation punctuation" style="color:#fff">(</span><span class="token template-string interpolation">_exhaustiveCheck </span><span class="token template-string interpolation keyword" style="color:#C586C0">as</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation builtin">any</span><span class="token template-string interpolation punctuation" style="color:#fff">)</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">__typename</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This approach ensures that if a new type is added in the future, TypeScript will raise a compile-time error, prompting developers to update their code.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-union-expansion-conundrum">The Union Expansion Conundrum<a href="https://tailcall.run/blog/graphql-schema-part-2-1/#the-union-expansion-conundrum" class="hash-link" aria-label="Direct link to The Union Expansion Conundrum" title="Direct link to The Union Expansion Conundrum">​</a></h3>
<p>Similar to interfaces, adding new members to a union can cause runtime surprises. Consider this:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-diff codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-diff codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token deleted-sign deleted prefix deleted" style="color:#d73a49">-</span><span class="token deleted-sign deleted line" style="color:#d73a49">  union SearchResult = User | Post</span><br></span><span class="token-line" style="color:#fff"><span class="token deleted-sign deleted line" style="color:#d73a49"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">  union SearchResult = User | Post | Comment</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Surprise! Your clients might suddenly receive a type they weren't expecting. It's like opening a box of chocolates and finding a pickle - not necessarily bad, but definitely unexpected. Make sure to document how clients should handle these surprise types.</p>
<p>Let's delve into why union expansions can be tricky and how to handle them gracefully:</p>
<p>When you add <code>Comment</code> to the <code>SearchResult</code> union, existing clients might break in subtle ways:</p>
<ol>
<li><strong>Incomplete UI:</strong> If the client only has UI components for <code>User</code> and <code>Post</code>, <code>Comment</code> results won't be displayed.</li>
<li><strong>Runtime Errors:</strong> Code that assumes only <code>User</code> and <code>Post</code> types exist might throw errors when encountering a <code>Comment</code>.</li>
</ol>
<p>To handle this gracefully:</p>
<ol>
<li>
<p>Implement a fallback UI component for unknown types:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">function</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">SearchResultItem</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">result</span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">switch</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">result</span><span class="token punctuation" style="color:#fff">.</span><span class="token property-access">__typename</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">case</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"User"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag class-name" style="color:#C586C0">UserResult</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">user</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#fff">=</span><span class="token tag script language-javascript punctuation" style="color:#fff">{</span><span class="token tag script language-javascript" style="color:#fff">result</span><span class="token tag script language-javascript punctuation" style="color:#fff">}</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag punctuation" style="color:#fff">/&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">case</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"Post"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag class-name" style="color:#C586C0">PostResult</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">post</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#fff">=</span><span class="token tag script language-javascript punctuation" style="color:#fff">{</span><span class="token tag script language-javascript" style="color:#fff">result</span><span class="token tag script language-javascript punctuation" style="color:#fff">}</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag punctuation" style="color:#fff">/&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">case</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"Comment"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag class-name" style="color:#C586C0">CommentResult</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">comment</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#fff">=</span><span class="token tag script language-javascript punctuation" style="color:#fff">{</span><span class="token tag script language-javascript" style="color:#fff">result</span><span class="token tag script language-javascript punctuation" style="color:#fff">}</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag punctuation" style="color:#fff">/&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">default</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token tag punctuation" style="color:#fff">&lt;</span><span class="token tag class-name" style="color:#C586C0">UnknownResultType</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag attr-name" style="color:#8DFFF8">type</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#fff">=</span><span class="token tag script language-javascript punctuation" style="color:#fff">{</span><span class="token tag script language-javascript" style="color:#fff">result</span><span class="token tag script language-javascript punctuation" style="color:#fff">.</span><span class="token tag script language-javascript property-access" style="color:#fff">__typename</span><span class="token tag script language-javascript punctuation" style="color:#fff">}</span><span class="token tag" style="color:#b76b01"> </span><span class="token tag punctuation" style="color:#fff">/&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
</li>
<li>
<p>Encourage clients to use introspection queries to stay updated on schema changes:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property-query">__type</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"SearchResult"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">kinds</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token object">possibleTypes</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
</li>
</ol>
<p>By implementing these strategies, clients can gracefully handle new union members without breaking existing functionality.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-enum-evolution">The Enum Evolution<a href="https://tailcall.run/blog/graphql-schema-part-2-1/#the-enum-evolution" class="hash-link" aria-label="Direct link to The Enum Evolution" title="Direct link to The Enum Evolution">​</a></h3>
<p>Adding new enum values seems innocent enough, but it can impact client-side logic. Let's look at an example:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-diff codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-diff codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token unchanged prefix unchanged"> </span><span class="token unchanged line"> enum OrderStatus {</span><br></span><span class="token-line" style="color:#fff"><span class="token unchanged line"></span><span class="token unchanged prefix unchanged"> </span><span class="token unchanged line">  PENDING</span><br></span><span class="token-line" style="color:#fff"><span class="token unchanged line"></span><span class="token unchanged prefix unchanged"> </span><span class="token unchanged line">  COMPLETED</span><br></span><span class="token-line" style="color:#fff"><span class="token unchanged line"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">  CANCELED</span><br></span><span class="token-line" style="color:#fff"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">  REFUNDED</span><br></span><span class="token-line" style="color:#fff"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Clients that were using exhaustive switches might now have incomplete logic. Encourage clients to use default cases to handle new enum values.</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">switch</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">order</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">status</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">case</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"PENDING"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"Order is pending"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">case</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"COMPLETED"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"Order is completed"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">default</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"Order status unknown"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion">Conclusion<a href="https://tailcall.run/blog/graphql-schema-part-2-1/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>Evolving a GraphQL schema through additive changes allows you to expand your API's capabilities while maintaining backward compatibility. By following the principles and strategies outlined in this article, you can confidently add new fields, types, and arguments without causing disruptions to your clients.</p>
<p>Remember these key takeaways:</p>
<ol>
<li>
<p><strong>Favor Additive Changes</strong>: Whenever possible, add new fields, types, or arguments instead of modifying existing ones. This approach maintains backward compatibility while allowing your schema to grow.</p>
</li>
<li>
<p><strong>Provide Transition Paths</strong>: Introduce new features alongside existing ones to allow gradual client adoption.</p>
</li>
</ol>
<p>By treating your GraphQL schema as a product with its own lifecycle and evolution strategy, you can build APIs that are both powerful and adaptable. This approach allows you to innovate rapidly while providing a stable and reliable service to your clients.</p>
<p>Stay tuned for the <a href="https://tailcall.run/blog/graphql-schema-part-2-2/">next part</a> of this series, where we will dive into removing schema elements and handling breaking changes!</p>]]></content:encoded>
            <category>GraphQL</category>
            <category>API</category>
            <category>Schema</category>
            <category>Design</category>
            <category>Best Practices</category>
        </item>
        <item>
            <title><![CDATA[Apollo vs Urql vs Fetch: The Ultimate Showdown]]></title>
            <link>https://tailcall.run/blog/graphql-angular-client/</link>
            <guid>https://tailcall.run/blog/graphql-angular-client/</guid>
            <pubDate>Sat, 20 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[We pushed each method to its limits. Here's what we discovered.]]></description>
            <content:encoded><![CDATA[<p>Angular developers often face the challenge of efficiently fetching and managing data from GraphQL APIs. This comprehensive guide dives into five powerful approaches for integrating GraphQL into your Angular applications. We'll explore everything from full-featured client libraries to lightweight solutions, using a practical example of fetching post data to demonstrate each method's strengths and nuances.</p>
<p>Our journey will take us through Apollo Angular, Urql, GraphQL-Request, Axios, and the native Fetch API, each offering unique advantages for different project needs. Whether you're building a small-scale application or a complex enterprise system, this guide will equip you with the knowledge to choose the best GraphQL integration method for your Angular project.</p>
<p>We'll not only cover the implementation details but also delve into error handling strategies, providing you with robust solutions to gracefully manage various API-related issues. By the end of this guide, you'll have a clear understanding of how to leverage GraphQL in Angular, complete with code snippets, real-world analogies, and a detailed comparison table to aid your decision-making process.</p>
<p>So, buckle up and get ready to supercharge your Angular applications with the power of GraphQL!</p>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_BuS1"><p><em><strong>NB</strong>: We are not using the traditional NgModule-based Angular applications instead we will be using the newer standalone component approach; below is the version of angular cli version used throughout the guide.</em></p></div></div>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">ng version</span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    _                      _                 ____ _     ___</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">   / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"> / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">/_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|</span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">Angular CLI: 18.0.7</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">Node: 20.12.2</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">Package Manager: npm 10.5.0</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">OS: linux x64</span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">Angular: 18.0.6</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">... animations, common, compiler, compiler-cli, core, forms</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">... platform-browser, platform-browser-dynamic, platform-server</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">... router</span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">Package                         Version</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">---------------------------------------------------------</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">@angular-devkit/architect       0.1800.7</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">@angular-devkit/build-angular   18.0.7</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">@angular-devkit/core            18.0.7</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">@angular-devkit/schematics      18.0.7</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">@angular/cli                    18.0.7</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">@angular/ssr                    18.0.7</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">@schematics/angular             18.0.7</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">rxjs                            7.8.1</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">typescript                      5.4.5</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">zone.js                         0.14.7</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>We'll be using a Tailcall backend that wraps the JSONPlaceholder API, providing a GraphQL interface to RESTful data.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="️-project-setup">🛠️ Project Setup<a href="https://tailcall.run/blog/graphql-angular-client/#%EF%B8%8F-project-setup" class="hash-link" aria-label="Direct link to 🛠️ Project Setup" title="Direct link to 🛠️ Project Setup">​</a></h3>
<p>First, let's set up our Angular project:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">ng new angular-graphql-tailcall-showcase</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">cd angular-graphql-tailcall-showcase</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="-tailcall-backend-configuration">🔧 Tailcall Backend Configuration<a href="https://tailcall.run/blog/graphql-angular-client/#-tailcall-backend-configuration" class="hash-link" aria-label="Direct link to 🔧 Tailcall Backend Configuration" title="Direct link to 🔧 Tailcall Backend Configuration">​</a></h3>
<p>Create a <code>tailcall</code> directory in the project root and add a jsonplaceholder.graphql file:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token comment" style="color:#30C26D;font-style:italic"># File: tailcall/jsonplaceholder.graphql</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">schema</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token directive function" style="color:#FDEA2F">@server</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">port</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">8000</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token attr-name" style="color:#8DFFF8">hostname</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"0.0.0.0"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token directive function" style="color:#FDEA2F">@upstream</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">httpCache</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">42</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">query</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Query</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">posts</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">Post</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token directive function" style="color:#FDEA2F">@http</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">url</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"http://jsonplaceholder.typicode.com/posts"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">user</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token directive function" style="color:#FDEA2F">@http</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token attr-name" style="color:#8DFFF8">url</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"http://jsonplaceholder.typicode.com/users/{{.args.id}}"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">username</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">email</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">phone</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">website</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Post</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">userId</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">title</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">body</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">user</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token directive function" style="color:#FDEA2F">@http</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token attr-name" style="color:#8DFFF8">url</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"http://jsonplaceholder.typicode.com/users/{{.value.userId}}"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>To start the Tailcall server, run:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">tailcall start ./tailcall/jsonplaceholder.graphql</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="1-apollo-angular---the-luxury-sports-car-of-graphql-clients">1. Apollo Angular - The Luxury Sports Car of GraphQL Clients<a href="https://tailcall.run/blog/graphql-angular-client/#1-apollo-angular---the-luxury-sports-car-of-graphql-clients" class="hash-link" aria-label="Direct link to 1. Apollo Angular - The Luxury Sports Car of GraphQL Clients" title="Direct link to 1. Apollo Angular - The Luxury Sports Car of GraphQL Clients">​</a></h3>
<p>First up on our list is Apollo Angular. If GraphQL clients were cars, Apollo would be the Tesla of the bunch - sleek, powerful, and packed with features you didn't even know you needed. Let's pop the hood and see what makes this beauty purr!</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="installation-and-integration-steps">Installation and Integration Steps<a href="https://tailcall.run/blog/graphql-angular-client/#installation-and-integration-steps" class="hash-link" aria-label="Direct link to Installation and Integration Steps" title="Direct link to Installation and Integration Steps">​</a></h4>
<p>Before we can take Apollo for a spin, we need to get it set up in our garage (I mean, project). Here's how:</p>
<ol>
<li>
<p><strong>Install the necessary packages:</strong>:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">npm install apollo-angular @apollo/client graphql</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
</li>
<li>
<p><strong>Configure Apollo in your <code>app.config.ts</code></strong>:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-jsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-jsx codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain"> </span><span class="token keyword module" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"> </span><span class="token constant" style="color:#C586C0">APOLLO_OPTIONS</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token maybe-class-name">ApolloModule</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'apollo-angular'</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"> </span><span class="token keyword module" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#fff">{</span><span class="token imports"> </span><span class="token imports maybe-class-name">HttpLink</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'apollo-angular/http'</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"> </span><span class="token keyword module" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#fff">{</span><span class="token imports"> </span><span class="token imports maybe-class-name">InMemoryCache</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'@apollo/client/core'</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"> </span><span class="token comment" style="color:#30C26D;font-style:italic">// In your ApplicationConfig</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"> </span><span class="token literal-property property" style="color:#C586C0">providers</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">     </span><span class="token function" style="color:#FDEA2F">importProvidersFrom</span><span class="token punctuation" style="color:#fff">(</span><span class="token maybe-class-name">ApolloModule</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">     </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">     </span><span class="token literal-property property" style="color:#C586C0">provide</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token constant" style="color:#C586C0">APOLLO_OPTIONS</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">     </span><span class="token function-variable function" style="color:#FDEA2F">useFactory</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token parameter literal-property property" style="color:#C586C0">httpLink</span><span class="token parameter operator" style="color:#8DFFF8">:</span><span class="token parameter" style="color:#953800"> </span><span class="token parameter maybe-class-name" style="color:#953800">HttpLink</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">         </span><span class="token literal-property property" style="color:#C586C0">cache</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">InMemoryCache</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">         </span><span class="token literal-property property" style="color:#C586C0">link</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> httpLink</span><span class="token punctuation" style="color:#fff">.</span><span class="token method function property-access" style="color:#FDEA2F">create</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">         </span><span class="token literal-property property" style="color:#C586C0">uri</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'/graphql'</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">         </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">     </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">     </span><span class="token literal-property property" style="color:#C586C0">deps</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token maybe-class-name">HttpLink</span><span class="token punctuation" style="color:#fff">]</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">     </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"> </span><span class="token punctuation" style="color:#fff">]</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"> </span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
</li>
<li>
<p><strong>Code Snippets</strong>
Now that we've got our Apollo rocket fueled up, let's see it in action! Here's a component that fetches a list of posts using Apollo in <code>src/app/apollo-angular/post-list.component.ts</code>:</p>
</li>
</ol>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">Component</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> OnDestroy</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@angular/core"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">CommonModule</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@angular/common"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">Apollo</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> gql</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"apollo-angular"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">ChangeDetectorRef</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@angular/core"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  catchError</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  takeUntil</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  mergeMap</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"rxjs/operators"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">Subject</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">of</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> throwError</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"rxjs"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token decorator at operator" style="color:#8DFFF8">@</span><span class="token decorator function" style="color:#FDEA2F">Component</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  selector</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"app-apollo-post-list"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  standalone</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">true</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  imports</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token plain">CommonModule</span><span class="token punctuation" style="color:#fff">]</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  template</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;h2&gt;Posts (Apollo Angular)&lt;/h2&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;button (click)="fetchPosts()" [disabled]="loading"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      {{ loading ? "Loading..." : "Load Posts" }}</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/button&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;button (click)="triggerNetworkError()"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      Trigger Network Error</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/button&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;button (click)="triggerGraphQLError()"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      Trigger GraphQL Error</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/button&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;button (click)="triggerUnexpectedError()"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      Trigger Unexpected Error</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/button&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;ul *ngIf="!error"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      &lt;li *ngFor="let post of posts"&gt;{{ post.title }}&lt;/li&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/ul&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;div *ngIf="error" class="error-message"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      {{ error }}</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/div&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">  </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  styles</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      .error-message {</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">        color: red;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">        margin-top: 10px;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      }</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">]</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">export</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">class</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">ApolloPostListComponent</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">implements</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">OnDestroy</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic">// ... (component properties and constructor)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token function" style="color:#FDEA2F">fetchPosts</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">null</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">posts </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">let</span><span class="token plain"> query </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> gql</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">        </span><span class="token template-string graphql language-graphql keyword" style="color:#C586C0">query</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql definition-query function" style="color:#FDEA2F">GetPosts</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">(</span><span class="token template-string graphql language-graphql variable" style="color:#E36209">$limit</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">:</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql scalar" style="color:#8DFFF8">Int</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">)</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">{</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">            </span><span class="token template-string graphql language-graphql property-query">posts</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">(</span><span class="token template-string graphql language-graphql attr-name" style="color:#8DFFF8">limit</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">:</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql variable" style="color:#E36209">$limit</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">)</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">{</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">            </span><span class="token template-string graphql language-graphql property" style="color:#C586C0">id</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">            </span><span class="token template-string graphql language-graphql property" style="color:#C586C0">title</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">            </span><span class="token template-string graphql language-graphql property interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string graphql language-graphql property interpolation keyword" style="color:#C586C0">this</span><span class="token template-string graphql language-graphql property interpolation punctuation" style="color:#fff">.</span><span class="token template-string graphql language-graphql property interpolation property-access" style="color:#C586C0">simulateGraphQLError</span><span class="token template-string graphql language-graphql property interpolation" style="color:#C586C0"> </span><span class="token template-string graphql language-graphql property interpolation operator" style="color:#8DFFF8">?</span><span class="token template-string graphql language-graphql property interpolation" style="color:#C586C0"> </span><span class="token template-string graphql language-graphql property interpolation string" style="color:#FDB869">"nonExistentField"</span><span class="token template-string graphql language-graphql property interpolation" style="color:#C586C0"> </span><span class="token template-string graphql language-graphql property interpolation operator" style="color:#8DFFF8">:</span><span class="token template-string graphql language-graphql property interpolation" style="color:#C586C0"> </span><span class="token template-string graphql language-graphql property interpolation string" style="color:#FDB869">""</span><span class="token template-string graphql language-graphql property interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">            </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">}</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">        </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">}</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">        </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">apollo</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">watchQuery</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        query</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> query</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        variables</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          limit</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">10</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">valueChanges</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">pipe</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token function" style="color:#FDEA2F">takeUntil</span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">unsubscribe$</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token function" style="color:#FDEA2F">mergeMap</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">result</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">simulateNetworkError</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">throwError</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">              </span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Error</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">"Simulated network error"</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">simulateUnexpectedError</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token keyword" style="color:#C586C0">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Error</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">"Simulated unexpected error"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">of</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">result</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token function" style="color:#FDEA2F">catchError</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">handleError</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">of</span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">null</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">subscribe</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token function-variable function" style="color:#FDEA2F">next</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">result</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">result</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">posts </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> result</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">data</span><span class="token operator" style="color:#8DFFF8">?.</span><span class="token plain">posts </span><span class="token operator" style="color:#8DFFF8">||</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">cdr</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">detectChanges</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token function-variable function" style="color:#FDEA2F">error</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">handleError</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token function-variable function" style="color:#FDEA2F">complete</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">cdr</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">detectChanges</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic">// ... (error handling and simulation methods)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Wow, would you look at that beauty? 😍 This component is like a finely tuned engine, ready to fetch your posts with the precision of a Swiss watch. Let's break down what's happening here:</p>
<ol>
<li>We're using Apollo's watchQuery method to fetch our posts. It's like having a personal assistant who's always on the lookout for the latest data.</li>
<li>We've got some nifty error simulation methods. It's like having a crash test dummy for your data fetching - you can deliberately cause errors to see how your app handles them. Safety first, right?</li>
<li>The mergeMap operator is our traffic controller, deciding whether to let the data through or throw an error based on our simulation flags.</li>
<li>We're using takeUntil with a Subject to ensure we clean up our subscriptions when the component is destroyed. It's like having an eco-friendly car that doesn't leave any pollution (memory leaks) behind!</li>
<li>The template gives us a simple UI to fetch posts and trigger various error scenarios. It's like having a dashboard with different buttons to test your car's performance.</li>
</ol>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="error-handling">Error Handling<a href="https://tailcall.run/blog/graphql-angular-client/#error-handling" class="hash-link" aria-label="Direct link to Error Handling" title="Direct link to Error Handling">​</a></h4>
<p>Speaking of errors, Apollo doesn't just fetch data - it's got your back when things go wrong. Check out this error handling logic:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">handleError</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">networkError</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'Network error. Please check your internet connection.'</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">graphQLErrors</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869">GraphQL error: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation">error</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">graphQLErrors</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string interpolation">        </span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation function" style="color:#FDEA2F">map</span><span class="token template-string interpolation punctuation" style="color:#fff">(</span><span class="token template-string interpolation punctuation" style="color:#fff">(</span><span class="token template-string interpolation">e</span><span class="token template-string interpolation operator" style="color:#8DFFF8">:</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation punctuation" style="color:#fff">{</span><span class="token template-string interpolation"> message</span><span class="token template-string interpolation operator" style="color:#8DFFF8">:</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation builtin">any</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation punctuation" style="color:#fff">}</span><span class="token template-string interpolation punctuation" style="color:#fff">)</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation operator" style="color:#8DFFF8">=&gt;</span><span class="token template-string interpolation"> e</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">message</span><span class="token template-string interpolation punctuation" style="color:#fff">)</span><span class="token template-string interpolation"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string interpolation">        </span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation function" style="color:#FDEA2F">join</span><span class="token template-string interpolation punctuation" style="color:#fff">(</span><span class="token template-string interpolation string" style="color:#FDB869">', '</span><span class="token template-string interpolation punctuation" style="color:#fff">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'An unexpected error occurred. Please try again later.'</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">error</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">'Error fetching posts'</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> error</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">cdr</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">detectChanges</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This error handler is like having a built-in mechanic. Whether it's a network issue (like running out of gas) or a GraphQL error (engine trouble), it's got you covered with user-friendly messages.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="wrapping-up-apollo-angular">Wrapping Up Apollo Angular<a href="https://tailcall.run/blog/graphql-angular-client/#wrapping-up-apollo-angular" class="hash-link" aria-label="Direct link to Wrapping Up Apollo Angular" title="Direct link to Wrapping Up Apollo Angular">​</a></h4>
<p>And there you have it, folks! Apollo Angular - the smooth-riding, feature-packed, error-handling marvel of the GraphQL world. It's like driving a luxury car with a supercomputer onboard.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="2-axios---the-versatile-muscle-car-of-http-clients">2. Axios - The Versatile Muscle Car of HTTP Clients<a href="https://tailcall.run/blog/graphql-angular-client/#2-axios---the-versatile-muscle-car-of-http-clients" class="hash-link" aria-label="Direct link to 2. Axios - The Versatile Muscle Car of HTTP Clients" title="Direct link to 2. Axios - The Versatile Muscle Car of HTTP Clients">​</a></h3>
<p>If Apollo Angular is the luxury sports car of GraphQL clients, then Axios is like a classic muscle car - powerful, versatile, and ready to handle anything you throw at it. It might not have all the GraphQL-specific bells and whistles, but boy, can it perform!</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="1-installation-and-integration-steps">1. Installation and Integration Steps<a href="https://tailcall.run/blog/graphql-angular-client/#1-installation-and-integration-steps" class="hash-link" aria-label="Direct link to 1. Installation and Integration Steps" title="Direct link to 1. Installation and Integration Steps">​</a></h4>
<p>Before we hit the gas, let's get our Axios engine installed and tuned up:</p>
<ol>
<li><strong>Installations</strong>.</li>
</ol>
<p>First, rev up your terminal and run:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">npm install axios</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Unlike Apollo, Axios doesn't need any special configuration in your app.config.ts. It's more of a plug-and-play solution. Just import it where you need it, and you're good to go!</p>
<ol>
<li><strong>Code Snippets</strong></li>
</ol>
<p>Now, below we implement data fetching using axios in <code>src/app/axios-angular/post-list.component.ts</code>:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  Component</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  OnInit</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  ChangeDetectorRef</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@angular/core"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">CommonModule</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@angular/common"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> axios</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">AxiosInstance</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> AxiosError</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"axios"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token decorator at operator" style="color:#8DFFF8">@</span><span class="token decorator function" style="color:#FDEA2F">Component</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  selector</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"app-axios-post-list"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  standalone</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">true</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  imports</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token plain">CommonModule</span><span class="token punctuation" style="color:#fff">]</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  template</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;h2&gt;Posts (Axios Angular)&lt;/h2&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;button (click)="fetchPosts()" [disabled]="loading"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      {{ loading ? "Loading..." : "Load Posts" }}</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/button&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;button (click)="triggerNetworkError()"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      Trigger Network Error</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/button&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;button (click)="triggerGraphQLError()"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      Trigger GraphQL Error</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/button&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;button (click)="triggerUnexpectedError()"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      Trigger Unexpected Error</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/button&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;ul *ngIf="!error"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      &lt;li *ngFor="let post of posts"&gt;{{ post.title }}&lt;/li&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/ul&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;div *ngIf="error" class="error-message"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      {{ error }}</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/div&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">  </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic">// ... (styles omitted for brevity)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">export</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">class</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">AxiosPostsListsComponent</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">implements</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">OnInit</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> client</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> AxiosInstance</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  posts</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#fff">[</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  error</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">|</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">null</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">null</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic">// Error simulation flags</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> simulateNetworkError </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> simulateGraphQLError </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> simulateUnexpectedError </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token function" style="color:#FDEA2F">constructor</span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> cdr</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> ChangeDetectorRef</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">client </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> axios</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">create</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      baseURL</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"/graphql"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      headers</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token string-property property" style="color:#C586C0">"Content-Type"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"application/json"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token function" style="color:#FDEA2F">ngOnInit</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token comment" style="color:#30C26D;font-style:italic">// Add a request interceptor</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">client</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">interceptors</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">request</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">use</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">config</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">simulateNetworkError</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> </span><span class="token builtin">Promise</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">reject</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Error</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">"Simulated network error"</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> config</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> </span><span class="token builtin">Promise</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">reject</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> </span><span class="token constant" style="color:#C586C0">GET_DATA</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">        query GetPosts($limit: Int) {</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">        posts(limit: $limit) {</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">            id</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">            title</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">            </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation keyword" style="color:#C586C0">this</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">simulateGraphQLError </span><span class="token template-string interpolation operator" style="color:#8DFFF8">?</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation string" style="color:#FDB869">"nonExistentField"</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation operator" style="color:#8DFFF8">:</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation string" style="color:#FDB869">""</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string string" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">        }</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">        }</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">async</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">query</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">queryString</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> variables</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">try</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">simulateUnexpectedError</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Error</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">"Simulated unexpected error"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> response </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">await</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">client</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">post</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">""</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        query</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> queryString</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        variables</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> response</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">data</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">handleError</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">throw</span><span class="token plain"> error</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">async</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">fetchPosts</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">null</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">posts </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">cdr</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">detectChanges</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">try</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> result </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">await</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">query</span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token constant" style="color:#C586C0">GET_DATA</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        limit</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">10</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">posts </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> result</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">data</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">posts</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">cdr</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">detectChanges</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token comment" style="color:#30C26D;font-style:italic">// Error is already handled in query method</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">cdr</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">detectChanges</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic">// ... (error handling and simulation methods omitted for brevity)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This Axios-powered component is revving up to fetch those posts faster than you can say "GraphQL"! Let's break down what's happening in this high-octane code:</p>
<ol>
<li>We're creating an Axios instance in the constructor. It's like customizing your car with a specific paint job (baseURL) and some cool decals (headers).</li>
<li>The ngOnInit method adds a request interceptor. Think of it as a nitrous oxide system - it can give your requests an extra boost or, in this case, simulate a network error if you want to test your error handling.</li>
<li>Our query method is like the engine of this muscle car. It takes a GraphQL query string and variables, then fires off the request. If something goes wrong, it calls our trusty mechanic (the handleError method).</li>
<li>The fetchPosts method is where the rubber meets the road. It calls our query method with the posts query, then updates our component state with the results.</li>
<li>We've got our error simulation methods, just like in the Apollo example. It's like having different test tracks for your muscle car - you can simulate various error conditions to make sure your code can handle any bumps in the road.</li>
</ol>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="2-error-handling">2. Error Handling<a href="https://tailcall.run/blog/graphql-angular-client/#2-error-handling" class="hash-link" aria-label="Direct link to 2. Error Handling" title="Direct link to 2. Error Handling">​</a></h4>
<p>Now, let's talk about handling of errors:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">handleError</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">axios</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">isAxiosError</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> axiosError </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> error </span><span class="token keyword" style="color:#C586C0">as</span><span class="token plain"> AxiosError</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">axiosError</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">response</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token comment" style="color:#30C26D;font-style:italic">// The request was made and the server responded with a status code</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token comment" style="color:#30C26D;font-style:italic">// that falls out of the range of 2xx</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869">Server error: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation">axiosError</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">response</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">status</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string string" style="color:#FDB869"> </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation">axiosError</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">response</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">statusText</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">axiosError</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">request</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token comment" style="color:#30C26D;font-style:italic">// The request was made but no response was received</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'Network error. Please check your internet connection.'</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token comment" style="color:#30C26D;font-style:italic">// Something happened in setting up the request that triggered an Error</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'An unexpected error occurred. Please try again later.'</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">graphQLErrors</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869">GraphQL error: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation">error</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">graphQLErrors</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string interpolation">        </span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation function" style="color:#FDEA2F">map</span><span class="token template-string interpolation punctuation" style="color:#fff">(</span><span class="token template-string interpolation punctuation" style="color:#fff">(</span><span class="token template-string interpolation">e</span><span class="token template-string interpolation operator" style="color:#8DFFF8">:</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation builtin">any</span><span class="token template-string interpolation punctuation" style="color:#fff">)</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation operator" style="color:#8DFFF8">=&gt;</span><span class="token template-string interpolation"> e</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">message</span><span class="token template-string interpolation punctuation" style="color:#fff">)</span><span class="token template-string interpolation"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string interpolation">        </span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation function" style="color:#FDEA2F">join</span><span class="token template-string interpolation punctuation" style="color:#fff">(</span><span class="token template-string interpolation string" style="color:#FDB869">', '</span><span class="token template-string interpolation punctuation" style="color:#fff">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'An unexpected error occurred. Please try again later.'</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">error</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">'Error fetching posts:'</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> error</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This error handler is like the world's best shock absorber system. Whether you hit a pothole (network error), take a wrong turn (server error), or your engine misfires (unexpected error), it's got you covered with user-friendly messages. It even handles those tricky GraphQL-specific errors!</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="wrapping-up-axios">Wrapping Up Axios<a href="https://tailcall.run/blog/graphql-angular-client/#wrapping-up-axios" class="hash-link" aria-label="Direct link to Wrapping Up Axios" title="Direct link to Wrapping Up Axios">​</a></h4>
<p>And there you have it, Axios - the muscle car of HTTP clients, now tuned up to handle GraphQL queries with style. It might not have all the GraphQL-specific features of Apollo, but it's a powerhouse that can handle just about anything you throw at it.
Axios shines when you need a lightweight, versatile solution that can handle both REST and GraphQL APIs. It's like having a car that's equally at home on the racetrack and the city streets. Plus, if you're already familiar with Axios from REST API work, the learning curve here is as smooth as a freshly paved highway.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="3-fetch-api---the-lean-mean-javascript-machine">3. Fetch API - The Lean, Mean, JavaScript Machine<a href="https://tailcall.run/blog/graphql-angular-client/#3-fetch-api---the-lean-mean-javascript-machine" class="hash-link" aria-label="Direct link to 3. Fetch API - The Lean, Mean, JavaScript Machine" title="Direct link to 3. Fetch API - The Lean, Mean, JavaScript Machine">​</a></h3>
<p>If Apollo was our luxury sports car and Axios our muscle car, then the Fetch API is like a nimble, lightweight motorcycle. It's built right into modern browsers, requires no external libraries, and can zip through traffic with ease. Let's see how this speed demon handles our GraphQL queries!</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="1-installation-and-integration-steps-1">1. Installation and Integration Steps<a href="https://tailcall.run/blog/graphql-angular-client/#1-installation-and-integration-steps-1" class="hash-link" aria-label="Direct link to 1. Installation and Integration Steps" title="Direct link to 1. Installation and Integration Steps">​</a></h4>
<p>Here's the beauty of the Fetch API - there's nothing to install! 🎉 It's like finding out your new apartment comes with a free motorcycle in the garage. Just hop on and ride!</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="2-code-snippets">2. Code Snippets<a href="https://tailcall.run/blog/graphql-angular-client/#2-code-snippets" class="hash-link" aria-label="Direct link to 2. Code Snippets" title="Direct link to 2. Code Snippets">​</a></h4>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">Component</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> ChangeDetectorRef</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@angular/core"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">CommonModule</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@angular/common"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token decorator at operator" style="color:#8DFFF8">@</span><span class="token decorator function" style="color:#FDEA2F">Component</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  selector</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"app-fetch-post-list"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  standalone</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">true</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  imports</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token plain">CommonModule</span><span class="token punctuation" style="color:#fff">]</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  template</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;h2&gt;Posts (Fetch Angular)&lt;/h2&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;button (click)="fetchPosts()" [disabled]="loading"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      {{ loading ? "Loading..." : "Load Posts" }}</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/button&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;button (click)="triggerNetworkError()"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      Trigger Network Error</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/button&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;button (click)="triggerGraphQLError()"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      Trigger GraphQL Error</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/button&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;button (click)="triggerUnexpectedError()"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      Trigger Unexpected Error</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/button&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;ul *ngIf="!error"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      &lt;li *ngFor="let post of posts"&gt;{{ post.title }}&lt;/li&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/ul&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;div *ngIf="error" class="error-message"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      {{ error }}</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/div&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">  </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic">// ... (styles omitted for brevity)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">export</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">class</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">FetchPostListComponent</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> endpoint </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"/graphql"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  posts</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#fff">[</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  error</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">|</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">null</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">null</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic">// Error simulation flags</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> simulateNetworkError </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> simulateGraphQLError </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> simulateUnexpectedError </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token function" style="color:#FDEA2F">constructor</span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> cdr</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> ChangeDetectorRef</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> </span><span class="token constant" style="color:#C586C0">GET_DATA</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">        query GetPosts($limit: Int) {</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">        posts(limit: $limit) {</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">            id</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">            title</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">            </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation keyword" style="color:#C586C0">this</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">simulateGraphQLError </span><span class="token template-string interpolation operator" style="color:#8DFFF8">?</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation string" style="color:#FDB869">"nonExistentField"</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation operator" style="color:#8DFFF8">:</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation string" style="color:#FDB869">""</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string string" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">        }</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">        }</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">async</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">query</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">queryString</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> variables</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">simulateNetworkError</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Error</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">"Simulated network error"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">simulateUnexpectedError</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Error</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">"Simulated unexpected error"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">try</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> response </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">await</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">fetch</span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">endpoint</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        method</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"POST"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        headers</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token string-property property" style="color:#C586C0">"Content-Type"</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"application/json"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        body</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token constant" style="color:#C586C0">JSON</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">stringify</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          query</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> queryString</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          variables</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain">response</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">ok</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Error</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869">HTTP error! status: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation">response</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">status</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> result </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">await</span><span class="token plain"> response</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">json</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">result</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">errors</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Error</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          result</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">errors</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">map</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">e</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> e</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">message</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">join</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">", "</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">return</span><span class="token plain"> result</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">handleError</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">throw</span><span class="token plain"> error</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">async</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">fetchPosts</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">null</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">posts </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">cdr</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">detectChanges</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">try</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> result </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">await</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">query</span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token constant" style="color:#C586C0">GET_DATA</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        limit</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">10</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">posts </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> result</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">data</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">posts</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">cdr</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">detectChanges</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token comment" style="color:#30C26D;font-style:italic">// Error is already handled in query method</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">cdr</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">detectChanges</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic">// ... (error handling and simulation methods omitted for brevity)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This Fetch-powered component is leaner than a greyhound and faster than a caffeinated cheetah! Let's break down what's happening in this high-speed code:</p>
<ol>
<li>No imports needed for Fetch - it's built right into the browser. It's like having a motorcycle that doesn't need gas!</li>
<li>Our query method is the engine of this speed machine. It takes a GraphQL query string and variables, then zooms off to fetch the data.</li>
<li>We're using async/await syntax, which makes our asynchronous code read like a smooth ride down the highway.</li>
<li>The fetchPosts method is where we kick into high gear. It calls our query method with the posts query, then updates our component state with the results.</li>
<li>We've still got our error simulation methods. It's like having different obstacle courses for our motorcycle - we can test how it handles in various tricky situations.</li>
</ol>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="error-handling-1">Error Handling<a href="https://tailcall.run/blog/graphql-angular-client/#error-handling-1" class="hash-link" aria-label="Direct link to Error Handling" title="Direct link to Error Handling">​</a></h4>
<p>Now, let's talk about the suspension system of our Fetch motorcycle - the error handling:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">handleError</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error </span><span class="token keyword" style="color:#C586C0">instanceof</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">TypeError</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">&amp;&amp;</span><span class="token plain"> error</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">message </span><span class="token operator" style="color:#8DFFF8">===</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'Failed to fetch'</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'Network error. Please check your internet connection.'</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error </span><span class="token keyword" style="color:#C586C0">instanceof</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">message</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">includes</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">'GraphQL error'</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869">GraphQL error: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation">error</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">message</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">message</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">startsWith</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">'HTTP error!'</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869">Server error: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation">error</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">message</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'An unexpected error occurred. Please try again later.'</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'An unexpected error occurred. Please try again later.'</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">error</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">'Error fetching posts:'</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> error</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This error handler efficiently manages various error types. It provides user-friendly messages for network issues, server errors, unexpected problems, and GraphQL-specific errors, ensuring a smooth user experience even when things go wrong.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="wrapping-up-fetch-api">Wrapping Up Fetch API<a href="https://tailcall.run/blog/graphql-angular-client/#wrapping-up-fetch-api" class="hash-link" aria-label="Direct link to Wrapping Up Fetch API" title="Direct link to Wrapping Up Fetch API">​</a></h4>
<p>And there you have it, The Fetch API - the nimble, lightweight motorcycle of HTTP clients, now revved up to handle GraphQL queries with style. It might not have all the bells and whistles of Apollo or the versatility of Axios, but it's fast, it's built-in, and it gets the job done with minimal fuss.</p>
<p>Fetch shines when you need a lightweight, no-dependency solution that can handle both REST and GraphQL APIs. It's like having a motorcycle that's equally at home zipping through city traffic or cruising on the open highway. Plus, if you're looking to keep your project dependencies to a minimum, Fetch is your go-to ride.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="4-graphql-request---the-precision-engineered-sports-car">4. GraphQL Request - The Precision-Engineered Sports Car<a href="https://tailcall.run/blog/graphql-angular-client/#4-graphql-request---the-precision-engineered-sports-car" class="hash-link" aria-label="Direct link to 4. GraphQL Request - The Precision-Engineered Sports Car" title="Direct link to 4. GraphQL Request - The Precision-Engineered Sports Car">​</a></h3>
<p>If Apollo was our luxury sedan, Axios our muscle car, and Fetch our nimble motorcycle, then GraphQL Request is like a finely-tuned sports car. It's designed specifically for GraphQL, offering a perfect balance of simplicity and power. Let's see how this beauty handles our data-fetching curves!</p>
<ol>
<li><strong>Installation and Integration Steps</strong>
Before we hit the track, let's get our GraphQL Request engine installed:</li>
</ol>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">npm install graphql-request graphql</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>No special configuration needed in your app.config.ts. Just import it in your component, and you're ready to race!</p>
<ol start="2">
<li><strong>Code Snippets</strong></li>
</ol>
<p>Now, let's pop the hood and examine our GraphQL Request-powered component:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">Component</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> ChangeDetectorRef</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@angular/core"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain">CommonModule</span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@angular/common"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  GraphQLClient</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  gql</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  ClientError</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"graphql-request"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token decorator at operator" style="color:#8DFFF8">@</span><span class="token decorator function" style="color:#FDEA2F">Component</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  selector</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"app-graphql-request-post-list"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  standalone</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">true</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  imports</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token plain">CommonModule</span><span class="token punctuation" style="color:#fff">]</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  template</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;h2&gt;Posts (Graphql Request Angular)&lt;/h2&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;button (click)="fetchPosts()" [disabled]="loading"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      {{ loading ? "Loading..." : "Load Posts" }}</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/button&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;button (click)="triggerNetworkError()"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      Trigger Network Error</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/button&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;button (click)="triggerGraphQLError()"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      Trigger GraphQL Error</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/button&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;button (click)="triggerUnexpectedError()"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      Trigger Unexpected Error</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/button&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;ul *ngIf="!error"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      &lt;li *ngFor="let post of posts"&gt;{{ post.title }}&lt;/li&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/ul&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;div *ngIf="error" class="error-message"&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">      {{ error }}</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">    &lt;/div&gt;</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string string" style="color:#FDB869">  </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic">// ... (styles omitted for brevity)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">export</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">class</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">GraphqlRequestPostListComponent</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> client</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> GraphQLClient</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  posts</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#fff">[</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  error</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">|</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">null</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">null</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic">// Error simulation flags</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> simulateNetworkError </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> simulateGraphQLError </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> simulateUnexpectedError </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token function" style="color:#FDEA2F">constructor</span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> cdr</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> ChangeDetectorRef</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">client </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">GraphQLClient</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token string" style="color:#FDB869">"http://localhost:4200/graphql"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> </span><span class="token constant" style="color:#C586C0">GET_DATA</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> gql</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">        </span><span class="token template-string graphql language-graphql keyword" style="color:#C586C0">query</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql definition-query function" style="color:#FDEA2F">GetPosts</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">(</span><span class="token template-string graphql language-graphql variable" style="color:#E36209">$limit</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">:</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql scalar" style="color:#8DFFF8">Int</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">)</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">{</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">        </span><span class="token template-string graphql language-graphql property-query">posts</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">(</span><span class="token template-string graphql language-graphql attr-name" style="color:#8DFFF8">limit</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">:</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql variable" style="color:#E36209">$limit</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">)</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">{</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">            </span><span class="token template-string graphql language-graphql property" style="color:#C586C0">id</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">            </span><span class="token template-string graphql language-graphql property" style="color:#C586C0">title</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">            </span><span class="token template-string graphql language-graphql property interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string graphql language-graphql property interpolation keyword" style="color:#C586C0">this</span><span class="token template-string graphql language-graphql property interpolation punctuation" style="color:#fff">.</span><span class="token template-string graphql language-graphql property interpolation property-access" style="color:#C586C0">simulateGraphQLError</span><span class="token template-string graphql language-graphql property interpolation" style="color:#C586C0"> </span><span class="token template-string graphql language-graphql property interpolation operator" style="color:#8DFFF8">?</span><span class="token template-string graphql language-graphql property interpolation" style="color:#C586C0"> </span><span class="token template-string graphql language-graphql property interpolation string" style="color:#FDB869">"nonExistentField"</span><span class="token template-string graphql language-graphql property interpolation" style="color:#C586C0"> </span><span class="token template-string graphql language-graphql property interpolation operator" style="color:#8DFFF8">:</span><span class="token template-string graphql language-graphql property interpolation" style="color:#C586C0"> </span><span class="token template-string graphql language-graphql property interpolation string" style="color:#FDB869">""</span><span class="token template-string graphql language-graphql property interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">        </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">}</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">        </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">}</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">    </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">async</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">fetchPosts</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">null</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">posts </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">cdr</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">detectChanges</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">try</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">simulateNetworkError</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Error</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">"Simulated network error"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">simulateUnexpectedError</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Error</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">"Simulated unexpected error"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> result</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">await</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">client</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">request</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token constant" style="color:#C586C0">GET_DATA</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          limit</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">10</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">posts </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> result</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">posts</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">cdr</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">detectChanges</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">handleError</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">cdr</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">detectChanges</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic">// ... (error handling and simulation methods omitted for brevity)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Let's break down what's happening in this high-performance code:</p>
<ol>
<li>We're importing GraphQLClient and gql from graphql-request. It's like having a custom-built engine and transmission, specifically designed for GraphQL roads.</li>
<li>In the constructor, we're initializing our GraphQLClient. It's like setting up the onboard computer of our sports car, telling it exactly where to go for our data.</li>
<li>Our GET_DATA query is defined using the gql tag. It's like programming the GPS with the exact route we want to take.</li>
<li>The fetchPosts method is where we put the pedal to the metal. We're using the client.request method, which is like engaging the launch control on our sports car - it handles everything for us, from acceleration to gear shifts.</li>
<li>We've still got our error simulation methods. It's like having different road conditions we can simulate - wet roads, oil slicks, you name it!</li>
</ol>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="error-handling-2">Error Handling<a href="https://tailcall.run/blog/graphql-angular-client/#error-handling-2" class="hash-link" aria-label="Direct link to Error Handling" title="Direct link to Error Handling">​</a></h4>
<p>Now, let's talk about the advanced traction control system of our GraphQL Request sports car - the error handling:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">handleError</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error </span><span class="token keyword" style="color:#C586C0">instanceof</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">ClientError</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">response</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">errors</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token comment" style="color:#30C26D;font-style:italic">// GraphQL errors</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869">GraphQL error: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation">error</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">response</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">errors</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string interpolation">            </span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation function" style="color:#FDEA2F">map</span><span class="token template-string interpolation punctuation" style="color:#fff">(</span><span class="token template-string interpolation punctuation" style="color:#fff">(</span><span class="token template-string interpolation">e</span><span class="token template-string interpolation punctuation" style="color:#fff">)</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation operator" style="color:#8DFFF8">=&gt;</span><span class="token template-string interpolation"> e</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">message</span><span class="token template-string interpolation punctuation" style="color:#fff">)</span><span class="token template-string interpolation"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string interpolation">            </span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation function" style="color:#FDEA2F">join</span><span class="token template-string interpolation punctuation" style="color:#fff">(</span><span class="token template-string interpolation string" style="color:#FDB869">', '</span><span class="token template-string interpolation punctuation" style="color:#fff">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token comment" style="color:#30C26D;font-style:italic">// Network errors or other HTTP errors</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869">Network error: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation">error</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">response</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">status</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string string" style="color:#FDB869"> </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation">error</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">response</span><span class="token template-string interpolation punctuation" style="color:#fff">[</span><span class="token template-string interpolation string" style="color:#FDB869">'statusText'</span><span class="token template-string interpolation punctuation" style="color:#fff">]</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error </span><span class="token keyword" style="color:#C586C0">instanceof</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">message </span><span class="token operator" style="color:#8DFFF8">===</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'Simulated network error'</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'Network error. Please check your internet connection.'</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'An unexpected error occurred. Please try again later.'</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'An unexpected error occurred. Please try again later.'</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">error</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">'Error fetching posts:'</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> error</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This error handler is like having the world's best traction control and stability management system. Whether you hit a patch of black ice (network error), take a corner too fast (GraphQL error), or encounter an unexpected obstacle (other errors), it's got you covered with user-friendly messages. It even distinguishes between different types of errors, giving you precise control over how to handle each situation.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="wrapping-up-graphql-request">Wrapping Up GraphQL Request<a href="https://tailcall.run/blog/graphql-angular-client/#wrapping-up-graphql-request" class="hash-link" aria-label="Direct link to Wrapping Up GraphQL Request" title="Direct link to Wrapping Up GraphQL Request">​</a></h4>
<p>And there you have it, folks! GraphQL Request - the precision-engineered sports car of GraphQL clients. It's streamlined, efficient, and designed specifically for the twists and turns of GraphQL queries.
GraphQL Request shines when you need a lightweight, GraphQL-specific solution that offers more than Fetch but doesn't require the full ecosystem of Apollo. It's like having a sports car that's perfect for both daily commutes and weekend track days. Plus, its simplicity makes it a joy to work with, especially for smaller to medium-sized projects.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="5-urql-in-angular">5. Urql in Angular<a href="https://tailcall.run/blog/graphql-angular-client/#5-urql-in-angular" class="hash-link" aria-label="Direct link to 5. Urql in Angular" title="Direct link to 5. Urql in Angular">​</a></h3>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="installation-and-integration-steps-1">Installation and Integration Steps<a href="https://tailcall.run/blog/graphql-angular-client/#installation-and-integration-steps-1" class="hash-link" aria-label="Direct link to Installation and Integration Steps" title="Direct link to Installation and Integration Steps">​</a></h4>
<p>First things first, let's get our hands dirty with some installation magic. To bring Urql into your Angular project, you'll need to wave your command line wand and chant:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">npm install @urql/core graphql</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>We need to set up our Urql client.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="code-snippets-and-explanation">Code Snippets and Explanation<a href="https://tailcall.run/blog/graphql-angular-client/#code-snippets-and-explanation" class="hash-link" aria-label="Direct link to Code Snippets and Explanation" title="Direct link to Code Snippets and Explanation">​</a></h4>
<p>Let's break down our UrqlPostListComponent which you'll create following the same format above and solder structure:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  createClient</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  fetchExchange</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  cacheExchange</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  Client</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"@urql/core"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token comment" style="color:#30C26D;font-style:italic">// ... other imports</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">export</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">class</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">UrqlPostListComponent</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  client</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> Client</span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token function" style="color:#FDEA2F">constructor</span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> cdr</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> ChangeDetectorRef</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">client </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">createClient</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      url</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"http://localhost:4200/graphql"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      exchanges</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token plain">cacheExchange</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> fetchExchange</span><span class="token punctuation" style="color:#fff">]</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic">// ... rest of the component</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Here, we're setting up our Urql client faster than you can say "GraphQL". We're telling it where to find our GraphQL endpoint and which exchanges to use. Think of exchanges as middleware for your GraphQL requests - they're like bouncers at a club, deciding how to handle incoming and outgoing traffic.</p>
<p>Now, let's look at how we're fetching posts:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">    getPostsQuery </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> gql</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">    </span><span class="token template-string graphql language-graphql keyword" style="color:#C586C0">query</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql definition-query function" style="color:#FDEA2F">GetPosts</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">(</span><span class="token template-string graphql language-graphql variable" style="color:#E36209">$limit</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">:</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql scalar" style="color:#8DFFF8">Int</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">)</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">{</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">        </span><span class="token template-string graphql language-graphql property-query">posts</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">(</span><span class="token template-string graphql language-graphql attr-name" style="color:#8DFFF8">limit</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">:</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql variable" style="color:#E36209">$limit</span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">)</span><span class="token template-string graphql language-graphql"> </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">{</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">        </span><span class="token template-string graphql language-graphql property" style="color:#C586C0">id</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">        </span><span class="token template-string graphql language-graphql property" style="color:#C586C0">title</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">        </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">}</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">    </span><span class="token template-string graphql language-graphql punctuation" style="color:#fff">}</span><span class="token template-string graphql language-graphql"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string graphql language-graphql">    </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token function" style="color:#FDEA2F">fetchPosts</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">true</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">null</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">posts </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token punctuation" style="color:#fff">]</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">cdr</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">detectChanges</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">client</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">query</span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">getPostsQuery</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"> limit</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">10</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">toPromise</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">then</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">result</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">result</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">handleError</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">result</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">posts </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> result</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">data</span><span class="token operator" style="color:#8DFFF8">?.</span><span class="token plain">posts </span><span class="token operator" style="color:#8DFFF8">||</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token punctuation" style="color:#fff">]</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">            </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">cdr</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">detectChanges</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">catch</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">handleError</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">finally</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">cdr</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">detectChanges</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This fetchPosts method is where the magic happens. We're using Urql's query method to fetch our posts, handling the result like a pro juggler. If there's an error, we toss it to our error handler. If it's successful, we update our posts faster than you can say "data fetched"!</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="error-handling-3">Error Handling<a href="https://tailcall.run/blog/graphql-angular-client/#error-handling-3" class="hash-link" aria-label="Direct link to Error Handling" title="Direct link to Error Handling">​</a></h4>
<p>Now, let's talk about error handling. In the world of APIs, errors are like unexpected plot twists in a movie - they keep things interesting, but you need to know how to handle them:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">private</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">handleError</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token operator" style="color:#8DFFF8">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">loading </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error </span><span class="token keyword" style="color:#C586C0">instanceof</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">CombinedError</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">networkError</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'Network error. Please check your internet connection.'</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">graphQLErrors</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">length </span><span class="token operator" style="color:#8DFFF8">&gt;</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">0</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869">GraphQL error: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation">error</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">graphQLErrors</span><br></span><span class="token-line" style="color:#fff"><span class="token template-string interpolation">            </span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation function" style="color:#FDEA2F">map</span><span class="token template-string interpolation punctuation" style="color:#fff">(</span><span class="token template-string interpolation punctuation" style="color:#fff">(</span><span class="token template-string interpolation">e</span><span class="token template-string interpolation punctuation" style="color:#fff">)</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation operator" style="color:#8DFFF8">=&gt;</span><span class="token template-string interpolation"> e</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">message</span><span class="token template-string interpolation punctuation" style="color:#fff">)</span><span class="token template-string interpolation"></span><br></span><span class="token-line" style="color:#fff"><span class="token template-string interpolation">            </span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation function" style="color:#FDEA2F">join</span><span class="token template-string interpolation punctuation" style="color:#fff">(</span><span class="token template-string interpolation string" style="color:#FDB869">', '</span><span class="token template-string interpolation punctuation" style="color:#fff">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">error </span><span class="token keyword" style="color:#C586C0">instanceof</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Error</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token template-string string" style="color:#FDB869">An unexpected error occurred: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">${</span><span class="token template-string interpolation">error</span><span class="token template-string interpolation punctuation" style="color:#fff">.</span><span class="token template-string interpolation">message</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#fff">}</span><span class="token template-string template-punctuation string" style="color:#FDB869">`</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">error </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'An unexpected error occurred. Please try again later.'</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token builtin">console</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">error</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">'Error fetching posts:'</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> error</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">this</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">cdr</span><span class="token punctuation" style="color:#fff">.</span><span class="token function" style="color:#FDEA2F">detectChanges</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This error handler is like a Swiss Army knife for API errors. Network error? We've got you covered. GraphQL error? No problem. Unexpected error that makes you question the nature of reality? We handle that too!
Why Choose Urql?
You might be wondering, "Why should I choose Urql over other options?" Well, let me tell you, Urql is like that cool, efficient friend who always knows the best way to get things done:</p>
<ol>
<li><strong>Lightweight</strong>: Urql is as light as a feather, which means your app won't feel like it's carrying extra baggage.</li>
<li><strong>Flexible</strong>: It's adaptable to various use cases, like a chameleon in the coding world.</li>
<li><strong>Great Developer Experience</strong>: With Urql, you'll feel like you're coding with a tailwind, not against a headwind.</li>
</ol>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</div><div class="admonitionContent_BuS1"><p>Want to see all this in action?
Check out our GitHub repo!</p><p>We've put together a complete set of working examples for everything we've covered in this article. It's the perfect companion to help you dive deeper into Angular and GraphQL.</p><p><a href="https://github.com/onyedikachi-david/angular-graphql-multiapproach" target="_blank" rel="noopener noreferrer">Explore the code on GitHub</a></p></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="detailed-comparison-table">Detailed Comparison Table<a href="https://tailcall.run/blog/graphql-angular-client/#detailed-comparison-table" class="hash-link" aria-label="Direct link to Detailed Comparison Table" title="Direct link to Detailed Comparison Table">​</a></h2>
<table><thead><tr><th>Method</th><th>Bundle Size (minified + gzip)*</th><th>Learning Curve</th><th>Caching Capabilities</th><th>Community Support</th><th>Additional Features</th></tr></thead><tbody><tr><td>Apollo Angular¹</td><td>258 KB</td><td>Moderate</td><td>Extensive (InMemoryCache, customizable)</td><td>High</td><td>State management, optimistic UI updates</td></tr><tr><td>Urql²</td><td>17 KB</td><td>Low</td><td>Moderate (Document and normalized caching)</td><td>Moderate</td><td>Extensible architecture, lightweight, plugin system</td></tr><tr><td>GraphQL-Request³</td><td>58.6 KB</td><td>Low</td><td>None (Minimal client)</td><td>Moderate</td><td>Simplicity, works in Node and browsers</td></tr><tr><td>Axios⁴</td><td>24 KB</td><td>Low</td><td>None (HTTP client only)</td><td>High</td><td>Familiar HTTP handling, interceptors</td></tr><tr><td>Fetch API</td><td>0 KB (Browser built-in)</td><td>Low</td><td>None (Native API)</td><td>High</td><td>No additional dependency, widely supported</td></tr></tbody></table>
<p>(*) Bundle sizes are based on bundlejs.com calculations using the provided export statements, with minification and gzip compression applied.</p>
<p><strong>Notes:</strong></p>
<ol>
<li>Apollo Angular's bundle size (258 KB gzipped) is significantly larger than other options, which may impact initial load times for applications.</li>
<li>Urql offers a much smaller bundle size (17 KB gzipped) while still providing both document caching and normalized caching through its plugin architecture.</li>
<li>GraphQL-Request, despite being a minimal client, has a larger bundle size (58.6 KB gzipped) than expected, which might be due to including the full GraphQL parser.</li>
<li>Axios, a general-purpose HTTP client, has a moderate bundle size (24 KB gzipped) considering its feature set.</li>
<li>The Fetch API remains the lightest option as it's built into modern browsers, but it lacks some conveniences provided by other libraries.</li>
<li>Bundle sizes for critical path libraries can significantly impact performance. Consider lazy-loading or code-splitting strategies when using larger libraries like Apollo Angular.</li>
</ol>
<p><strong>Bundle Size References:</strong></p>
<ol>
<li>Apollo Angular: <a href="https://bundlejs.com/?q=apollo-angular%2Capollo-angular%2Fhttp%2C%40apollo%2Fclient%2Fcore&amp;treeshake=%5B%7B+APOLLO_OPTIONS%2CApolloModule+%7D%5D%2C%5B%7B+HttpLink+%7D%5D%2C%5B%7B+InMemoryCache+%7D%5D" target="_blank" rel="noopener noreferrer">bundlejs.com link</a></li>
<li>Urql: <a href="https://bundlejs.com/?q=urql%2C%40urql%2Fcore&amp;treeshake=%5B%7B+createClient%2CProvider%2CuseQuery%2CuseMutation+%7D%5D%2C%5B%7B+cacheExchange%2CfetchExchange+%7D%5D" target="_blank" rel="noopener noreferrer">bundlejs.com link</a></li>
<li>GraphQL-Request: <a href="https://bundlejs.com/?q=graphql-request&amp;treeshake=%5B%7B+GraphQLClient%2Cgql+%7D%5D" target="_blank" rel="noopener noreferrer">bundlejs.com link</a></li>
<li>Axios: <a href="https://bundlejs.com/?q=axios&amp;treeshake=%5B%7B+default+as+axios+%7D%5D" target="_blank" rel="noopener noreferrer">bundlejs.com link</a></li>
</ol>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="caching-capabilities">Caching Capabilities<a href="https://tailcall.run/blog/graphql-angular-client/#caching-capabilities" class="hash-link" aria-label="Direct link to Caching Capabilities" title="Direct link to Caching Capabilities">​</a></h3>
<ol>
<li>
<p><strong>Apollo Angular</strong></p>
<ul>
<li>Extensive caching capabilities through InMemoryCache</li>
<li>Normalization of data for efficient storage and retrieval</li>
<li>Customizable cache policies (cache-first, network-only, etc.)</li>
<li>Automatic cache updates on mutations</li>
<li>Support for pagination and optimistic UI updates</li>
<li>Ability to manually update and read from the cache</li>
</ul>
</li>
<li>
<p><strong>Urql</strong></p>
<ul>
<li>Document caching by default</li>
<li>Customizable caching through exchangeable cache implementations</li>
<li>Supports normalized caching with additional setup</li>
<li>Cache invalidation and updates through GraphQL mutations</li>
<li>Simpler caching model compared to Apollo, focusing on ease of use</li>
</ul>
</li>
<li>
<p><strong>GraphQL-Request</strong></p>
<ul>
<li>No built-in caching mechanism</li>
<li>Requires manual implementation of caching if needed</li>
<li>Can be combined with external caching solutions or state management libraries</li>
</ul>
</li>
<li>
<p><strong>Axios</strong></p>
<ul>
<li>No built-in GraphQL-specific caching</li>
<li>Can implement HTTP-level caching (e.g., using headers)</li>
<li>Requires manual implementation of application-level caching</li>
<li>Can be combined with state management libraries for more sophisticated caching</li>
</ul>
</li>
<li>
<p><strong>Fetch API</strong></p>
<ul>
<li>No built-in GraphQL-specific caching</li>
<li>Supports basic HTTP caching through cache-control headers</li>
<li>Requires manual implementation of application-level caching</li>
<li>Can be combined with other libraries or custom solutions for more advanced caching</li>
</ul>
</li>
</ol>
<p>In summary, Apollo Angular offers the most robust out-of-the-box caching solution, followed by Urql with its flexible caching system. GraphQL-Request, Axios, and Fetch API do not provide GraphQL-specific caching, requiring developers to implement their own caching strategies or integrate with other libraries for advanced caching needs.</p>
<p>When choosing an approach, consider your application's complexity, performance requirements, and willingness to manage caching manually versus leveraging built-in solutions.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="common-issues-and-resolutions">Common Issues and Resolutions<a href="https://tailcall.run/blog/graphql-angular-client/#common-issues-and-resolutions" class="hash-link" aria-label="Direct link to Common Issues and Resolutions" title="Direct link to Common Issues and Resolutions">​</a></h2>
<ol>
<li>
<p><strong>Apollo Angular</strong></p>
<p>Issue: Cache inconsistencies after mutations
Resolution:</p>
<ul>
<li>Ensure proper cache updates in mutation's <code>update</code> function</li>
<li>Use <code>refetchQueries</code> option to refresh related queries</li>
<li>Implement <code>optimisticResponse</code> for immediate UI updates</li>
</ul>
<p>Issue: Over-fetching data
Resolution:</p>
<ul>
<li>Utilize fragments for reusable field selections</li>
<li>Implement proper query splitting for components</li>
<li>Use <code>@connection</code> directive for pagination to avoid refetching all data</li>
</ul>
</li>
<li>
<p><strong>Urql</strong></p>
<p>Issue: Stale data after mutations
Resolution:</p>
<ul>
<li>Use the <code>cache-and-network</code> request policy</li>
<li>Implement cache updates in mutation's <code>updates</code> option</li>
<li>Utilize the <code>refocusExchange</code> for automatic refetching on window focus</li>
</ul>
<p>Issue: Complex state management
Resolution:</p>
<ul>
<li>Combine Urql with external state management libraries like NgRx if needed</li>
<li>Leverage Urql's <code>useQuery</code> and <code>useMutation</code> hooks for simpler state handling</li>
</ul>
</li>
<li>
<p><strong>GraphQL-Request</strong></p>
<p>Issue: Lack of automatic caching
Resolution:</p>
<ul>
<li>Implement manual caching using services or state management libraries</li>
<li>Use HTTP caching headers for basic caching needs</li>
<li>Consider switching to Apollo or Urql for more complex applications</li>
</ul>
<p>Issue: Error handling complexities
Resolution:</p>
<ul>
<li>Implement a centralized error handling service</li>
<li>Use TypeScript for better type checking and error prevention</li>
<li>Wrap GraphQL-Request calls in try-catch blocks for granular error handling</li>
</ul>
</li>
<li>
<p><strong>Axios</strong></p>
<p>Issue: Constructing complex GraphQL queries
Resolution:</p>
<ul>
<li>Use template literals for dynamic query construction</li>
<li>Implement a query builder utility for complex queries</li>
<li>Consider using a GraphQL-specific library for very complex schemas</li>
</ul>
<p>Issue: Handling GraphQL errors
Resolution:</p>
<ul>
<li>Check for <code>errors</code> array in the response body</li>
<li>Implement custom error classes for different GraphQL error types</li>
<li>Use interceptors for global error handling</li>
</ul>
</li>
<li>
<p><strong>Fetch API</strong></p>
<p>Issue: Verbose syntax for GraphQL operations
Resolution:</p>
<ul>
<li>Create utility functions to abstract common GraphQL operations</li>
<li>Use TypeScript interfaces for better type safety and autocompletion</li>
<li>Consider using a lightweight wrapper around Fetch for GraphQL specifics</li>
</ul>
<p>Issue: Limited built-in features
Resolution:</p>
<ul>
<li>Implement custom middleware for features like retries and caching</li>
<li>Use external libraries for advanced features (e.g., Observable support)</li>
<li>Create a custom Angular service to encapsulate Fetch API logic</li>
</ul>
</li>
</ol>
<p>General Resolutions:</p>
<ul>
<li>Implement proper error boundaries in your Angular components</li>
<li>Use TypeScript for better type checking and IDE support</li>
<li>Leverage Angular's HttpInterceptors for global request/response handling</li>
<li>Implement proper loading states to improve user experience during data fetching</li>
<li>Use environment variables for GraphQL endpoint configuration</li>
</ul>
<p>By addressing these common issues, developers can create more robust and efficient GraphQL implementations in their Angular applications, regardless of the chosen approach.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion">Conclusion<a href="https://tailcall.run/blog/graphql-angular-client/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>As we've journeyed through the landscape of GraphQL integration in Angular, we've explored five distinct approaches, each with its own strengths and considerations. Let's recap and draw some final insights:</p>
<ol>
<li>
<p><strong>Apollo Angular</strong> emerges as the powerhouse solution, offering a comprehensive feature set including robust caching, state management, and optimistic UI updates. It's ideal for large-scale applications with complex data requirements, though it comes with a steeper learning curve and larger bundle size.</p>
</li>
<li>
<p><strong>Urql</strong> strikes a balance between functionality and simplicity. Its lightweight nature and extensible architecture make it an excellent choice for projects that need flexibility without the full weight of Apollo. It's particularly suitable for medium-sized applications or teams that prefer a more customizable approach.</p>
</li>
<li>
<p><strong>GraphQL-Request</strong> shines in its simplicity. For small projects or microservices where basic GraphQL operations are all that's needed, it provides a no-frills solution with minimal overhead. However, it lacks built-in caching and advanced features, which may become limitations as your project grows.</p>
</li>
<li>
<p><strong>Axios</strong>, while not GraphQL-specific, leverages its widespread adoption and familiarity among developers. It's a solid choice for teams already using Axios in their stack or for projects that mix RESTful and GraphQL APIs. However, it requires more manual work for GraphQL-specific features.</p>
</li>
<li>
<p><strong>Fetch API</strong> represents the most lightweight approach, with zero additional bundle size. It's ideal for projects prioritizing minimal dependencies and maximum browser compatibility. However, it necessitates more boilerplate code and manual implementation of GraphQL-specific features.</p>
</li>
</ol>
<p>The choice between these approaches ultimately depends on your project's specific needs, your team's expertise, and your application's scalability requirements. Here are some final recommendations:</p>
<ul>
<li>For large, data-intensive applications with complex requirements, Apollo Angular is likely your best bet.</li>
<li>If you're looking for a lightweight yet capable solution, Urql offers an excellent middle ground.</li>
<li>For smaller projects or microservices, GraphQL-Request or Fetch API might be sufficient.</li>
<li>If your project involves a mix of REST and GraphQL APIs, consider Axios for its versatility.</li>
</ul>
<p>Remember, there's no one-size-fits-all solution. The best approach is the one that aligns with your project's needs and your team's capabilities. As your application evolves, don't hesitate to reassess and switch approaches if necessary.</p>
<p>Whichever path you choose, GraphQL's power in providing flexible, efficient data fetching can significantly enhance your Angular applications. By understanding these different approaches, you're now equipped to make an informed decision and leverage GraphQL to its full potential in your Angular projects.</p>
<p>Happy coding, and may your GraphQL queries be ever efficient!</p>]]></content:encoded>
            <category>GraphQL</category>
            <category>Angular</category>
            <category>Apollo client</category>
        </item>
        <item>
            <title><![CDATA[gRPC Decoded: The API Protocol That's Changing Everything]]></title>
            <link>https://tailcall.run/blog/what-is-grpc/</link>
            <guid>https://tailcall.run/blog/what-is-grpc/</guid>
            <pubDate>Sat, 13 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Demystify gRPC and its impact on modern software architecture. Explore how this powerful tool is reshaping the landscape of API communication.]]></description>
            <content:encoded><![CDATA[<p>gRPC is an open-source RPC (Remote Procedure Call) framework initially developed by Google. It enables efficient communication between services across different environments, utilizing a binary serialization format called Protocol Buffers (Protobuf) over HTTP/2.</p>
<p>gRPC plays a crucial role in modernizing software architectures by providing efficient, high-performance communication channels. Due to it's low-latency, it is used by many well-known software like Kubernetes, CockroachDB and Netflix etc.</p>
<p><a href="https://github.com/kubernetes/kubernetes/blob/0c8b3e5f305bf2bf56d47019199b81330d90c2c3/staging/src/k8s.io/kms/apis/v1beta1/api.proto#L29" target="_blank" rel="noopener noreferrer">An Example Snippet from Kubernetes</a></p>
<p><em>sample code for gRPC:</em></p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-protobuf codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-protobuf codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">syntax</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"proto3"</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">package</span><span class="token plain"> greeting</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">service</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">GreetingService</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">rpc</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">SayHello</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token class-name" style="color:#C586C0">HelloRequest</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">returns</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token class-name" style="color:#C586C0">HelloResponse</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">message</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">HelloRequest</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token builtin">string</span><span class="token plain"> name </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">1</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">message</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">HelloResponse</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token builtin">string</span><span class="token plain"> message </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">1</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-evolution-of-api-communication">The Evolution of API Communication<a href="https://tailcall.run/blog/what-is-grpc/#the-evolution-of-api-communication" class="hash-link" aria-label="Direct link to The Evolution of API Communication" title="Direct link to The Evolution of API Communication">​</a></h2>
<p><img decoding="async" loading="lazy" alt="evolution" src="https://tailcall.run/assets/images/timeline-74749c2b92508f20a5afef12bff4741f.png" width="1263" height="316" class="img_ev3q"></p>
<p>Request–response protocols date back to early distributed computing in the late 1960s. Theoretical proposals of remote procedure calls as the model of network operations date to the 1970s, with practical implementations emerging in the early 1980s. Traditional RPC mechanisms had limitations in terms of performance, language independence, and flexibility. gRPC addresses these issues by leveraging modern protocols and technologies.</p>
<p>gRPC was initially created by Google, which used a single general-purpose RPC infrastructure called Stubby to connect its numerous microservices. In 2015, Google decided to build the next version of Stubby and make it open source.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="understanding-grpc">Understanding gRPC<a href="https://tailcall.run/blog/what-is-grpc/#understanding-grpc" class="hash-link" aria-label="Direct link to Understanding gRPC" title="Direct link to Understanding gRPC">​</a></h2>
<p>gRPC is a high-performance, language-neutral RPC framework. It uses Protobuf for serialization and HTTP/2 for transport, offering features like streaming, multiplexing, and bidirectional communication. It uses HTTP/2 for transport, Protocol Buffers as the interface description language, and provides features such as authentication, bidirectional streaming and flow control, blocking or nonblocking bindings, and cancellation and timeouts.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="key-components-of-grpc">Key components of gRPC<a href="https://tailcall.run/blog/what-is-grpc/#key-components-of-grpc" class="hash-link" aria-label="Direct link to Key components of gRPC" title="Direct link to Key components of gRPC">​</a></h3>
<ul>
<li>
<p><strong>Protocol Buffers (Protobuf):</strong> A language-neutral, platform-neutral, extensible mechanism for serializing structured data. It is used to define the structure of messages (request and response payloads) that gRPC services exchange.</p>
</li>
<li>
<p><strong>HTTP/2:</strong> Provides additional capabilities such as multiplexing, header compression, and server push, which are not as efficient and reliable in HTTP/1.1</p>
</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="how-grpc-works-step-by-step-process">How gRPC works (step-by-step process)<a href="https://tailcall.run/blog/what-is-grpc/#how-grpc-works-step-by-step-process" class="hash-link" aria-label="Direct link to How gRPC works (step-by-step process)" title="Direct link to How gRPC works (step-by-step process)">​</a></h3>
<p><img decoding="async" loading="lazy" alt="step by step process" src="https://tailcall.run/assets/images/steps-fcfc17e96ed67559f7b2e5a1870ea25b.png" width="1006" height="383" class="img_ev3q"></p>
<p>gRPC (Remote Procedure Call) works using a straightforward yet powerful mechanism that facilitates communication between clients and servers in a distributed system.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="1-service-definition">1. Service Definition<a href="https://tailcall.run/blog/what-is-grpc/#1-service-definition" class="hash-link" aria-label="Direct link to 1. Service Definition" title="Direct link to 1. Service Definition">​</a></h3>
<ul>
<li><strong>Protocol Buffers (Protobuf)</strong>: The starting point for using gRPC is defining a service and its methods using Protocol Buffers (Protobuf). Protobuf is a language-neutral, platform-neutral, extensible mechanism for serializing structured data. The structure of data and services is defined in a <code>.proto</code> file.</li>
</ul>
<p><a href="https://github.com/linkerd/linkerd2/blob/ad0546b488fad76879e654ad91ceed1e9e53d630/proto/common/net.proto#L4" target="_blank" rel="noopener noreferrer">An Example Snippet From Linkerd</a></p>
<p><em>Example of a simple <code>.proto</code> file :</em></p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-protobuf codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-protobuf codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">syntax</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"proto3"</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">package</span><span class="token plain"> calculator</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">service</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">CalculatorService</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">rpc</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">Add</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token class-name" style="color:#C586C0">AddRequest</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">returns</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token class-name" style="color:#C586C0">AddResponse</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">message</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">AddRequest</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token builtin">double</span><span class="token plain"> number1 </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">1</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token builtin">double</span><span class="token plain"> number2 </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">2</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">message</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">AddResponse</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token builtin">double</span><span class="token plain"> result </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">1</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="2-code-generation">2. Code Generation<a href="https://tailcall.run/blog/what-is-grpc/#2-code-generation" class="hash-link" aria-label="Direct link to 2. Code Generation" title="Direct link to 2. Code Generation">​</a></h3>
<p>Once a service is defined in a .proto file, the Protocol Buffer compiler (protoc) is used to generate client and server code in your chosen programming languages. This step is crucial as it automates the creation of the boilerplate code needed for the gRPC service and client to communicate effectively. The generated code includes:</p>
<ul>
<li>
<p><strong>Service Stubs:</strong> These are classes with methods that correspond to the service methods defined in the .proto file. They handle the marshalling and unmarshalling of request and response messages, abstracting away the complexities of network communication.</p>
</li>
<li>
<p><strong>Client-Side Stubs:</strong> These are used by the client application to make remote procedure calls to the server. The client stubs handle the creation and sending of requests, as well as receiving and processing responses.</p>
</li>
</ul>
<p>For Example if the calculator example is converted to python, it would look something like this:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token comment" style="color:#30C26D;font-style:italic"># -*- coding: utf-8 -*-</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token comment" style="color:#30C26D;font-style:italic"># Generated by the protocol buffer compiler.  DO NOT EDIT!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token comment" style="color:#30C26D;font-style:italic"># source: calculator</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token triple-quoted-string string" style="color:#FDB869">"""Generated protocol buffer code."""</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> google</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">protobuf </span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> descriptor </span><span class="token keyword" style="color:#C586C0">as</span><span class="token plain"> _descriptor</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> google</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">protobuf </span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> descriptor_pool </span><span class="token keyword" style="color:#C586C0">as</span><span class="token plain"> _descriptor_pool</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> google</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">protobuf </span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> message </span><span class="token keyword" style="color:#C586C0">as</span><span class="token plain"> _message</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> google</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">protobuf </span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> reflection </span><span class="token keyword" style="color:#C586C0">as</span><span class="token plain"> _reflection</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">from</span><span class="token plain"> google</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">protobuf </span><span class="token keyword" style="color:#C586C0">import</span><span class="token plain"> symbol_database </span><span class="token keyword" style="color:#C586C0">as</span><span class="token plain"> _symbol_database</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token comment" style="color:#30C26D;font-style:italic"># @@protoc_insertion_point(imports)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">_sym_db </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> _symbol_database</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">Default</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">DESCRIPTOR </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> _descriptor_pool</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">Default</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">AddSerializedFile</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">b'\n\ncalculator\x12\ncalculator\".\n\nAddRequest\x12\x0f\n\x07number1\x18\x01 \x01(\x01\x12\x0f\n\x07number2\x18\x02 \x01(\x01\"\x1d\n\x0b\x41\x64\x64Response\x12\x0e\n\x06result\x18\x01 \x01(\x01\x32K\n\x11\x43\x61lculatorService\x12\x36\n\x03\x41\x64\x64\x12\x16.calculator.AddRequest\x1a\x17.calculator.AddResponseb\x06proto3'</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">_ADDREQUEST </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> DESCRIPTOR</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">message_types_by_name</span><span class="token punctuation" style="color:#fff">[</span><span class="token string" style="color:#FDB869">'AddRequest'</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">_ADDRESPONSE </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> DESCRIPTOR</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">message_types_by_name</span><span class="token punctuation" style="color:#fff">[</span><span class="token string" style="color:#FDB869">'AddResponse'</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">AddRequest </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> _reflection</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">GeneratedProtocolMessageType</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">'AddRequest'</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">_message</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">Message</span><span class="token punctuation" style="color:#fff">,</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token string" style="color:#FDB869">'DESCRIPTOR'</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> _ADDREQUEST</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token string" style="color:#FDB869">'__module__'</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'calculator_pb2'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token comment" style="color:#30C26D;font-style:italic"># @@protoc_insertion_point(class_scope:calculator.AddRequest)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">_sym_db</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">RegisterMessage</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">AddRequest</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">AddResponse </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> _reflection</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">GeneratedProtocolMessageType</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">'AddResponse'</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">_message</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">Message</span><span class="token punctuation" style="color:#fff">,</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token string" style="color:#FDB869">'DESCRIPTOR'</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> _ADDRESPONSE</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token string" style="color:#FDB869">'__module__'</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">'calculator_pb2'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token comment" style="color:#30C26D;font-style:italic"># @@protoc_insertion_point(class_scope:calculator.AddResponse)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">_sym_db</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">RegisterMessage</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">AddResponse</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">_CALCULATORSERVICE </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> DESCRIPTOR</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">services_by_name</span><span class="token punctuation" style="color:#fff">[</span><span class="token string" style="color:#FDB869">'CalculatorService'</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">if</span><span class="token plain"> _descriptor</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">_USE_C_DESCRIPTORS </span><span class="token operator" style="color:#8DFFF8">==</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">False</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">DESCRIPTOR</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">_options </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">None</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">_ADDREQUEST</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">_serialized_start</span><span class="token operator" style="color:#8DFFF8">=</span><span class="token number" style="color:#C586C0">26</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">_ADDREQUEST</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">_serialized_end</span><span class="token operator" style="color:#8DFFF8">=</span><span class="token number" style="color:#C586C0">72</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">_ADDRESPONSE</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">_serialized_start</span><span class="token operator" style="color:#8DFFF8">=</span><span class="token number" style="color:#C586C0">74</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">_ADDRESPONSE</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">_serialized_end</span><span class="token operator" style="color:#8DFFF8">=</span><span class="token number" style="color:#C586C0">103</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">_CALCULATORSERVICE</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">_serialized_start</span><span class="token operator" style="color:#8DFFF8">=</span><span class="token number" style="color:#C586C0">105</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">_CALCULATORSERVICE</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">_serialized_end</span><span class="token operator" style="color:#8DFFF8">=</span><span class="token number" style="color:#C586C0">180</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token comment" style="color:#30C26D;font-style:italic"># @@protoc_insertion_point(module_scope)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="3-client-server-communication">3. Client-Server Communication<a href="https://tailcall.run/blog/what-is-grpc/#3-client-server-communication" class="hash-link" aria-label="Direct link to 3. Client-Server Communication" title="Direct link to 3. Client-Server Communication">​</a></h3>
<ul>
<li><strong>Transmission</strong>:
When a gRPC client initiates a request to a gRPC server, it sends an HTTP/2 request containing the service name, specific method, and serialized parameters using Protobuf. HTTP/2's advantages include multiplexing, enabling concurrent handling of multiple streams over a single connection, binary framing that minimizes overhead and accelerates data exchange, efficient header compression via HPACK, and integrated flow control mechanisms.</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="4-serialization-and-deserialization">4. Serialization and Deserialization<a href="https://tailcall.run/blog/what-is-grpc/#4-serialization-and-deserialization" class="hash-link" aria-label="Direct link to 4. Serialization and Deserialization" title="Direct link to 4. Serialization and Deserialization">​</a></h3>
<ul>
<li><strong>Protobuf Serialization</strong>: Data exchanged between gRPC clients and servers is serialized and deserialized using Protobuf.</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="grpc-service-methods">gRPC Service Methods<a href="https://tailcall.run/blog/what-is-grpc/#grpc-service-methods" class="hash-link" aria-label="Direct link to gRPC Service Methods" title="Direct link to gRPC Service Methods">​</a></h2>
<p><img decoding="async" loading="lazy" alt="gRPC Methods" src="https://tailcall.run/assets/images/methods-35307e474e222e0f3266a391be1d2e8f.png" width="602" height="404" class="img_ev3q"></p>
<ul>
<li>
<p><strong>Unary RPC</strong>: This is the simplest form where the client sends a single request to the server and receives a single response:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-protobuf codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-protobuf codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">service</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">MyService</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">rpc</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">UnaryExample</span><span class="token punctuation" style="color:#fff">(</span><span class="token class-name" style="color:#C586C0">MyRequest</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">returns</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token class-name" style="color:#C586C0">MyResponse</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
</li>
<li>
<p><strong>Server Streaming RPC</strong>: The client sends a request to the server and receives a stream of responses:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-protobuf codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-protobuf codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">service</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">MyService</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">rpc</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">UnaryExample</span><span class="token punctuation" style="color:#fff">(</span><span class="token class-name" style="color:#C586C0">MyRequest</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">returns</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">stream</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">MyResponse</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
</li>
<li>
<p><strong>Client Streaming RPC</strong>: The client sends a stream of requests to the server and receives a single response:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-protobuf codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-protobuf codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">service</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">MyService</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">rpc</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">UnaryExample</span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">stream</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">MyRequest</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">returns</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token class-name" style="color:#C586C0">MyResponse</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
</li>
<li>
<p><strong>Bidirectional Streaming RPC</strong>: Both the client and server send a stream of messages to each other, establishing a persistent connection:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-protobuf codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-protobuf codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">service</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">MyService</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">rpc</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">UnaryExample</span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">stream</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">MyRequest</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">returns</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">stream</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">MyResponse</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="grpc-vs-rest-basic-comparison">gRPC vs. REST: Basic Comparison<a href="https://tailcall.run/blog/what-is-grpc/#grpc-vs-rest-basic-comparison" class="hash-link" aria-label="Direct link to gRPC vs. REST: Basic Comparison" title="Direct link to gRPC vs. REST: Basic Comparison">​</a></h2>
<p><img decoding="async" loading="lazy" alt="payload size comparison" src="https://tailcall.run/assets/images/size-compare-ef1aa143ae128ea4e6b77d00b7fe5367.png" width="737" height="361" class="img_ev3q"></p>
<p><em>A comparison of payload sizes: REST JSON vs gRPC binary <a href="https://nilsmagnus.github.io/post/proto-json-sizes/" target="_blank" rel="noopener noreferrer">checkout full comparison </a></em></p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="communication-model">Communication model<a href="https://tailcall.run/blog/what-is-grpc/#communication-model" class="hash-link" aria-label="Direct link to Communication model" title="Direct link to Communication model">​</a></h3>
<ul>
<li><strong>gRPC:</strong> RPC-based, strong typing, and allows unary and bi-directional streaming, making it feasible for modern-day applications and use-cases.</li>
<li><strong>REST:</strong> Stateless, used for CRUD-based operations over HTTP, follows a simple unary request/response cycle.</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="data-format-and-serialization">Data format and serialization<a href="https://tailcall.run/blog/what-is-grpc/#data-format-and-serialization" class="hash-link" aria-label="Direct link to Data format and serialization" title="Direct link to Data format and serialization">​</a></h3>
<ul>
<li><strong>gRPC:</strong> Uses Protobuf for efficient binary serialization.</li>
<li><strong>REST:</strong> Uses a plain-text format like JSON and XML, which requires more processing in order to parse.</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="use-cases-for-each">Use cases for each<a href="https://tailcall.run/blog/what-is-grpc/#use-cases-for-each" class="hash-link" aria-label="Direct link to Use cases for each" title="Direct link to Use cases for each">​</a></h3>
<ul>
<li><strong>gRPC:</strong> Suitable for internal microservices, real-time applications, and situations needing high-performance and time-sensitive communication.</li>
<li><strong>REST:</strong> Better for public APIs, browser-based applications, and situations requiring stateless operations where ease of use is a priority.</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="advantages-of-grpc">Advantages of gRPC<a href="https://tailcall.run/blog/what-is-grpc/#advantages-of-grpc" class="hash-link" aria-label="Direct link to Advantages of gRPC" title="Direct link to Advantages of gRPC">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="efficiency-and-performance">Efficiency and performance<a href="https://tailcall.run/blog/what-is-grpc/#efficiency-and-performance" class="hash-link" aria-label="Direct link to Efficiency and performance" title="Direct link to Efficiency and performance">​</a></h3>
<p><img decoding="async" loading="lazy" alt="gRPC performance" src="https://tailcall.run/assets/images/grpc_performance-98f1ea4a03ee239664393b319ecea42f.webp" width="1500" height="750" class="img_ev3q"></p>
<p>Protobuf efficiently serializes messages on both the server and client sides, ensuring that data is transmitted in a compact binary format. This results in smaller message payloads, which are quicker to transmit over the network compared to the verbose JSON format used in REST APIs.</p>
<p>In addition, HTTP/2 uses features like header-compression, multiplexing and server-push which significantly reduce the payload size, as well as make response faster.</p>
<p>These features collectively contribute to significant performance gains, making gRPC <a href="https://medium.com/@EmperorRXF/evaluating-performance-of-rest-vs-grpc-1b8bdf0b22da" target="_blank" rel="noopener noreferrer">7-10 times</a> faster than traditional REST APIs using JSON.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="language-agnostic-nature">Language-agnostic nature<a href="https://tailcall.run/blog/what-is-grpc/#language-agnostic-nature" class="hash-link" aria-label="Direct link to Language-agnostic nature" title="Direct link to Language-agnostic nature">​</a></h3>
<p><img decoding="async" loading="lazy" alt="gRPC Language Agnostic" src="https://tailcall.run/assets/images/language_agnostic-8f1a65cf33ea3c4cf7e3b1fa9fa9839d.png" width="917" height="581" class="img_ev3q"></p>
<p>gRPC uses Protocol Buffers (Protobuf) as its (IDL) for describing both the structure and the semantics of the messages sent between clients and servers. Protobuf is independent of programming languages, meaning you can define your API once using Protobuf and then generate code in various languages to interact with it. This allows seamless integration of sub-systems API specification, while also enhancing the DX.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="strong-typing-and-code-generation">Strong typing and code generation<a href="https://tailcall.run/blog/what-is-grpc/#strong-typing-and-code-generation" class="hash-link" aria-label="Direct link to Strong typing and code generation" title="Direct link to Strong typing and code generation">​</a></h3>
<p>Protocol Buffers (Protobuf) defines both the structure and the types of messages exchanged between clients and servers within a .proto file, thereby establishing a clear and standardized API contract. This contract specifies the fields and their data types for each message, ensuring consistency and predictability in communication. By enforcing strong typing, Protobuf enhances code reliability by detecting type-related errors during compilation rather than at runtime. This approach not only prevents type mismatches and potential bugs but also saves developers time that would otherwise be spent implementing manual type-checking. Additionally, Protobuf's built-in type safety simplifies the development process, allowing developers to focus more on business logic and less on handling data integrity issues, thus improving the developer experience.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="bidirectional-streaming-capabilities">Bidirectional streaming capabilities<a href="https://tailcall.run/blog/what-is-grpc/#bidirectional-streaming-capabilities" class="hash-link" aria-label="Direct link to Bidirectional streaming capabilities" title="Direct link to Bidirectional streaming capabilities">​</a></h3>
<p>Unlike traditional RPC methods that are unidirectional (either client-to-server or server-to-client), gRPC's bidirectional streaming allows both parties to establish a persistent connection and send a sequence of messages asynchronously.</p>
<p>Bidirectional streaming is particularly beneficial for applications requiring interactive and responsive communication, such as chat systems, collaborative tools, multiplayer games, and real-time data feeds.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="extensibility-and-backward-compatibility">Extensibility and backward compatibility<a href="https://tailcall.run/blog/what-is-grpc/#extensibility-and-backward-compatibility" class="hash-link" aria-label="Direct link to Extensibility and backward compatibility" title="Direct link to Extensibility and backward compatibility">​</a></h3>
<p>gRPC using Protobuf as the IDL opens support for extensibility by allowing new fields, messages, and services to be added to the <code>.proto</code> file definitions. As services evolve, these changes can be propagated through automated code generation using the <code>protoc</code> compiler, which produces language-specific stubs and serializers/deserializers.</p>
<p>Moreover, explicit versioning and API contracts defined in the <code>.proto</code> files help manage compatibility between different versions of services. During the RPC connection handshake, gRPC allows clients and servers to negotiate capabilities, ensuring that both parties can communicate effectively even if they support different versions or extensions.</p>
<p><strong><em>Example:</em></strong></p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-protobuf codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-protobuf codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">syntax</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"proto3"</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">package</span><span class="token plain"> greet</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">v1</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">service</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Greeter</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">rpc</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">SayHello</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token class-name" style="color:#C586C0">HelloRequest</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">returns</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token class-name" style="color:#C586C0">HelloReply</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">message</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">HelloRequest</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token builtin">string</span><span class="token plain"> name </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">1</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">message</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">HelloReply</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token builtin">string</span><span class="token plain"> message </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token number" style="color:#C586C0">1</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="challenges-and-considerations">Challenges and Considerations<a href="https://tailcall.run/blog/what-is-grpc/#challenges-and-considerations" class="hash-link" aria-label="Direct link to Challenges and Considerations" title="Direct link to Challenges and Considerations">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="learning-curve">Learning curve<a href="https://tailcall.run/blog/what-is-grpc/#learning-curve" class="hash-link" aria-label="Direct link to Learning curve" title="Direct link to Learning curve">​</a></h3>
<p>gRPC has a much steeper learning curve compared to the traditional REST, mainly due to some new concepts like HTTP/2 and Protobuf which require significant practice and experience.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="debugging-complexity">Debugging complexity<a href="https://tailcall.run/blog/what-is-grpc/#debugging-complexity" class="hash-link" aria-label="Direct link to Debugging complexity" title="Direct link to Debugging complexity">​</a></h3>
<p>Debugging gRPC applications can be really challenging compared to traditional REST APIs. The binary nature of Protobuf messages makes it difficult to inspect and manipulate payloads directly. Tools for debugging and tracing gRPC calls are available, but they often require additional setup and expertise.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="ecosystem-maturity">Ecosystem maturity<a href="https://tailcall.run/blog/what-is-grpc/#ecosystem-maturity" class="hash-link" aria-label="Direct link to Ecosystem maturity" title="Direct link to Ecosystem maturity">​</a></h3>
<p>While gRPC has gained significant traction and support, its ecosystem is still maturing compared to REST. Some languages and frameworks may have limited or incomplete support for gRPC features. Additionally, there is less developer support on the internet, less browser-support and very few articles published which makes it challenging to learn especially for beginners.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="browser-support-limitations">Browser support limitations<a href="https://tailcall.run/blog/what-is-grpc/#browser-support-limitations" class="hash-link" aria-label="Direct link to Browser support limitations" title="Direct link to Browser support limitations">​</a></h3>
<p>Current browser limitations prevent direct implementation of the HTTP/2 gRPC specification. Browsers lack the necessary APIs to provide fine-grained control over requests. For instance:</p>
<ol>
<li>There's no way to enforce the use of HTTP/2.</li>
<li>Even if HTTP/2 could be enforced, browsers can't access raw HTTP/2 frames.</li>
</ol>
<p>To address these limitations, the gRPC-Web specification was developed. It builds upon the HTTP/2 spec but introduces key differences:</p>
<ol>
<li>Support for both HTTP/1.1 and HTTP/2 protocols.</li>
<li>A new method for handling gRPC trailers:<!-- -->
<ul>
<li>Trailers are sent at the very end of request/response bodies.</li>
<li>A new bit in the gRPC message header indicates the presence of trailers.</li>
</ul>
</li>
<li>Requirement of a proxy server:<!-- -->
<ul>
<li>This proxy translates between gRPC-Web requests and standard gRPC HTTP/2 responses.</li>
<li>It's a mandatory component in the gRPC-Web architecture.</li>
</ul>
</li>
</ol>
<p>These adaptations allow gRPC-like functionality in web browsers while working within current browser constraints.</p>
<p>gRPC is powerful for service to service communication, but it may not be the best choice for public APIs or browser-based applications where REST/GraphQL is more prevalent.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</div><div class="admonitionContent_BuS1"><p>To seamlessly integrate the benefits of both gRPC and GraphQL, you can easily generate GraphQL from gRPC using Tailcall. Check out the documentation here:</p><ul>
<li><a href="https://tailcall.run/docs/graphql-grpc-tailcall/" target="_blank" rel="noopener noreferrer">gRPC to GraphQL</a> .</li>
<li><a href="https://tailcall.run/docs/graphql-configuration-generation-with-tailcall/#effortless-grpc-integration" target="_blank" rel="noopener noreferrer">Automated gRPC to GraphQL</a></li>
</ul></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="implementing-grpc-best-practices">Implementing gRPC: Best Practices<a href="https://tailcall.run/blog/what-is-grpc/#implementing-grpc-best-practices" class="hash-link" aria-label="Direct link to Implementing gRPC: Best Practices" title="Direct link to Implementing gRPC: Best Practices">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="designing-effective-protobuf-schemas">Designing Effective Protobuf Schemas<a href="https://tailcall.run/blog/what-is-grpc/#designing-effective-protobuf-schemas" class="hash-link" aria-label="Direct link to Designing Effective Protobuf Schemas" title="Direct link to Designing Effective Protobuf Schemas">​</a></h3>
<p>Creating efficient and maintainable Protobuf schemas is crucial. Use meaningful field names and provide clear comments for each field, otherwise you may end up in a nested jargon of types! Versioning schemas properly ensures backward and forward compatibility makes it easier to evolve your API without breaking existing clients.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="error-handling-and-status-codes">Error Handling and Status Codes<a href="https://tailcall.run/blog/what-is-grpc/#error-handling-and-status-codes" class="hash-link" aria-label="Direct link to Error Handling and Status Codes" title="Direct link to Error Handling and Status Codes">​</a></h3>
<p>Define and document all possible error codes your service can return. Consistent and informative error messages aid in debugging and provide a better experience for developers integrating with your API, if the API is not verbose about the error, the developer trying to integrate the API on the other side may get frustrated:</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_BuS1"><p><strong><em>A bad API is like a traffic jam - frustrating, confusing, and costly.</em></strong>
<a href="https://www.twitter.com/joshbloch" target="_blank" rel="noopener noreferrer"> - Joshua Bloch</a></p></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="security-considerations-authentication-encryption">Security Considerations (Authentication, Encryption)<a href="https://tailcall.run/blog/what-is-grpc/#security-considerations-authentication-encryption" class="hash-link" aria-label="Direct link to Security Considerations (Authentication, Encryption)" title="Direct link to Security Considerations (Authentication, Encryption)">​</a></h3>
<p>Secure your gRPC services by implementing authentication and encryption. Use Transport Layer Security (TLS) to encrypt communication between clients and servers. Leverage gRPC's support for various authentication mechanisms, such as OAuth, JWT, or custom tokens, to ensure that only authorized clients can access your services.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="performance-optimization-techniques">Performance Optimization Techniques<a href="https://tailcall.run/blog/what-is-grpc/#performance-optimization-techniques" class="hash-link" aria-label="Direct link to Performance Optimization Techniques" title="Direct link to Performance Optimization Techniques">​</a></h3>
<p>gRPC API performance can be boosted in many ways. The channels are expensive to make, and reusing them instead of remaking has a significant impact.</p>
<p><strong><em>Example:</em></strong></p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> grpc </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">require</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">"grpc"</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token comment" style="color:#30C26D;font-style:italic">// Singleton instance for the gRPC channel</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">let</span><span class="token plain"> channel </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword null nil" style="color:#C586C0">null</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">function</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">getGrpcChannel</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#C586C0">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain">channel</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token comment" style="color:#30C26D;font-style:italic">// Create a new channel if it doesn't exist</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    channel </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">new</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">grpc</span><span class="token class-name punctuation" style="color:#fff">.</span><span class="token class-name" style="color:#C586C0">Client</span><span class="token punctuation" style="color:#fff">(</span><span class="token string" style="color:#FDB869">"localhost:50051"</span><span class="token punctuation" style="color:#fff">,</span><span class="token plain"> grpc</span><span class="token punctuation" style="color:#fff">.</span><span class="token property-access">credentials</span><span class="token punctuation" style="color:#fff">.</span><span class="token method function property-access" style="color:#FDEA2F">createInsecure</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#C586C0">return</span><span class="token plain"> channel</span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token comment" style="color:#30C26D;font-style:italic">// Example usage:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">const</span><span class="token plain"> myChannel </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">getGrpcChannel</span><span class="token punctuation" style="color:#fff">(</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token comment" style="color:#30C26D;font-style:italic">// Use `myChannel` to make gRPC calls</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Alongside with reusing channels, many other ways can improve performance like implementing <a href="https://grpc.io/blog/grpc-load-balancing/" target="_blank" rel="noopener noreferrer">load-balancers</a> and using streaming instead of unary where needed.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="grpc-use-cases-and-real-world-examples">gRPC Use Cases and Real-World Examples<a href="https://tailcall.run/blog/what-is-grpc/#grpc-use-cases-and-real-world-examples" class="hash-link" aria-label="Direct link to gRPC Use Cases and Real-World Examples" title="Direct link to gRPC Use Cases and Real-World Examples">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="microservices-architecture">Microservices Architecture<a href="https://tailcall.run/blog/what-is-grpc/#microservices-architecture" class="hash-link" aria-label="Direct link to Microservices Architecture" title="Direct link to Microservices Architecture">​</a></h3>
<p>gRPC is well-suited for microservices architectures, enabling efficient communication between services. Companies like Netflix and Google use gRPC to connect their microservices, benefiting from its performance and strong typing. It ensures reliable, low-latency communication, which is crucial for maintaining responsive and scalable microservices.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="real-time-communication-systems">Real-Time Communication Systems<a href="https://tailcall.run/blog/what-is-grpc/#real-time-communication-systems" class="hash-link" aria-label="Direct link to Real-Time Communication Systems" title="Direct link to Real-Time Communication Systems">​</a></h3>
<p><img decoding="async" loading="lazy" alt="enter image description here" src="https://tailcall.run/assets/images/realtime-375fd2cf1837a0ae1de8cd74fbd240cd.png" width="802" height="503" class="img_ev3q"></p>
<p>gRPC is ideal for real-time communication systems such as chat applications, online gaming, and live streaming services. Its support for bidirectional streaming allows for seamless and efficient data exchange between clients and servers, enabling real-time interactions and reducing latency.</p>
<p><a href="https://github.com/googleforgames/open-match/blob/d781be1a3ce1b6b7fce495345b23256089f55de9/api/backend.proto#L132" target="_blank" rel="noopener noreferrer">A snippet from Open-Match, a gaming framework:</a></p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-protobuf codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-protobuf codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic">// Tickets in matches returned by FetchMatches are moved from active to</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic">// pending, and will not be returned by query.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token keyword" style="color:#C586C0">rpc</span><span class="token plain"> </span><span class="token function" style="color:#FDEA2F">FetchMatches</span><span class="token punctuation" style="color:#fff">(</span><span class="token class-name" style="color:#C586C0">FetchMatchesRequest</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">returns</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token keyword" style="color:#C586C0">stream</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">FetchMatchesResponse</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token keyword" style="color:#C586C0">option</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">(</span><span class="token plain">google</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">api</span><span class="token punctuation" style="color:#fff">.</span><span class="token plain">http</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      post</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"/v1/backendservice/matches:fetch"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      body</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token string" style="color:#FDB869">"*"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token punctuation" style="color:#fff">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="iot-and-edge-computing">IoT and Edge Computing<a href="https://tailcall.run/blog/what-is-grpc/#iot-and-edge-computing" class="hash-link" aria-label="Direct link to IoT and Edge Computing" title="Direct link to IoT and Edge Computing">​</a></h3>
<p>In IoT and edge computing scenarios, gRPC's low overhead and efficient communication make it suitable for resource-constrained devices. It enables reliable communication between edge devices and central servers, facilitating data collection, processing, and command execution in real time.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="mobile-and-web-applications">Mobile and Web Applications<a href="https://tailcall.run/blog/what-is-grpc/#mobile-and-web-applications" class="hash-link" aria-label="Direct link to Mobile and Web Applications" title="Direct link to Mobile and Web Applications">​</a></h3>
<p>gRPC is increasingly used in mobile and web applications to improve performance and reduce bandwidth usage. For example, companies like Lyft use gRPC to enhance the efficiency of their mobile apps, ensuring faster response times and a smoother user experience.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="tools-and-frameworks-for-grpc-development">Tools and Frameworks for gRPC Development<a href="https://tailcall.run/blog/what-is-grpc/#tools-and-frameworks-for-grpc-development" class="hash-link" aria-label="Direct link to Tools and Frameworks for gRPC Development" title="Direct link to Tools and Frameworks for gRPC Development">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="popular-grpc-libraries-for-different-languages">Popular gRPC Libraries for Different Languages<a href="https://tailcall.run/blog/what-is-grpc/#popular-grpc-libraries-for-different-languages" class="hash-link" aria-label="Direct link to Popular gRPC Libraries for Different Languages" title="Direct link to Popular gRPC Libraries for Different Languages">​</a></h3>
<p>gRPC has libraries and tooling support for various programming languages:</p>
<ul>
<li><a href="https://github.com/grpc/grpc" target="_blank" rel="noopener noreferrer">gRPC Core</a> - C, C++, Ruby, Node.js, Python, PHP, C#, Objective-C</li>
<li><a href="https://github.com/grpc/grpc-java" target="_blank" rel="noopener noreferrer">gRPC Java</a> - The Java gRPC implementation. HTTP/2 based RPC</li>
<li><a href="https://github.com/grpc/grpc-node" target="_blank" rel="noopener noreferrer">gRPC Node.js</a> - gRPC for Node.js</li>
<li><a href="https://github.com/grpc/grpc-go" target="_blank" rel="noopener noreferrer">gRPC Go</a> - The Go language implementation of gRPC. HTTP/2 based RPC</li>
<li><a href="https://github.com/grpc/grpc-dotnet" target="_blank" rel="noopener noreferrer">gRPC C#</a> - The C# language implementation of gRPC</li>
<li><a href="https://github.com/grpc/grpc-web" target="_blank" rel="noopener noreferrer">gRPC Web</a> - gRPC for Web Clients</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="testing-and-debugging-tools">Testing and Debugging Tools<a href="https://tailcall.run/blog/what-is-grpc/#testing-and-debugging-tools" class="hash-link" aria-label="Direct link to Testing and Debugging Tools" title="Direct link to Testing and Debugging Tools">​</a></h3>
<ul>
<li><a href="https://github.com/bojand/ghz" target="_blank" rel="noopener noreferrer">ghz</a></li>
<li><a href="https://github.com/phiSgr/gatling-grpc" target="_blank" rel="noopener noreferrer">gatling-grpc</a></li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="api-management-platforms">API Management Platforms<a href="https://tailcall.run/blog/what-is-grpc/#api-management-platforms" class="hash-link" aria-label="Direct link to API Management Platforms" title="Direct link to API Management Platforms">​</a></h3>
<ul>
<li><a href="https://postman.com/" target="_blank" rel="noopener noreferrer">Postman</a></li>
<li><a href="https://github.com/gogo/letmegrpc" target="_blank" rel="noopener noreferrer">letmegrpc</a></li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="future-of-grpc-and-api-communication">Future of gRPC and API Communication<a href="https://tailcall.run/blog/what-is-grpc/#future-of-grpc-and-api-communication" class="hash-link" aria-label="Direct link to Future of gRPC and API Communication" title="Direct link to Future of gRPC and API Communication">​</a></h2>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="emerging-trends-in-api-design">Emerging Trends in API Design<a href="https://tailcall.run/blog/what-is-grpc/#emerging-trends-in-api-design" class="hash-link" aria-label="Direct link to Emerging Trends in API Design" title="Direct link to Emerging Trends in API Design">​</a></h3>
<p>The future of API design is moving towards more efficient and flexible communication protocols like gRPC. With the rise of microservices, IoT, and real-time applications, gRPC's performance advantages make it a compelling choice. Trends like GraphQL and RESTful JSON APIs will continue to coexist, but gRPC will gain traction for specific use cases requiring high efficiency and low latency.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="grpcs-role-in-cloud-native-applications">gRPC's Role in Cloud-Native Applications<a href="https://tailcall.run/blog/what-is-grpc/#grpcs-role-in-cloud-native-applications" class="hash-link" aria-label="Direct link to gRPC's Role in Cloud-Native Applications" title="Direct link to gRPC's Role in Cloud-Native Applications">​</a></h3>
<p>gRPC is becoming a cornerstone of cloud-native applications, facilitating communication in containerized environments orchestrated by platforms like Kubernetes. Its ability to handle high-performance, low-latency communication is essential for the scalability and reliability of cloud-native architectures.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="potential-improvements-and-extensions">Potential Improvements and Extensions<a href="https://tailcall.run/blog/what-is-grpc/#potential-improvements-and-extensions" class="hash-link" aria-label="Direct link to Potential Improvements and Extensions" title="Direct link to Potential Improvements and Extensions">​</a></h3>
<p>The gRPC ecosystem is continuously evolving, with potential improvements and extensions on the horizon. Enhancements in tooling, support for more languages, better integration with existing frameworks, and increased adoption of gRPC-Web are some areas of expected growth. The community's efforts to address current limitations will make gRPC more accessible and robust for a wider range of applications.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion">Conclusion<a href="https://tailcall.run/blog/what-is-grpc/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="recap-of-grpcs-key-features-and-benefits">Recap of gRPC's key features and benefits<a href="https://tailcall.run/blog/what-is-grpc/#recap-of-grpcs-key-features-and-benefits" class="hash-link" aria-label="Direct link to Recap of gRPC's key features and benefits" title="Direct link to Recap of gRPC's key features and benefits">​</a></h4>
<p>In summary, gRPC offers efficient, low-latency communication, strong typing through Protobuf, and support for multiple languages. Its bidirectional streaming and multiplexing capabilities make it ideal for real-time and microservices-based applications. The performance and reliability of gRPC provide significant advantages over traditional REST APIs in many scenarios, mainly because of the new HTTP/2 and its binary nature.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="considerations-for-adopting-grpc-in-projects">Considerations for Adopting gRPC in Projects<a href="https://tailcall.run/blog/what-is-grpc/#considerations-for-adopting-grpc-in-projects" class="hash-link" aria-label="Direct link to Considerations for Adopting gRPC in Projects" title="Direct link to Considerations for Adopting gRPC in Projects">​</a></h4>
<p>When considering gRPC for your projects, ensure that your team is prepared to handle the challenges and leverage the best practices discussed to design, implement, and maintain robust gRPC services. Make sure you have enough support resources and officials, as gRPC doesn't have a community as large as REST.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="further-resources">Further Resources<a href="https://tailcall.run/blog/what-is-grpc/#further-resources" class="hash-link" aria-label="Direct link to Further Resources" title="Direct link to Further Resources">​</a></h3>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="official-documentation-and-tutorials">Official documentation and tutorials<a href="https://tailcall.run/blog/what-is-grpc/#official-documentation-and-tutorials" class="hash-link" aria-label="Direct link to Official documentation and tutorials" title="Direct link to Official documentation and tutorials">​</a></h4>
<ul>
<li><a href="https://grpc.io/" target="_blank" rel="noopener noreferrer">gRPC Official Documentation</a></li>
</ul>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="community-forums-and-support">Community forums and support<a href="https://tailcall.run/blog/what-is-grpc/#community-forums-and-support" class="hash-link" aria-label="Direct link to Community forums and support" title="Direct link to Community forums and support">​</a></h4>
<ul>
<li><a href="https://twitter.com/grpcio" target="_blank" rel="noopener noreferrer">gRPC Twitter handle</a></li>
<li><a href="https://stackoverflow.com/questions/tagged/grpc" target="_blank" rel="noopener noreferrer">gRPC StackOverflow tag</a></li>
<li><a href="https://app.gitter.im/#/room/#grpc_grpc:gitter.im" target="_blank" rel="noopener noreferrer">gRPC Gitter room</a></li>
<li><a href="https://groups.google.com/g/grpc-io" target="_blank" rel="noopener noreferrer">gRPC Google Group</a></li>
</ul>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="books-for-in-depth-learning">Books for in-depth learning<a href="https://tailcall.run/blog/what-is-grpc/#books-for-in-depth-learning" class="hash-link" aria-label="Direct link to Books for in-depth learning" title="Direct link to Books for in-depth learning">​</a></h4>
<ul>
<li><a href="https://www.oreilly.com/library/view/grpc-up-and/9781492058328/" target="_blank" rel="noopener noreferrer">gRPC: Up and Running</a></li>
<li><a href="https://www.manning.com/books/grpc-microservices-in-go" target="_blank" rel="noopener noreferrer">gRPC Microservices in Go</a></li>
</ul>]]></content:encoded>
            <category>microservices</category>
            <category>gRPC</category>
            <category>API</category>
        </item>
        <item>
            <title><![CDATA[Are Hackers Using Your Own GraphQL API Against You?]]></title>
            <link>https://tailcall.run/blog/graphql-introspection-security/</link>
            <guid>https://tailcall.run/blog/graphql-introspection-security/</guid>
            <pubDate>Fri, 12 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn how attackers exploit GraphQL introspection and the battle-tested strategies to keep your data safe.]]></description>
            <content:encoded><![CDATA[<p>GraphQL has taken the API world by storm, offering developers a flexible and powerful way to interact with backend systems. But with great power comes great responsibility—especially when it comes to security.</p>
<p>Let's dive into one of GraphQL's most fascinating features: introspection. It's a double-edged sword that can be both a developer's best friend and a security expert's nightmare.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="understanding-graphql-introspection">Understanding GraphQL Introspection<a href="https://tailcall.run/blog/graphql-introspection-security/#understanding-graphql-introspection" class="hash-link" aria-label="Direct link to Understanding GraphQL Introspection" title="Direct link to Understanding GraphQL Introspection">​</a></h2>
<p>Imagine having a magical lens that lets you peek into the very structure of a GraphQL server. That's essentially what introspection does! It's like having a detailed map of a treasure trove, showing you every nook and cranny of the API's capabilities. This self-documenting capability is incredibly useful for developers, enabling tools like GraphiQL and GraphQL Playground to provide rich, interactive documentation and auto-completion features.</p>
<p>A basic introspection query might look like this:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token object">__schema</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token object">types</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token object">fields</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">          </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">        </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">      </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This query asks the server to return information about all the types in the schema, including their fields and field types. The server's response provides a comprehensive map of its structure, which can be invaluable during development.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-security-implications-of-introspection">The Security Implications of Introspection<a href="https://tailcall.run/blog/graphql-introspection-security/#the-security-implications-of-introspection" class="hash-link" aria-label="Direct link to The Security Implications of Introspection" title="Direct link to The Security Implications of Introspection">​</a></h2>
<p>While introspection is a goldmine for developers, it can also be a treasure map for attackers. Let's put on our black hat for a moment and see how a malicious actor might exploit this feature.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="schema-reconnaissance">Schema Reconnaissance<a href="https://tailcall.run/blog/graphql-introspection-security/#schema-reconnaissance" class="hash-link" aria-label="Direct link to Schema Reconnaissance" title="Direct link to Schema Reconnaissance">​</a></h3>
<p>One of the primary risks of introspection is schema reconnaissance. An attacker who gains access to a GraphQL endpoint can use introspection to explore the schema and identify potential targets for further attacks. This includes discovering sensitive types and fields, as well as understanding the relationships between different parts of the schema. Armed with this knowledge, an attacker can craft more effective queries to exploit vulnerabilities in the system.</p>
<p>For instance, an attacker might discover a 'User' type with fields like 'email', 'password', and 'isAdmin'. They could then craft a query to exploit this:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token object">allUsers</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">email</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">password</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">isAdmin</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>If not properly secured, this query could potentially expose sensitive user data. The attacker might also notice an 'updateUser' mutation, which could be a target for privilege escalation attempts.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="information-disclosure">Information Disclosure<a href="https://tailcall.run/blog/graphql-introspection-security/#information-disclosure" class="hash-link" aria-label="Direct link to Information Disclosure" title="Direct link to Information Disclosure">​</a></h3>
<p>Another significant risk is information disclosure. The introspection feature can inadvertently reveal implementation details that should remain hidden. This includes internal types, deprecated fields, and administrative functionalities. Such exposure can give attackers clues about the underlying system architecture and any potential weaknesses.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="attack-surface-expansion">Attack Surface Expansion<a href="https://tailcall.run/blog/graphql-introspection-security/#attack-surface-expansion" class="hash-link" aria-label="Direct link to Attack Surface Expansion" title="Direct link to Attack Surface Expansion">​</a></h3>
<p>By using introspection, attackers can significantly expand their attack surface. They can identify entry points for various attacks, including SQL injection, cross-site scripting (XSS), and denial of service (DoS) attacks. For instance, if introspection reveals that certain fields accept user input, an attacker might probe these fields for injection vulnerabilities.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="mitigating-introspection-risks">Mitigating Introspection Risks<a href="https://tailcall.run/blog/graphql-introspection-security/#mitigating-introspection-risks" class="hash-link" aria-label="Direct link to Mitigating Introspection Risks" title="Direct link to Mitigating Introspection Risks">​</a></h2>
<p>Now, let's switch gears and become the defenders of our GraphQL realm. Here are some battle-tested strategies to keep your API safe from prying eyes:</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="disable-introspection-in-production">Disable Introspection in Production<a href="https://tailcall.run/blog/graphql-introspection-security/#disable-introspection-in-production" class="hash-link" aria-label="Direct link to Disable Introspection in Production" title="Direct link to Disable Introspection in Production">​</a></h3>
<p>Disabling introspection in production is crucial because it significantly reduces the information available to potential attackers. Without introspection, they can't easily map out your API's structure or discover hidden fields and types. This forces attackers to rely on guesswork or prior knowledge, making their job much more difficult. However, it's important to note that this is not a silver bullet—determined attackers may still attempt to reverse-engineer your API through trial and error.</p>
<p>In many GraphQL implementations, disabling introspection is straightforward. For example, in <a href="https://tailcall.run/docs/server-directive/#introspection" target="_blank" rel="noopener noreferrer">Tailcall</a>, you can disable introspection by setting the <code>introspection</code> option to <code>false</code>:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">schema</span><span class="token plain"></span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#fff"><span class="token plain">  </span><span class="token directive function" style="color:#FDEA2F">@server</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">introspection</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token boolean" style="color:#C586C0">false</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">query</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Query</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">mutation</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Mutation</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This configuration ensures that introspection is disabled.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="implement-authentication-and-authorization">Implement Authentication and Authorization<a href="https://tailcall.run/blog/graphql-introspection-security/#implement-authentication-and-authorization" class="hash-link" aria-label="Direct link to Implement Authentication and Authorization" title="Direct link to Implement Authentication and Authorization">​</a></h3>
<p>Another critical measure is to implement robust authentication and authorization mechanisms. By ensuring that only authenticated and authorized users can access your GraphQL endpoint, you can reduce the risk of unauthorized introspection queries. Use industry-standard authentication protocols such as OAuth2 or JWT to secure your endpoints.</p>
<p>Imagine a GraphQL API for a banking application. You might implement role-based access control where only users with an 'ADMIN' role can access certain fields or mutations.</p>
<p>In <a href="https://tailcall.run/docs/field-level-access-control-graphql-authentication/" target="_blank" rel="noopener noreferrer">Tailcall</a>, you can achieve this by using the <code>@protected</code> directive.</p>
<p>Tailcall supports a variety of authentication and authorization mechanisms, including JWT, OAuth2, and custom authentication strategies.</p>
<p>This ensures that even if an attacker gains access to a regular user account, they can't use it to access sensitive admin-only data or operations.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="rate-limiting-and-throttling">Rate Limiting and Throttling<a href="https://tailcall.run/blog/graphql-introspection-security/#rate-limiting-and-throttling" class="hash-link" aria-label="Direct link to Rate Limiting and Throttling" title="Direct link to Rate Limiting and Throttling">​</a></h3>
<p>Rate limiting and throttling can also help mitigate the risks of introspection. By limiting the number of queries a client can execute within a given timeframe, you can reduce the likelihood of an attacker using introspection to gather information about your schema. Implementing these controls can also help protect your server from DoS attacks.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="query-allow-lists">Query Allow Lists<a href="https://tailcall.run/blog/graphql-introspection-security/#query-allow-lists" class="hash-link" aria-label="Direct link to Query Allow Lists" title="Direct link to Query Allow Lists">​</a></h3>
<p>Query allow lists work by pre-registering all valid queries that your application needs. This is typically done during the build process of your frontend application. Each query is hashed, and these hashes are stored on the server. When a query comes in, its hash is checked against the allow list.</p>
<p>For example, you might have a client-side query like this:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">query</span><span class="token plain"> </span><span class="token definition-query function" style="color:#FDEA2F">GetUserProfile</span><span class="token punctuation" style="color:#fff">(</span><span class="token variable" style="color:#E36209">$id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token property-query">user</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token variable" style="color:#E36209">$id</span><span class="token punctuation" style="color:#fff">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token property" style="color:#C586C0">email</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This query would be hashed and stored on the server. When executed, the server checks if the incoming query's hash matches any in its allow list. If not, it's rejected.</p>
<p>This approach is powerful because it completely prevents arbitrary queries, including introspection queries, from being executed. It does require more setup and maintenance, especially in applications where queries change frequently, but it provides a very high level of security.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="monitor-and-log-introspection-queries">Monitor and Log Introspection Queries<a href="https://tailcall.run/blog/graphql-introspection-security/#monitor-and-log-introspection-queries" class="hash-link" aria-label="Direct link to Monitor and Log Introspection Queries" title="Direct link to Monitor and Log Introspection Queries">​</a></h3>
<p>Monitoring and logging introspection queries can provide valuable insights into potential security threats. By tracking when and how introspection queries are executed, you can identify suspicious activity and respond accordingly. Implement logging at both the application and network levels to capture detailed information about each query.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="use-a-web-application-firewall-waf">Use a Web Application Firewall (WAF)<a href="https://tailcall.run/blog/graphql-introspection-security/#use-a-web-application-firewall-waf" class="hash-link" aria-label="Direct link to Use a Web Application Firewall (WAF)" title="Direct link to Use a Web Application Firewall (WAF)">​</a></h3>
<p>A WAF can be particularly effective for GraphQL APIs because it can be configured to understand GraphQL-specific threats. For instance, you can set up rules to:</p>
<ol>
<li>Limit query depth: Prevent deeply nested queries that could overload your server.</li>
<li>Restrict field counts: Avoid overly broad queries that request too many fields at once.</li>
<li>Block known malicious patterns: Such as attempts to inject malicious code into queries.</li>
</ol>
<p>For example, a WAF rule might look like this:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token plain">SecRule ARGS_POST:query "@contains __schema" \</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    "id:1000,\</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    phase:2,\</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    t:none,\</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    block,\</span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    msg:'GraphQL introspection query detected'"</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This rule would block any POST request containing '__schema' in the query parameter, which is typically indicative of an introspection query.</p>
<p>By implementing these kinds of rules, a WAF adds an extra layer of protection, catching many potential attacks before they even reach your GraphQL server.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion">Conclusion<a href="https://tailcall.run/blog/graphql-introspection-security/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>Securing GraphQL is like playing a high-stakes game of chess. You need to think several moves ahead, anticipating potential threats while leveraging the strengths of your position. By implementing these strategies, you're not just protecting your API—you're ensuring that GraphQL's power remains in the right hands. Stay vigilant, keep learning, and may your queries be ever secure!</p>
<p>By prioritizing security in your GraphQL implementation, you can harness the power of this modern query language while safeguarding your data and maintaining the trust of your users. Securing GraphQL is an ongoing process that requires vigilance and a proactive approach. Stay informed about the latest security developments, regularly review and update your security measures, and ensure that your development and security teams are aligned in their efforts to protect your applications.</p>]]></content:encoded>
            <category>GraphQL</category>
            <category>Schema</category>
            <category>Security</category>
            <category>Introspection</category>
        </item>
        <item>
            <title><![CDATA[Design a GraphQL Schema So Good, It'll Make REST APIs Cry - Part 1]]></title>
            <link>https://tailcall.run/blog/graphql-schema/</link>
            <guid>https://tailcall.run/blog/graphql-schema/</guid>
            <pubDate>Thu, 11 Jul 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn how to design a robust, scalable GraphQL schema. Best practices and considerations to build a schema that can evolve with your application's needs.]]></description>
            <content:encoded><![CDATA[<p>Designing a robust, scalable GraphQL schema is critical for building production-ready APIs that can evolve with your application's needs. In this comprehensive guide, we'll walk through the process of crafting a GraphQL schema for a real-world application, highlighting best practices and considerations along the way.</p>
<p>If you are thinking how we could possibly cover all of the lovely intricacies associated with this topic in one go, you are right, we can't and so we are not! We have created an amazing series to take you through the nuances of working with GraphQL schemas.</p>
<p>Let's break our job into puzzle pieces. Let's start by simply creating designing a brand new schema!</p>
<div style="text-align:center;margin:16px"><img src="https://tailcall.run/images/blog/puzzle-graphql-schema-1.png" alt="puzzle piece to visualise the series" style="max-width:40%"></div>
<p>If you're new to GraphQL Schema, check out our <a href="https://tailcall.run/graphql/schemas-and-types/" target="_blank" rel="noopener noreferrer">GraphQL Schema Tutorial</a> to get up to speed with the basics.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-power-of-graphql-schemas">The Power of GraphQL Schemas<a href="https://tailcall.run/blog/graphql-schema/#the-power-of-graphql-schemas" class="hash-link" aria-label="Direct link to The Power of GraphQL Schemas" title="Direct link to The Power of GraphQL Schemas">​</a></h2>
<p>A well-designed GraphQL schema serves as the blueprint for your entire API. It defines:</p>
<ul>
<li>The types of data available</li>
<li>The relationships between those types</li>
<li>The operations clients can perform (queries, mutations, subscriptions)</li>
<li>The structure of requests and responses</li>
</ul>
<p>Your schema acts as a contract between your backend and frontend teams. Once published, clients can rely on its structure, enabling them to build UIs with confidence. A thoughtful schema design upfront can save significant refactoring down the road.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="our-example-application-techtalent">Our Example Application: TechTalent<a href="https://tailcall.run/blog/graphql-schema/#our-example-application-techtalent" class="hash-link" aria-label="Direct link to Our Example Application: TechTalent" title="Direct link to Our Example Application: TechTalent">​</a></h2>
<p>To illustrate schema design principles, let's imagine we're building TechTalent - a platform connecting tech companies with job seekers. Our application will allow:</p>
<ul>
<li>Companies to post job listings</li>
<li>Candidates to create profiles and apply to jobs</li>
<li>Recruiters to search candidates and manage applications</li>
</ul>
<p>We'll design our schema step-by-step to support these core features.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-1-identify-core-types">Step 1: Identify Core Types<a href="https://tailcall.run/blog/graphql-schema/#step-1-identify-core-types" class="hash-link" aria-label="Direct link to Step 1: Identify Core Types" title="Direct link to Step 1: Identify Core Types">​</a></h2>
<p>The first step is to identify the main entities in our domain. For TechTalent, our core types might include:</p>
<ul>
<li>Company</li>
<li>JobListing</li>
<li>Candidate</li>
<li>Application</li>
<li>Recruiter</li>
</ul>
<p>Let's start by defining these as object types in our schema:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Company</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">description</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic"># More fields to come</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">JobListing</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">title</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">description</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic"># More fields to come</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Candidate</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">email</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic"># More fields to come</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Application</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic"># More fields to come</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Recruiter</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">email</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic"># More fields to come</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Notice we've only included a few basic fields at this stage. We'll flesh these out as we progress.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-2-model-relationships">Step 2: Model Relationships<a href="https://tailcall.run/blog/graphql-schema/#step-2-model-relationships" class="hash-link" aria-label="Direct link to Step 2: Model Relationships" title="Direct link to Step 2: Model Relationships">​</a></h2>
<p>Next, we need to consider how these types relate to each other. In GraphQL, we model relationships by adding fields that reference other types. Let's update our types:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Company</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">description</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">jobListings</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">JobListing</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">]</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">recruiters</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">Recruiter</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">]</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">JobListing</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">title</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">description</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">company</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Company</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">applications</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">Application</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">]</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Candidate</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">email</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">applications</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">Application</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">]</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Application</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">jobListing</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">JobListing</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">candidate</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Candidate</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">status</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">ApplicationStatus</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Recruiter</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">email</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">company</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Company</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">enum</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">ApplicationStatus</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token constant" style="color:#C586C0">PENDING</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token constant" style="color:#C586C0">REVIEWED</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token constant" style="color:#C586C0">REJECTED</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token constant" style="color:#C586C0">ACCEPTED</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>We've now established the core relationships:</p>
<ul>
<li>Companies have job listings and recruiters</li>
<li>Job listings belong to a company and have applications</li>
<li>Candidates have applications</li>
<li>Applications link a candidate to a job listing</li>
<li>Recruiters belong to a company</li>
</ul>
<p>Note the use of the <code>ApplicationStatus</code> enum to represent the fixed set of possible statuses.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-3-plan-query-operations">Step 3: Plan Query Operations<a href="https://tailcall.run/blog/graphql-schema/#step-3-plan-query-operations" class="hash-link" aria-label="Direct link to Step 3: Plan Query Operations" title="Direct link to Step 3: Plan Query Operations">​</a></h2>
<p>With our core types defined, let's consider what query operations our clients will need. We'll start with some basic CRUD (Create, Read, Update, Delete) operations:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">company</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Company</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">jobListing</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">JobListing</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">candidate</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Candidate</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic"># List operations</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">companies</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">Company</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">]</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">jobListings</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">filters</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">JobListingFilters</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">JobListing</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">]</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">candidates</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">filters</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">CandidateFilters</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">Candidate</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">]</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">input</span><span class="token plain"> </span><span class="token object">JobListingFilters</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">companyId</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">title</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic"># Add more filter options</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">input</span><span class="token plain"> </span><span class="token object">CandidateFilters</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">skills</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">experienceYears</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic"># Add more filter options</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>We've added basic queries to fetch individual entities by ID, as well as list queries for our main types. Notice the use of <code>input</code> types for filters - this allows for more flexible and extensible querying.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-4-plan-mutation-operations">Step 4: Plan Mutation Operations<a href="https://tailcall.run/blog/graphql-schema/#step-4-plan-mutation-operations" class="hash-link" aria-label="Direct link to Step 4: Plan Mutation Operations" title="Direct link to Step 4: Plan Mutation Operations">​</a></h2>
<p>Next, let's define some mutation operations to allow clients to modify data:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Mutation</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic"># Company mutations</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">createCompany</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">input</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token atom-input class-name" style="color:#C586C0">CreateCompanyInput</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">CreateCompanyPayload</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">updateCompany</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">input</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token atom-input class-name" style="color:#C586C0">UpdateCompanyInput</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">UpdateCompanyPayload</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic"># Job Listing mutations</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">createJobListing</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">input</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token atom-input class-name" style="color:#C586C0">CreateJobListingInput</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">CreateJobListingPayload</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">updateJobListing</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">input</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token atom-input class-name" style="color:#C586C0">UpdateJobListingInput</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">UpdateJobListingPayload</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic"># Candidate mutations</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">createCandidate</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">input</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token atom-input class-name" style="color:#C586C0">CreateCandidateInput</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">CreateCandidatePayload</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">updateCandidate</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">input</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token atom-input class-name" style="color:#C586C0">UpdateCandidateInput</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">UpdateCandidatePayload</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic"># Application mutations</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">submitApplication</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">input</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token atom-input class-name" style="color:#C586C0">SubmitApplicationInput</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">SubmitApplicationPayload</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">updateApplicationStatus</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">status</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">ApplicationStatus</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">UpdateApplicationStatusPayload</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token comment" style="color:#30C26D;font-style:italic"># Input and Payload types for each mutation...</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Notice the pattern we're using for mutations:</p>
<ol>
<li>Each mutation has a corresponding input type</li>
<li>Each mutation returns a payload type</li>
</ol>
<p>This structure offers several benefits:</p>
<ul>
<li>Input types allow for easy addition of new fields in the future</li>
<li>Payload types can include both the modified entity and any errors or metadata</li>
<li>It provides a consistent structure across all mutations</li>
</ul>
<p>Let's look at an example input and payload type:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">input</span><span class="token plain"> </span><span class="token atom-input class-name" style="color:#C586C0">CreateJobListingInput</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">companyId</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">title</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">description</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">requirements</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">]</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">salary</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token atom-input class-name" style="color:#C586C0">SalaryInput</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">input</span><span class="token plain"> </span><span class="token atom-input class-name" style="color:#C586C0">SalaryInput</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">min</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">max</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">currency</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">CreateJobListingPayload</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">jobListing</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">JobListing</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">errors</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">Error</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Error</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">message</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">path</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This structure allows for detailed error reporting and future extensibility.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-5-consider-authentication-and-authorization">Step 5: Consider Authentication and Authorization<a href="https://tailcall.run/blog/graphql-schema/#step-5-consider-authentication-and-authorization" class="hash-link" aria-label="Direct link to Step 5: Consider Authentication and Authorization" title="Direct link to Step 5: Consider Authentication and Authorization">​</a></h2>
<p>In a production application, we need to consider authentication and authorization. Let's add some operations for user management:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Mutation</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic"># ... previous mutations</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">signup</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">input</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token atom-input class-name" style="color:#C586C0">SignupInput</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">AuthPayload</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">login</span><span class="token punctuation" style="color:#fff">(</span><span class="token attr-name" style="color:#8DFFF8">input</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token atom-input class-name" style="color:#C586C0">LoginInput</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">AuthPayload</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">logout</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Boolean</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">input</span><span class="token plain"> </span><span class="token atom-input class-name" style="color:#C586C0">SignupInput</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">email</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">password</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">role</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">UserRole</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">input</span><span class="token plain"> </span><span class="token atom-input class-name" style="color:#C586C0">LoginInput</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">email</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">password</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">AuthPayload</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">token</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">user</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">User</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">email</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">role</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">UserRole</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">enum</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">UserRole</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token constant" style="color:#C586C0">CANDIDATE</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token constant" style="color:#C586C0">RECRUITER</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token constant" style="color:#C586C0">ADMIN</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>We've added basic authentication operations and a <code>User</code> type to represent authenticated users. In a real-world scenario, you'd likely want to implement more robust authentication and authorization mechanisms.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-6-implement-pagination">Step 6: Implement Pagination<a href="https://tailcall.run/blog/graphql-schema/#step-6-implement-pagination" class="hash-link" aria-label="Direct link to Step 6: Implement Pagination" title="Direct link to Step 6: Implement Pagination">​</a></h2>
<p>As our application grows, we'll need to implement pagination for our list queries. Let's update our <code>jobListings</code> query to use cursor-based pagination:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Query</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic"># ... other queries</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">jobListings</span><span class="token punctuation" style="color:#fff">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">first</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Int</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">after</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">    </span><span class="token attr-name" style="color:#8DFFF8">filters</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">JobListingFilters</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token punctuation" style="color:#fff">)</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">JobListingConnection</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">JobListingConnection</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">edges</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">[</span><span class="token class-name" style="color:#C586C0">JobListingEdge</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token punctuation" style="color:#fff">]</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">pageInfo</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">PageInfo</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">JobListingEdge</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">node</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">JobListing</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">cursor</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">PageInfo</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">hasNextPage</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">Boolean</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">endCursor</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This implementation follows the Relay connection specification, which provides a standardized way to handle pagination in GraphQL.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-7-plan-for-real-time-updates">Step 7: Plan for Real-time Updates<a href="https://tailcall.run/blog/graphql-schema/#step-7-plan-for-real-time-updates" class="hash-link" aria-label="Direct link to Step 7: Plan for Real-time Updates" title="Direct link to Step 7: Plan for Real-time Updates">​</a></h2>
<p>For certain features, we might want to provide real-time updates. Let's add a subscription to notify when new job listings are posted:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Subscription</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">newJobListing</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">JobListing</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Clients can subscribe to this operation to receive updates whenever a new job listing is created.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-8-implement-custom-scalars">Step 8: Implement Custom Scalars<a href="https://tailcall.run/blog/graphql-schema/#step-8-implement-custom-scalars" class="hash-link" aria-label="Direct link to Step 8: Implement Custom Scalars" title="Direct link to Step 8: Implement Custom Scalars">​</a></h2>
<p>Our schema might benefit from some custom scalar types for specific data formats. For example, let's add a <code>DateTime</code> scalar:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">scalar</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">DateTime</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">JobListing</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic"># ... other fields</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">postedAt</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">DateTime</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">applicationDeadline</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">DateTime</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>We'll need to implement the serialization/deserialization logic for this scalar in our resolvers.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-9-use-interfaces-for-shared-fields">Step 9: Use Interfaces for Shared Fields<a href="https://tailcall.run/blog/graphql-schema/#step-9-use-interfaces-for-shared-fields" class="hash-link" aria-label="Direct link to Step 9: Use Interfaces for Shared Fields" title="Direct link to Step 9: Use Interfaces for Shared Fields">​</a></h2>
<p>As our schema grows, we might notice some types sharing common fields. We can use interfaces to model this shared structure:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token keyword" style="color:#C586C0">interface</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Node</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">interface</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Timestamped</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">createdAt</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">DateTime</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">updatedAt</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">DateTime</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Company</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">implements</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Node</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">&amp;</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Timestamped</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">createdAt</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">DateTime</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">updatedAt</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">DateTime</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic"># ... other fields</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">JobListing</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">implements</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Node</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">&amp;</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Timestamped</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">createdAt</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">DateTime</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">updatedAt</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">DateTime</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic"># ... other fields</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>This approach promotes consistency and can make it easier to implement features that work across multiple types.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-10-document-your-schema">Step 10: Document Your Schema<a href="https://tailcall.run/blog/graphql-schema/#step-10-document-your-schema" class="hash-link" aria-label="Direct link to Step 10: Document Your Schema" title="Direct link to Step 10: Document Your Schema">​</a></h2>
<p>Finally, it's crucial to document your schema thoroughly. GraphQL allows for built-in documentation:</p>
<div class="rounded-3xl overflow-hidden"><div class="bg-[#35353A] p-4 flex justify-between items-center"><span class="text-white text-xs font-space-mono"></span><div class="relative"><button aria-label="Copy code" class="flex flex-row items-center bg-transparent appearance-none border-none"><img src="https://tailcall.run/icons/basic/copy-icon.svg" alt="Copy Icon" class="w-4 h-4 cursor-pointer hover:opacity-80 transition-opacity duration-150"></button></div></div><div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#fff;--prism-background-color:#303037"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#fff;background-color:#303037"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#fff"><span class="token description string" style="color:#FDB869">"""</span><span class="token description string language-markdown" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token description string language-markdown" style="color:#FDB869">Represents a company on the TechTalent platform.</span><br></span><span class="token-line" style="color:#fff"><span class="token description string language-markdown" style="color:#FDB869"></span><span class="token description string" style="color:#FDB869">"""</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token keyword" style="color:#C586C0">type</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Company</span><span class="token plain"> </span><span class="token keyword" style="color:#C586C0">implements</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Node</span><span class="token plain"> </span><span class="token operator" style="color:#8DFFF8">&amp;</span><span class="token plain"> </span><span class="token class-name" style="color:#C586C0">Timestamped</span><span class="token plain"> </span><span class="token punctuation" style="color:#fff">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token description string" style="color:#FDB869">"""</span><span class="token description string language-markdown" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token description string language-markdown" style="color:#FDB869">  Unique identifier for the company.</span><br></span><span class="token-line" style="color:#fff"><span class="token description string language-markdown" style="color:#FDB869">  </span><span class="token description string" style="color:#FDB869">"""</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">id</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">ID</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token description string" style="color:#FDB869">"""</span><span class="token description string language-markdown" style="color:#FDB869"></span><br></span><span class="token-line" style="color:#fff"><span class="token description string language-markdown" style="color:#FDB869">  The name of the company.</span><br></span><span class="token-line" style="color:#fff"><span class="token description string language-markdown" style="color:#FDB869">  </span><span class="token description string" style="color:#FDB869">"""</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token attr-name" style="color:#8DFFF8">name</span><span class="token punctuation" style="color:#fff">:</span><span class="token plain"> </span><span class="token scalar" style="color:#8DFFF8">String</span><span class="token operator" style="color:#8DFFF8">!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain">  </span><span class="token comment" style="color:#30C26D;font-style:italic"># ... other fields</span><span class="token plain"></span><br></span><span class="token-line" style="color:#fff"><span class="token plain"></span><span class="token punctuation" style="color:#fff">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div>
<p>Good documentation helps both your team and API consumers understand the purpose and usage of each type and field.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="visualizing-the-schema">Visualizing the Schema<a href="https://tailcall.run/blog/graphql-schema/#visualizing-the-schema" class="hash-link" aria-label="Direct link to Visualizing the Schema" title="Direct link to Visualizing the Schema">​</a></h2>
<p>To better understand the relationships in our schema, let's visualize the core types:</p>
<p><img decoding="async" loading="lazy" alt="Diagram Illustrating Relationships between various types " src="https://tailcall.run/assets/images/entity-relationships-2b31d862fb993cbb5b5a9cc1e019f855.png" width="865" height="825" class="img_ev3q"></p>
<p>This diagram illustrates the key relationships between our main entities, helping us ensure our schema accurately represents our domain.</p>
<p>To visualize your schema, you can use tools like <a href="https://graphql-kit.com/graphql-voyager/" target="_blank" rel="noopener noreferrer">GraphQL Voyager</a>.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="best-practices-and-considerations">Best Practices and Considerations<a href="https://tailcall.run/blog/graphql-schema/#best-practices-and-considerations" class="hash-link" aria-label="Direct link to Best Practices and Considerations" title="Direct link to Best Practices and Considerations">​</a></h2>
<p>As we've designed our schema, we've touched on several best practices. Let's recap some key points and add a few more considerations:</p>
<ol>
<li>
<p><strong>Start with the UI in mind</strong>: Design your schema based on how the data will be used in your UI, not just how it's stored in your database.</p>
</li>
<li>
<p><strong>Use clear, consistent naming</strong>: Adopt a naming convention (e.g., PascalCase for types, camelCase for fields) and stick to it.</p>
</li>
<li>
<p><strong>Leverage GraphQL features</strong>: Make use of enums, interfaces, and unions to create a rich, expressive schema.</p>
</li>
<li>
<p><strong>Plan for change</strong>: Use input types for mutations and consider versioning strategies for evolving your schema over time.</p>
</li>
<li>
<p><strong>Optimize for performance</strong>: Be mindful of N+1 query problems and consider implementing DataLoader or similar batching mechanisms.</p>
</li>
<li>
<p><strong>Secure your schema</strong>: Implement proper authentication and authorization. Consider using directives for field-level permissions.</p>
</li>
<li>
<p><strong>Validate input</strong>: Use non-nullable fields and custom scalars to enforce data integrity at the schema level.</p>
</li>
<li>
<p><strong>Provide meaningful errors</strong>: Return detailed error information in your mutation payloads to help clients handle failures gracefully.</p>
</li>
<li>
<p><strong>Monitor and analyze</strong>: Implement logging and monitoring to understand how your schema is being used and where optimizations can be made.</p>
</li>
<li>
<p><strong>Keep it DRY</strong>: Use interfaces and abstract types to reduce duplication in your schema.</p>
</li>
</ol>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="conclusion">Conclusion<a href="https://tailcall.run/blog/graphql-schema/#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion">​</a></h2>
<p>Designing a production-grade GraphQL schema is an iterative process that requires careful thought and planning. By starting with core types and relationships, then gradually adding queries, mutations, and advanced features, we can build a schema that's both powerful and maintainable.</p>
<p>Remember, your schema is a living document. As your application evolves, so too will your schema. By following these principles and best practices, you'll be well-equipped to design and maintain a GraphQL schema that can grow with your needs.</p>
<p>The TechTalent example we've explored here demonstrates many real-world considerations, but every application will have its unique requirements. Always design with your specific use cases in mind, and don't be afraid to iterate as you learn more about how your API is used in practice.</p>
<p>By investing time in thoughtful schema design upfront, you'll create a solid foundation for your GraphQL API, enabling efficient development and a great experience for your API consumers.</p>
<p>Alright greatttt! You have successfully completed the first part of a very intricate series!! Pat yourslef and maybe high five your cat! Here are the links to the next blogs in the series that have already been published.</p>
<p><img decoding="async" loading="lazy" alt="cat giving high five" src="https://tailcall.run/assets/images/cat-high-five-gif-cc8601ed8d765d559f1293ad9a98f652.webp" width="356" height="200" class="img_ev3q"></p>
<ul>
<li><a href="https://tailcall.run/blog/graphql-schema-part-2-1/">Next Part</a></li>
</ul>]]></content:encoded>
            <category>GraphQL</category>
            <category>API</category>
            <category>Schema</category>
            <category>Design</category>
            <category>Best Practices</category>
        </item>
        <item>
            <title><![CDATA[Writing a GraphQL Backend by Hand is Long Gone]]></title>
            <link>https://tailcall.run/blog/writing-a-graphql-backend-by-hand-is-long-gone/</link>
            <guid>https://tailcall.run/blog/writing-a-graphql-backend-by-hand-is-long-gone/</guid>
            <pubDate>Thu, 30 May 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Writing a GraphQL backend by hand doesn't scale beyond a point.]]></description>
            <content:encoded><![CDATA[<p>Building a GraphQL backend by hand might seem like a noble pursuit, but the landscape of API development is evolving rapidly, and so are the challenges that come with it. Today, the process is often fraught with complexity, performance bottlenecks, security vulnerabilities, and reliability issues. Yet again, we had a developer expressing <a href="https://bessey.dev/blog/2024/05/24/why-im-over-graphql/" target="_blank" rel="noopener noreferrer">frustration</a> about the issues with GraphQL and the reasons for leaving our mighty ship. I wish to dive deeper into these challenges and explore why the future points towards automated, high-performance solutions.</p>
<!-- -->
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="complexity-with-graphql">Complexity with GraphQL<a href="https://tailcall.run/blog/writing-a-graphql-backend-by-hand-is-long-gone/#complexity-with-graphql" class="hash-link" aria-label="Direct link to Complexity with GraphQL" title="Direct link to Complexity with GraphQL">​</a></h2>
<p>If you see, most of the concerns with GraphQL are around building a robust GraphQL backend. It's rarely about consuming GraphQL, because if you look closely at the GraphQL spec, you will find that it's focused on how to elegantly consume data. As long as the output of your backend matches what's expected in the query, the specification doesn't care about how the backend is implemented.</p>
<p>Hence, the main complexity with GraphQL comes with how GraphQL is built. One of the major hurdles in hand-coding a GraphQL backend is managing performance. Issues like batching, incorrect usage of data loaders, caching, and the notorious N+1 problem can cripple your application.</p>
<p>Manually implementing batching mechanisms and data loaders can be incredibly tedious. While libraries like <a href="https://github.com/graphql/dataloader" target="_blank" rel="noopener noreferrer">DataLoader</a> can assist, integrating them seamlessly into your system requires a deep understanding of both your data and the GraphQL query patterns. Overuse of data loaders is so common with most GraphQL implementations that ultimately it becomes the main culprit for high latency.</p>
<p>Secondly, traditional caching doesn't work with GraphQL, so you have to resort to all sorts of solutions, using persisted queries or some vendor-specific implementation of caching. Implementing effective caching strategies is essential for performance but it's tricky. Developers must decide what to cache, when to invalidate the cache, and how to manage cache consistency, which adds another layer of complexity.</p>
<p>The N+1 issue, boy, that's perhaps everyone's favorite issue with GraphQL. It arises when executing multiple upstream requests that could have been combined into one, leading to massive performance degradation. Detecting and solving this requires meticulous analysis of query patterns and database access, which requires developers to have the context of the whole query at once, generate a query plan, translate it to appropriate upstream calls, and then execute! That's a lot of complex engineering effort; building a general-purpose query engine is not for the faint-hearted, and in the midst of all this complex yet interesting work, I need to ship features!</p>
<blockquote>
<p><a href="https://grafast.org/grafast" target="_blank" rel="noopener noreferrer">Grafast</a> is an upcoming generalized query planner that could make query-planning in JS a bit more tamed.</p>
</blockquote>
<p>GraphQL’s flexibility can be a double-edged sword when it comes to security, necessitating robust mechanisms for authentication and authorization. Like caching, traditional route-based API access doesn't work with GraphQL. Implementing these security layers correctly involves ensuring that only authenticated users can access the GraphQL entity and that they can only access data or fields that they are authorized to see. This requires fine-grained control and often custom logic and the invention of a new standard that works just for you.</p>
<p>Lastly, but most importantly, ensuring your GraphQL API is reliable means tackling error handling, propagation, and telemetry. Proper error handling in GraphQL is crucial for providing meaningful feedback to clients and maintaining the integrity of your application. The GraphQL team recently started working on a <a href="https://graphql-http.com/" target="_blank" rel="noopener noreferrer">standard</a> for serving GraphQL over HTTP, which won't be easy to integrate if you already have a GraphQL API running in production. Moreover, integrating telemetry within a GraphQL backend isn't easy either; it is a very involved process to integrate spans to trace GraphQL resolvers. And, if you have written your GraphQL layer by hand in JavaScript, be ready for some <a href="https://github.com/DataDog/dd-trace-js/issues/1095" target="_blank" rel="noopener noreferrer">significant performance degradation</a>.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="graphql-is-more-like-sql-and-less-like-rest">GraphQL is more like SQL and less like REST<a href="https://tailcall.run/blog/writing-a-graphql-backend-by-hand-is-long-gone/#graphql-is-more-like-sql-and-less-like-rest" class="hash-link" aria-label="Direct link to GraphQL is more like SQL and less like REST" title="Direct link to GraphQL is more like SQL and less like REST">​</a></h2>
<p>We talked about it in our <a href="https://tailcall.run/blog/graphql-vs-rest-vs-grpc/">previous</a> blog why GraphQL isn't like REST or gRPC. I would argue that SQL is a closer elder sibling of GraphQL than REST or gRPC. Writing a GraphQL backend can be likened to building an SQL engine manually. Imagine if every time you wanted to interact with a database, you had to write the SQL engine from scratch. Every time you made a database change, you would need to rewrite your engine so that it can work with the new schema or indexes. It’s inefficient and impractical; no one does that. Fortunately, modern databases come with embedded, high-performance SQL engines such as <a href="https://calcite.apache.org/" target="_blank" rel="noopener noreferrer">Apache Calcite</a> that adhere to the SQL specification but abstract away the complexities around building it. These databases allow developers to focus on writing queries and managing data without worrying about the underlying mechanics, thanks to their sophisticated query engines.</p>
<p>GraphQL, much like SQL, is a query language designed to allow clients to request exactly the data they need. Unlike REST, which relies on fixed endpoints, or gRPC, which focuses on remote procedure calls, GraphQL provides a flexible, hierarchical way to fetch and manipulate data, making it a closer analog to SQL in terms of expressiveness and precision. And I believe the future of GraphQL is going to be like the journey of this elder sibling.</p>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="the-future-of-graphql">The future of GraphQL<a href="https://tailcall.run/blog/writing-a-graphql-backend-by-hand-is-long-gone/#the-future-of-graphql" class="hash-link" aria-label="Direct link to The future of GraphQL" title="Direct link to The future of GraphQL">​</a></h2>
<p>The future of GraphQL development is moving towards generalized automated solutions built on modern, low-level system stacks like Rust and Zig, and moving away from the prevalent hand-written Node.js-based solutions of today.</p>
<p><a href="https://hygraph.com/graphql-survey-2024#how-developers-build-graphql-apis" target="_blank" rel="noopener noreferrer"><img decoding="async" loading="lazy" alt="Most common GraphQL implementations" src="https://tailcall.run/assets/images/graphql-stack-44b03452c850592b2fc28fb2acfbd409.png" width="1750" height="1136" class="img_ev3q"></a></p>
<ul>
<li>
<p>These engines will connect to data sources of any type and build a GraphQL endpoint on top of them. They will find connections between other data sources, sometimes completely automatically and sometimes using hints given by the developer, creating a unified GraphQL experience.</p>
</li>
<li>
<p>Similar to SQL engines, which use JIT techniques to identify performance optimizations at runtime, GraphQL engines will become extremely smart about performance. My hope is that GraphQL will eventually move away from its dependency on the JSON protocol, into something more efficient such as protobuf.</p>
</li>
<li>
<p>There is definitely going to be a lot of work put into the standardization of the loose ends. GraphQL engines will eventually converge on error handling and error propagation strategies. GraphQL on HTTP is the first step in that direction. Authentication and Authorization too will very quickly become standard features of GraphQL, so you won't need to worry about inventing a new way of authentication. This will all be packed into a GraphQL standard. This might be a stretch, but if the standards team gets together, I think even GraphQL caching will be consistent across all GraphQL engines, and you will be able to switch from one caching solution to another without locking into a vendor-specific implementation.</p>
</li>
</ul>
<p>You might have already seen a wave of open-source solutions that build GraphQL on top of existing data sources. One such solution paving the way is <a href="https://tailcall.run/" target="_blank" rel="noopener noreferrer">Tailcall</a>. Tailcall’s platform is designed to automate the creation, validation, and optimization of GraphQL backends. Sticking to standards and ensuring developers don't ever have to pay the heavy tax of using GraphQL that they do today, do check it out!</p>
<p>Lastly, if you are reading this today and thinking of writing a GraphQL server by hand, I urge you to reconsider and use something that does this for you. Before you know it, your handwritten solution will be deprecated in favor of something faster, easier, and more secure: an automatic GraphQL solution.</p>]]></content:encoded>
            <category>GraphQL</category>
            <category>Node.js</category>
            <category>JavaScript</category>
        </item>
    </channel>
</rss>