<?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>GraphQL Java Blog</title>
        <link>https://graphql-java.com/blog</link>
        <description>GraphQL Java Blog</description>
        <lastBuildDate>Fri, 15 Aug 2025 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>
        <item>
            <title><![CDATA[Celebrating 10 years of GraphQL Java]]></title>
            <link>https://graphql-java.com/blog/10-years-of-graphql-java</link>
            <guid>https://graphql-java.com/blog/10-years-of-graphql-java</guid>
            <pubDate>Fri, 15 Aug 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[We are very proud to celebrate 10 years of GraphQL Java!]]></description>
            <content:encoded><![CDATA[<p>We are very proud to celebrate 10 years of GraphQL Java!</p>
<p>What started as a little hobby project has become an industry standard.</p>
<p>We want to express our sincere thanks to the GraphQL Java community, the 250+ code contributors and countless more who created issues and participated in discussions. Thanks to all volunteers who helped make GraphQL Java better!</p>
<p>Now we’d like to share fun stories about the last 10 years.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-we-came-to-the-library">How we came to the library<a href="https://graphql-java.com/blog/10-years-of-graphql-java#how-we-came-to-the-library" class="hash-link" aria-label="Direct link to How we came to the library" title="Direct link to How we came to the library" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="andis-story">Andi's story<a href="https://graphql-java.com/blog/10-years-of-graphql-java#andis-story" class="hash-link" aria-label="Direct link to Andi's story" title="Direct link to Andi's story" translate="no">​</a></h3>
<p>I was working at a small company which used a REST(ish) API for their web app. This API evolved and had a lot of typical features added on top of rest like field selection, sub selections etc. to make it performant and practical useable. When a colleague pointed me to the imminent release of a new protocol called “GraphQL” by Facebook I was immediately convinced of its value because: it solved the API problems we had on a fundamental level.</p>
<p>I sat down for a week or so and invested all my free time to come up with the first version of GraphQL Java as quick as possible. Very quickly after I released a version 0.1 I already got a first contributor and user. (The) REST is history 🙂</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="brads-story">Brad's story<a href="https://graphql-java.com/blog/10-years-of-graphql-java#brads-story" class="hash-link" aria-label="Direct link to Brad's story" title="Direct link to Brad's story" translate="no">​</a></h3>
<p>I was an architect at Atlassian on the Jira Service Desk product (now JSM) and we were embracing dynamic UIs driven by having more data called via browser calls.  If you don't know what jQuery and AJAX is - just trust me, it was cool in its time.</p>
<p>We invented a REST endpoint nicked named The Smoosher - you made a call and we just smooshed all the data you need to paint the JSD portal screens.  It worked but it clearly broke all the RESTian orthodoxy around resources and state and other networking dogma.</p>
<p>I started looking into GraphQL as a more architectural technique for getting the data you need for a dynamic UI.  As we had a JVM back end, I started to look into graphql-java.</p>
<p>My first PR was adding the Instrumentation classes that kinda still exist today (albeit in a more efficient form).  graphql-java became an after-work hobby to keep my hand in at coding (architects are always drawn away from coding towards the dark side called a rich text editor and eventually Keynote / Powerpoint)</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="donnas-story">Donna's story<a href="https://graphql-java.com/blog/10-years-of-graphql-java#donnas-story" class="hash-link" aria-label="Direct link to Donna's story" title="Direct link to Donna's story" translate="no">​</a></h3>
<p>I started a new job on the same team as Andi and Brad. At the time, GraphQL was completely new to me, yet I knew I had to learn pretty quickly for the job! I like to learn by coding, so I picked a few bug tickets to give me a goal to aim for. Andi and Brad patiently explained concepts and reviewed my PRs (and still do!), making the whole experience much less daunting.</p>
<p>Contributing to GraphQL Java was easily the best decision I’ve made in my career. I was hooked from my first PR, kept contributing, and things snowballed from there. Soon I became a maintainer, and a dream came true when Andi and I published a book together, <a href="https://leanpub.com/graphql-java/" target="_blank" rel="noopener noreferrer" class="">GraphQL with Java and Spring</a>.</p>
<p>Cheers to many more years of GraphQL Java 🍻 Later this year we’ll be speaking at <a href="https://graphql.org/conf/2025/schedule/3cfd3578b6acb121870ddcc96b69543e/" target="_blank" rel="noopener noreferrer" class="">GraphQL Conference 2025</a>, see you there!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Version 24 released]]></title>
            <link>https://graphql-java.com/blog/v24-released</link>
            <guid>https://graphql-java.com/blog/v24-released</guid>
            <pubDate>Tue, 13 May 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[We are pleased to announce the release of graphql-java v24.0.]]></description>
            <content:encoded><![CDATA[<p>We are pleased to announce the release of graphql-java v24.0.</p>
<p>This release is an unexpected breaking change release. It was made to help propagate a fix in the DataLoader library.</p>
<p>We consider v23.x poisoned and we don't recommend you use it because of the latent bug explained in the release notes on <a href="https://github.com/graphql-java/graphql-java/releases/tag/v24.0" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>
<p>Going forward we will not be supporting v23.x, instead please skip this series and use v24.x going forward.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Version 23 released]]></title>
            <link>https://graphql-java.com/blog/v23-released</link>
            <guid>https://graphql-java.com/blog/v23-released</guid>
            <pubDate>Sat, 12 Apr 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Update: please use the v24 series of releases instead of v23 releases. We have made a clearer breaking change in Java DataLoader, thus we will discontinue v23.]]></description>
            <content:encoded><![CDATA[<p><strong>Update: please use the v24 series of releases instead of v23 releases. We have made a clearer breaking change in Java DataLoader, thus we will discontinue v23.</strong></p>
<p>We are pleased to announce the release of graphql-java v23.0! Thanks to everyone in the community who contributed to the release, whether that was code, helping to report issues, or participating in discussions.</p>
<p>This is a <strong>breaking change</strong> release. Included are performance improvements and features.</p>
<p>For the full details, please see the release notes on <a href="https://github.com/graphql-java/graphql-java/releases/tag/v23.0" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[GraphQL Java is a CVE Numbering Authority]]></title>
            <link>https://graphql-java.com/blog/cna</link>
            <guid>https://graphql-java.com/blog/cna</guid>
            <pubDate>Sat, 07 Dec 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[We are please to announce GraphQL Java is now the CVE Numbering Authority (CNA) for GraphQL Java, Java DataLoader, GraphQL Java Extended Scalars, and GraphQL Java Extended Validation.]]></description>
            <content:encoded><![CDATA[<p>We are please to announce GraphQL Java is now the CVE Numbering Authority (CNA) for GraphQL Java, Java DataLoader, GraphQL Java Extended Scalars, and GraphQL Java Extended Validation.</p>
<p>See the CVE.org press release: <a href="https://www.cve.org/Media/News/item/news/2024/12/03/GraphQL-Java-Added-as-CNA" target="_blank" rel="noopener noreferrer" class="">https://www.cve.org/Media/News/item/news/2024/12/03/GraphQL-Java-Added-as-CNA</a></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Automated performance testing for GraphQL Java]]></title>
            <link>https://graphql-java.com/blog/performance</link>
            <guid>https://graphql-java.com/blog/performance</guid>
            <pubDate>Fri, 06 Dec 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[GraphQL Java has become a mature and widely adopted library over the past 9.5 years.]]></description>
            <content:encoded><![CDATA[<p>GraphQL Java has become a mature and widely adopted library over the past 9.5 years.
And while we continue to maintain, improve and add features, we don't expect revolutionary changes to the core of the library.</p>
<p>As side effect of this maturity it became clear over the least years, that performance is a key aspect that users are interested in.
Especially in larger scale applications performance can have a huge impact on operational costs and user experience.</p>
<p>In GraphQL Java we leverage <a href="https://github.com/openjdk/jmh" target="_blank" rel="noopener noreferrer" class="">JMH aka Java Microbenchmark Harness</a> to  measure and compare different performance aspects.</p>
<p>Historically, performance testing was done manually by running JMH benchmarks on a local machine.</p>
<p>This comes with the obvious flaw that it's not reproducible over time and across different machines. A benchmark run on one developer's machine is not
comparable to a run on another developer's machine (or often even the same machine months later).</p>
<p>We are very happy to share that we have now an automated performance testing setup in place to overcome these limitations by running
the benchmarks in an isolated cloud environment.</p>
<p>Currently, it runs on every commit to the <code>master</code> branch and the results are stored in the<br>
<a href="https://github.com/graphql-java/graphql-java/tree/master/performance-results" target="_blank" rel="noopener noreferrer" class="">performance results folder</a>.
You can visualize and compare results with the <a href="https://jmh.morethan.io/" target="_blank" rel="noopener noreferrer" class="">JMH Visualizer tool</a>, a free tool which runs in the browser.
Our goal is to provide clear and reproducible performance improvements over time while preventing any regressions.</p>
<p>This work is sponsored and made possible by <a href="https://www.atlassian.com/" target="_blank" rel="noopener noreferrer" class="">Atlassian</a> and we are very grateful for their support.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Version 22 released]]></title>
            <link>https://graphql-java.com/blog/v22-released</link>
            <guid>https://graphql-java.com/blog/v22-released</guid>
            <pubDate>Thu, 18 Apr 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[We are thrilled to announce the release of graphql-java v22.0! Thanks to everyone in the community who contributed to the release, whether that was code, helping to report issues, or participating in discussions.]]></description>
            <content:encoded><![CDATA[<p>We are thrilled to announce the release of graphql-java v22.0! Thanks to everyone in the community who contributed to the release, whether that was code, helping to report issues, or participating in discussions.</p>
<p>This is a <strong>breaking change</strong> release, which includes major performance improvements. This release also introduces the <code>@defer</code> directive, which enables data to be received incrementally, rather than waiting until all data is resolved. This can reduce an application's time-to-interactive. See more on the <code>@defer</code> draft specification on the <a href="https://github.com/graphql/graphql-wg/blob/main/rfcs/DeferStream.md" target="_blank" rel="noopener noreferrer" class="">GraphQL Working Group's GitHub repo</a>.</p>
<p>For the full details, please see the release notes on <a href="https://github.com/graphql-java/graphql-java/releases/tag/v22.0" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Version 21 released]]></title>
            <link>https://graphql-java.com/blog/v21-released</link>
            <guid>https://graphql-java.com/blog/v21-released</guid>
            <pubDate>Tue, 11 Jul 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[We are pleased to announce the release of graphql-java v21.0! Thanks to everyone in the community who contributed to the release, whether that was code, helping to report issues, or participating in discussions.]]></description>
            <content:encoded><![CDATA[<p>We are pleased to announce the release of graphql-java v21.0! Thanks to everyone in the community who contributed to the release, whether that was code, helping to report issues, or participating in discussions.</p>
<p>And a very Happy 8th Birthday to graphql-java, who celebrated their birthday last week!</p>
<p>This is a <strong>breaking change</strong> release, including upgrading to Java 11 and changes to <code>parseValue</code> coercion. See the full release notes on <a href="https://github.com/graphql-java/graphql-java/releases/tag/v21.0" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[GraphQL Java release policy]]></title>
            <link>https://graphql-java.com/blog/release-policy</link>
            <guid>https://graphql-java.com/blog/release-policy</guid>
            <pubDate>Tue, 21 Mar 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[We’re formalising our release schedule to give the community a better idea of when to expect releases, what will be contained within them, and when important fixes will be backported.]]></description>
            <content:encoded><![CDATA[<p>We’re formalising our release schedule to give the community a better idea of when to expect releases, what will be contained within them, and when important fixes will be backported.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="general-release-schedule">General release schedule<a href="https://graphql-java.com/blog/release-policy#general-release-schedule" class="hash-link" aria-label="Direct link to General release schedule" title="Direct link to General release schedule" translate="no">​</a></h2>
<div class="theme-admonition theme-admonition-caution admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>caution</div><div class="admonitionContent_BuS1"><p>Since this blog post was published, we changed our release schedule from 4 times to 3 times per year.</p></div></div>
<p>Going forward, we plan to have 3 releases every year. We will alternate between releases containing breaking changes, and releases containing features and bugfixes (without breaking changes).</p>
<p>For example: our next release 20.1 will be in late March 2023, and this will be a feature and bugfix release without breaking changes. Therefore, we’re going to retain Java 8 in the 20.1 release. Our subsequent release will be around early July 2023 and will contain breaking changes, including upgrading to Java 11.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="security-backports">Security backports<a href="https://graphql-java.com/blog/release-policy#security-backports" class="hash-link" aria-label="Direct link to Security backports" title="Direct link to Security backports" translate="no">​</a></h2>
<p>We will backport critical bugfixes and security fixes for versions dating back 18 months. These fixes will be backported depending on severity and demand. As security fixes are time sensitive, we will release them on demand instead of waiting for the next release date.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="bugfix-backports">Bugfix backports<a href="https://graphql-java.com/blog/release-policy#bugfix-backports" class="hash-link" aria-label="Direct link to Bugfix backports" title="Direct link to Bugfix backports" translate="no">​</a></h2>
<p>We will backport important bug fixes at most 12 months. These fixes will be backported depending on the severity of the bug and demand.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="deprecations">Deprecations<a href="https://graphql-java.com/blog/release-policy#deprecations" class="hash-link" aria-label="Direct link to Deprecations" title="Direct link to Deprecations" translate="no">​</a></h2>
<p>When code is deprecated, we will wait at least 12 months before removing it.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="version-numbering">Version numbering<a href="https://graphql-java.com/blog/release-policy#version-numbering" class="hash-link" aria-label="Direct link to Version numbering" title="Direct link to Version numbering" translate="no">​</a></h2>
<p>We will continue to use <code>major.minor</code> version numbering.</p>
<p>A minor version can include bug fixes and features, but not breaking changes. A major version can include breaking changes.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="allowing-for-policy-changes">Allowing for policy changes<a href="https://graphql-java.com/blog/release-policy#allowing-for-policy-changes" class="hash-link" aria-label="Direct link to Allowing for policy changes" title="Direct link to Allowing for policy changes" translate="no">​</a></h2>
<p>The aim of this release policy to give the community a better indication of release dates, what is contained in releases, and when fixes will be backported. However, we may make a pragmatic decision to diverge from this policy when required. For example, a major and urgent breaking change could result in two breaking change releases in a row. If we diverge from this release policy, we’ll make it clear in the release notes.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[GraphQL Java will require Java 11]]></title>
            <link>https://graphql-java.com/blog/java-11-required</link>
            <guid>https://graphql-java.com/blog/java-11-required</guid>
            <pubDate>Wed, 14 Dec 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[GraphQL Java will require Java 11 as a minimum Java version, starting from version 21.]]></description>
            <content:encoded><![CDATA[<p>GraphQL Java will require Java 11 as a minimum Java version, starting from version 21.</p>
<p>With Java 8 being released over 8 years ago and Java 17 more than one year ago, we think now is the
right time to upgrade the minimum Java version GraphQL Java is developed against.</p>
<p>This means starting with version 21 you need to use at least Java 11 to run GraphQL Java.</p>
<p>Depending on the feedback we get, we plan to release bugfix releases for version 20 for some time, but no longer
than until end of 2023.</p>
<p>Please discuss and leave feedback <a href="https://github.com/graphql-java/graphql-java/discussions/3052" target="_blank" rel="noopener noreferrer" class="">here</a></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Version 20 released]]></title>
            <link>https://graphql-java.com/blog/version-20-released</link>
            <guid>https://graphql-java.com/blog/version-20-released</guid>
            <pubDate>Wed, 07 Dec 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[We are pleased to announce the release of graphql-java 20.0!]]></description>
            <content:encoded><![CDATA[<p>We are pleased to announce the release of graphql-java 20.0!</p>
<p>Special thanks to each of the 200+ contributors over the years, who have made this milestone possible.</p>
<p>We've added support for record-like property fetching, added performance improvements for <code>PropertyDataFetcher</code> and reduced object allocation.</p>
<p>Version 20 also introduces internationalization (i18n) for validation, parsing, and scalar coercion <a href="https://github.com/graphql-java/graphql-java/tree/master/src/main/resources/i18n" target="_blank" rel="noopener noreferrer" class="">error messages</a>. We have added German translations, and we would love to see more languages. If you would like to contribute, please open a pull request.</p>
<p>See the full release notes on <a href="https://github.com/graphql-java/graphql-java/releases/tag/v20.0" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Spring for GraphQL is the recommended Spring integration]]></title>
            <link>https://graphql-java.com/blog/spring-for-graphql</link>
            <guid>https://graphql-java.com/blog/spring-for-graphql</guid>
            <pubDate>Tue, 20 Sep 2022 00:00:00 GMT</pubDate>
            <description><![CDATA[If you are building a GraphQL application with Spring, we recommend using the official Spring for GraphQL integration. This integration is a collaboration between the Spring and GraphQL Java teams, and is maintained by the Spring team. In May 2022, Spring for GraphQL 1.0 GA was released.]]></description>
            <content:encoded><![CDATA[<p>If you are building a GraphQL application with Spring, we recommend using the official <a href="https://spring.io/projects/spring-graphql" target="_blank" rel="noopener noreferrer" class="">Spring for GraphQL</a> integration. This integration is a collaboration between the Spring and GraphQL Java teams, and is maintained by the Spring team. In May 2022, Spring for GraphQL 1.0 GA was <a href="https://spring.io/blog/2022/05/19/spring-for-graphql-1-0-release" target="_blank" rel="noopener noreferrer" class="">released</a>.</p>
<p>Use <a href="https://start.spring.io/" target="_blank" rel="noopener noreferrer" class="">Spring Initializr</a> to create a GraphQL application. For a quick tutorial, please see our <a href="https://www.graphql-java.com/tutorials/getting-started-with-spring-boot" target="_blank" rel="noopener noreferrer" class="">Spring for GraphQL tutorial</a>.</p>
<p>See also the Spring for GraphQL <a href="https://docs.spring.io/spring-graphql/docs/current/reference/html/" target="_blank" rel="noopener noreferrer" class="">documentation</a> and the repo on <a href="https://github.com/spring-projects/spring-graphql" target="_blank" rel="noopener noreferrer" class="">GitHub</a>.</p>
<p>Before the official Spring for GraphQL integration was released, there were many other GraphQL integrations for Spring, including the similarly named <a href="https://github.com/graphql-java-kickstart/graphql-spring-boot" target="_blank" rel="noopener noreferrer" class="">GraphQL Java Spring</a> project from the GraphQL Java team, published under the <code>com.graphql-java</code> and <code>com.graphql-java-kickstart</code> group IDs. Many tutorials are still referring to this unrelated project.</p>
<p>Please use the official integration named <strong>"Spring for GraphQL"</strong>, published under <code>org.springframework</code> and related group IDs.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[GraphQL Java 17 released and an update about LTS]]></title>
            <link>https://graphql-java.com/blog/17-released-and-lts</link>
            <guid>https://graphql-java.com/blog/17-released-and-lts</guid>
            <pubDate>Tue, 03 Aug 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[We are happy to announce the availability of GraphQL Java 17.0.]]></description>
            <content:encoded><![CDATA[<p>We are happy to announce the availability of GraphQL Java 17.0.
See <a href="https://github.com/graphql-java/graphql-java/releases/tag/v17.0" target="_blank" rel="noopener noreferrer" class="">17.0 release notes</a> for all the details.</p>
<p>At the same time we wanted to give an update regarding our LTS (Long Term Support) policy.
Previously we maintained a LTS version of 9.x and after quite some time we announced 14.x as the next LTS.</p>
<p>The reality is that we didn't maintain 14.x really as a LTS version (we only released one bugfix release).
This was mainly caused by the minimal community feedback and our limited time and resources.</p>
<p>Going forward we decided to no offer any LTS versions anymore. We will only actively maintain and bugfix
the latest version (currently 17). We may backport critical bugfixes, but we are not committed to it.</p>
<p>If this is a huge problem for you or your Company and you are willing to help us with maintaining a LTS
version you can reach us via email at
hello at graphql-java dot com.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[GraphQL spec releases are not important]]></title>
            <link>https://graphql-java.com/blog/spec-releases-are-not-important</link>
            <guid>https://graphql-java.com/blog/spec-releases-are-not-important</guid>
            <pubDate>Fri, 12 Feb 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[Every once in a while somebody asks which version of the GraphQL spec]]></description>
            <content:encoded><![CDATA[<p>Every once in a while somebody asks which version of the <a href="https://github.com/graphql/graphql-spec" target="_blank" rel="noopener noreferrer" class="">GraphQL spec</a>
GraphQL Java supports. The general answer is: the current draft.</p>
<p>The bigger question behind this is: what is the information you want get out of this question?
Why do you ask this question?</p>
<p>The thing is: spec releases are not really important and people misinterpret what they mean.</p>
<p>The GraphQL spec has five releases so far:</p>
<ul>
<li class="">two in 2015 (including the first published version)</li>
<li class="">two in 2016</li>
<li class="">one in 2018</li>
</ul>
<p>As you can see in the first two years spec releases where quite frequently, but after the one in 2018,
there has not been a release.</p>
<p>2017 was also the year the <a href="https://github.com/graphql/graphql-wg" target="_blank" rel="noopener noreferrer" class="">GraphQL Working Group</a> was established.
This group is the main forum to evolve the spec since then. Over time this group established a very high bar
for every PR to be merged into the spec. (See the <a href="https://github.com/graphql/graphql-spec/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer" class="">Contributing guidelines</a>)</p>
<p>With this high standard set, nearly all implementations (including GraphQL Java) started to implement every
merged PR instead of waiting for a big release. Because they are very confident this change will be released
in this form, it is safe to implement it right away.</p>
<p>This treatment of merged PRs as de-factor releases is now an established rule in the GraphQL community.
This explains why the whole GraphQL ecosystem has evolved a lot since 2018, even without a release.</p>
<p><strong>A release is not needed anymore if every merged PR is like a mini release.</strong></p>
<p>Future releases are more like an
<a href="https://github.com/graphql/graphql-wg/blob/main/notes/2021-02-04.md#promoting-and-documenting-spec-release-5m-brian" target="_blank" rel="noopener noreferrer" class="">opportunity to look back and promote the work since the last release.</a></p>
<p>I personally hope that we make this de-facto rule, that evey PR is a mini release, more official.
We should not use the word "draft" any more, but every merged PR should automatically result in a
new GraphQL spec version which is formally approved by the <a href="https://github.com/graphql/graphql-wg/blob/main/GraphQL-TSC.md" target="_blank" rel="noopener noreferrer" class="">GraphQL TSC.</a></p>
<p>Coming back to the question: "Which spec version of GraphQL is supported"?
I hope by now it is clear why this question is probably not really helpful.</p>
<p>It is better to think about certain features you want to discuss instead referring to the spec releases.</p>
<h1>Feedback or questions</h1>
<p>We use <a href="https://github.com/graphql-java/graphql-java/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a> for general feedback and questions.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[GraphQL Java and Threads]]></title>
            <link>https://graphql-java.com/blog/threads</link>
            <guid>https://graphql-java.com/blog/threads</guid>
            <pubDate>Fri, 05 Feb 2021 00:00:00 GMT</pubDate>
            <description><![CDATA[We follow a fundamental rule in GraphQL Java regarding Threads: GraphQL Java never creates]]></description>
            <content:encoded><![CDATA[<p>We follow a fundamental rule in GraphQL Java regarding Threads: GraphQL Java never creates
Threads or interacts with Thread pools. We do this because we want to give the user the full control
and whatever GraphQL Java would do, it would not be correct for every use case.</p>
<p>Additionally to being strictly unopinionated regarding Threads, GraphQL Java is also fully reactive,
implemented via <code>CompletableFuture</code> (<code>CF</code>).
These two constrain together mean we rely on the <code>CF</code> returned by the user.
Specifically we piggyback on the <code>CF</code> returned by the <code>DataFetcher</code>
(or other async methods which can be implemented by the user, but we focus here on <code>DataFetcher</code>
as it is by far the most important).</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Pseudo code in GraphQL Java</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token class-name">CompletableFuture</span><span class="token generics punctuation" style="color:#393A34">&lt;</span><span class="token generics class-name">Object</span><span class="token generics punctuation" style="color:#393A34">&gt;</span><span class="token plain"> dataFetcherResult </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">invokeDataFetcher</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">dataFetcherResult</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">thenApply</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">result </span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// in which Thread  where this code happens is controlled by the CF returned</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">continueExecutingQuery</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">result</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<h1>Blocking DataFetcher</h1>
<p>Lets assume you are accessing a DB in a blocking way in your <code>DataFetcher</code>:</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token class-name">String</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">DataFetchingEnvironment</span><span class="token plain"> env</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">getValueFromDb</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">env</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// blocking the Thread until the value is read from DB</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>This is not completely wrong, but not recommend in general as the consequence of this kind of <code>DataFecher</code>
is that GraphQL can't execute the query in the most efficient way.</p>
<p>For example for the following query:</p>
<div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">dbData1</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">dbData2</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">dbData3</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>If the <code>DataFetcher</code> for these <code>dbData</code> fields don't return a <code>CF</code>,
but block the Thread until the data is read, GraphQL Java will not work with maximum efficiency.</p>
<p>GraphQL Java can invoke the <code>DataFetcher</code> for all three fields in parallel. But if your <code>DataFetcher</code> for
<code>dbData1</code> is blocking, GraphQL Java will also be blocked and only invoke the next <code>DataFetcher</code> once <code>dbData&lt;n&gt;</code>
is finished.
The recommend solution to this problem is offloading your blocking code onto a separate Thread pool
as shown here:</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token class-name">CompletableFuture</span><span class="token generics punctuation" style="color:#393A34">&lt;</span><span class="token generics class-name">String</span><span class="token generics punctuation" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">DataFetchingEnvironment</span><span class="token plain"> env</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token class-name">CompletableFuture</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">supplyAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">getValueFromDb</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">env</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> dbThreadPool </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>This code will maximize the performance and will cause all three fields to be fetched in parallel.</p>
<h1>Different pools for different work</h1>
<p>The subsequent work done by GraphQL Java will be executed in the same <code>dbThreadPool</code> until it
encounters a new <code>DataFetcher</code> returned by the user code and this new <code>CF</code> dedicates the Thread
for the subsequent work.</p>
<p>If you want to have separate pools for different kind of work, one for the actual <code>DataFetcher</code> which normally
involve IO and one of the actual GraphQL Java work (which is pure CPU), you need to switch back from your offloaded
pool to a dedicated GraphQL Java pool before returning the <code>CF</code>. You can achieve this with code like this:</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token class-name">CompletableFuture</span><span class="token generics punctuation" style="color:#393A34">&lt;</span><span class="token generics class-name">String</span><span class="token generics punctuation" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">DataFetchingEnvironment</span><span class="token plain"> env</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token class-name">CompletableFuture</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">supplyAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">getValueFromDb</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">env</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> dbThreadPool </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">handleAsync</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">result</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">exception</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">if</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">exception </span><span class="token operator" style="color:#393A34">!=</span><span class="token keyword" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">throw</span><span class="token plain"> exception</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> result</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> graphqlJavaPool</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>Notice the <code>.handleAsync</code> which doesn't do anything except forwarding the result, but on a
different pool (<code>graphqlJavaPool</code>).</p>
<p>This way you have different pools for different kind of work (one for CPU bound GraphQL Java work and one
for multiple ones for IO bound work), which can be configured and monitored independently.</p>
<h1>In a fully reactive system</h1>
<p>If your system is fully reactive your <code>DataFetcher</code> will more look like this</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token class-name">CompletableFuture</span><span class="token generics punctuation" style="color:#393A34">&lt;</span><span class="token generics class-name">String</span><span class="token generics punctuation" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">DataFetchingEnvironment</span><span class="token plain"> env</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">callAnotherServiceNonBlocking</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">env</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// returns CompletableFuture</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>The code above could be implemented via <a href="https://github.com/AsyncHttpClient/async-http-client" target="_blank" rel="noopener noreferrer" class="">Async Http Client</a>
or <a href="https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-client" target="_blank" rel="noopener noreferrer" class="">WebFlux WebClient</a>.
Both provide fully reactive HTTP clients.</p>
<p>Because the code is non blocking there is no need to offload anything on a dedicated Thread pool to avoid blocking
GraphQL Java.</p>
<p>You still might want to consider using a dedicated GraphQL Java pool as you otherwise would use
Threads which are dedicated to IO. How much this is really relevant depends highly on your use case.</p>
<p>For example <code>Async Http Client</code> (<code>AHC</code>) uses by default 2 * #cores (this value comes actually from Netty) Threads. If you
don't use a dedicated Thread Pool for GraphQL Java you might encounter situations under load where all <code>AHC</code>
Threads are either busy or blocked by GraphQL Java code and as a result your system is not as performant as it
could be. Normally only load tests in production like environments can show the relevance of different Thread pools.</p>
<h1>Feedback or questions</h1>
<p>We use <a href="https://github.com/graphql-java/graphql-java/discussions" target="_blank" rel="noopener noreferrer" class="">GitHub Discussions</a> for general feedback and questions.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Building efficient data fetchers by looking ahead]]></title>
            <link>https://graphql-java.com/blog/deep-dive-data-fetcher-results</link>
            <guid>https://graphql-java.com/blog/deep-dive-data-fetcher-results</guid>
            <pubDate>Thu, 11 Apr 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[Today we are looking into the graphql.schema.DataFetchingFieldSelectionSet and graphql.execution.DataFetcherResult objects as means]]></description>
            <content:encoded><![CDATA[<p>Today we are looking into the <code>graphql.schema.DataFetchingFieldSelectionSet</code> and <code>graphql.execution.DataFetcherResult</code> objects as means
to build efficient data fetchers.</p>
<h1>The scenario</h1>
<p>But first lets set the scene. Imagine we have a system that can return <code>issues</code> and the <code>comments</code> on those <code>issues</code></p>
<div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token object">issues</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">key</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">summary</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token object">comments</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">text</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>Nominally we would have a <code>graphql.schema.DataFetcher</code> on <code>issues</code> that returns a list of issues and one on the field <code>comments</code> that returns the list of comments
for each issue <code>source</code> object.</p>
<p>As you can see this naively creates an <em>N+1 problem</em> where we need to fetch data multiple times, one for each <code>issue</code> object in isolation.</p>
<p>We could attack this using the <code>org.dataloader.DataLoader</code> pattern but there is another way which will discuss in this article.</p>
<h1>Look ahead via DataFetchingFieldSelectionSet</h1>
<p>The data fetcher behind the <code>issues</code> field is able to look ahead and see what sub fields are being asked for.  In this case it knows that <code>comments</code> are being asked
for and hence it could prefetch them at the same time.</p>
<p><code>graphql.schema.DataFetchingEnvironment#getSelectionSet</code> (aka <code>graphql.schema.DataFetchingFieldSelectionSet</code>) can be used by data fetcher code to get the selection set of fields for a given parent field.</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token class-name">DataFetcher</span><span class="token plain"> issueDataFetcher </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> environment </span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">DataFetchingFieldSelectionSet</span><span class="token plain"> selectionSet </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> environment</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getSelectionSet</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">selectionSet</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">contains</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"comments"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">List</span><span class="token generics punctuation" style="color:#393A34">&lt;</span><span class="token generics class-name">IssueAndCommentsDTO</span><span class="token generics punctuation" style="color:#393A34">&gt;</span><span class="token plain"> data </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">getAllIssuesWithComments</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">environment</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> selectionSet</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getFields</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> data</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">List</span><span class="token generics punctuation" style="color:#393A34">&lt;</span><span class="token generics class-name">IssueDTO</span><span class="token generics punctuation" style="color:#393A34">&gt;</span><span class="token plain"> issues </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">getAllIssuesWitNoComments</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">environment</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> issues</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>Imagine this is backed by an SQL system we might be able to use this field look ahead to produce the following SQL</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">SELECT</span><span class="token plain"> Issues</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">Key</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Issues</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">Summary</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> Comments</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">Text</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">FROM</span><span class="token plain"> Issues</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">INNER</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">JOIN</span><span class="token plain"> Comments </span><span class="token keyword" style="color:#00009f">ON</span><span class="token plain"> Issues</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">CommentID</span><span class="token operator" style="color:#393A34">=</span><span class="token plain">Comments</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">ID</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>So we have looked ahead and returned different data depending on the field sub selection.  We have made our system more efficient by using look ahead
to fetch data just the <code>1</code> time and not <code>N+1</code> times.</p>
<h1>Code Challenges</h1>
<p>The challenge with this code design is that the shapes of the returned data is now field sub selection specific.  We needed a <code>IssueAndCommentsDTO</code> for one sub selection
path and a simpler <code>IssueDTO</code> for another path.</p>
<p>With enough paths this becomes problematic as it adds new DTO classes per path and makes out child data fetchers more complex</p>
<p>Also the standard graphql pattern is that the returned object becomes the <code>source</code> ie. <code>graphql.schema.DataFetchingEnvironment#getSource</code> of the next child
data fetcher.  But we might have pre fetched data that is needed 2 levels deep and this is challenging to do since each data fetcher would need to capture and copy
that data down to the layers below via new TDOs classes per level.</p>
<h1>Passing Data and Local Context</h1>
<p>GraphQL Java offers a capability that helps with this pattern.  GraphQL Java goes beyond what the reference graphql-js system gives you where the object you
returned is automatically the <code>source</code> of the next child fetcher and that's all it can be.</p>
<p>In GraphQL Java you can use well known <code>graphql.execution.DataFetcherResult</code> to return three sets of values</p>
<ul>
<li class=""><code>data</code>  - which will be used as the source on the next set of sub fields</li>
<li class=""><code>errors</code> - allowing you to return data as well as errors</li>
<li class=""><code>localContext</code> - which allows you to pass down field specific context</li>
</ul>
<p>When the engine sees the <code>graphql.execution.DataFetcherResult</code> object, it automatically unpacks it and handles it three classes of data in specific ways.</p>
<p>In our example case we will be use <code>data</code> and <code>localContext</code> to communicate between fields easily.</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token class-name">DataFetcher</span><span class="token plain"> issueDataFetcher </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> environment </span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">DataFetchingFieldSelectionSet</span><span class="token plain"> selectionSet </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> environment</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getSelectionSet</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">selectionSet</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">contains</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"comments"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">List</span><span class="token generics punctuation" style="color:#393A34">&lt;</span><span class="token generics class-name">IssueAndCommentsDTO</span><span class="token generics punctuation" style="color:#393A34">&gt;</span><span class="token plain"> data </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">getAllIssuesWithComments</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">environment</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> selectionSet</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getFields</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">List</span><span class="token generics punctuation" style="color:#393A34">&lt;</span><span class="token generics class-name">IssueDTO</span><span class="token generics punctuation" style="color:#393A34">&gt;</span><span class="token plain"> issues </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> data</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">stream</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">map</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">dto </span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token plain"> dto</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getIssue</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">collect</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">toList</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">Map</span><span class="token generics punctuation" style="color:#393A34">&lt;</span><span class="token generics class-name">IssueDTO</span><span class="token generics punctuation" style="color:#393A34">,</span><span class="token generics"> </span><span class="token generics class-name">List</span><span class="token generics punctuation" style="color:#393A34">&lt;</span><span class="token generics class-name">CommentDTO</span><span class="token generics punctuation" style="color:#393A34">&gt;</span><span class="token generics punctuation" style="color:#393A34">&gt;</span><span class="token plain"> preFetchedComments </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">mkMapOfComments</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">data</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token class-name">DataFetcherResult</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">newResult</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">data</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">issues</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">localContext</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">preFetchedComments</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">build</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">List</span><span class="token generics punctuation" style="color:#393A34">&lt;</span><span class="token generics class-name">IssueDTO</span><span class="token generics punctuation" style="color:#393A34">&gt;</span><span class="token plain"> issues </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">getAllIssuesWitNoComments</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">environment</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token class-name">DataFetcherResult</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">newResult</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">data</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">issues</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">                </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">build</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>If you look now you will see that our data fetcher returns a <code>DataFetcherResult</code> object that contains <code>data</code> for the child data fetchers which is the
list of <code>issueDTO</code> objects as per usual.  It will be their <code>source</code> object when they run.</p>
<p>It also passes down field specific <code>localContext</code> which is the pre-fetched comment data.</p>
<p>Unlike the global context object, local context objects are passed down from a specific field to its children and are not shared across to peer fields.  This means
a parent field has a "back channel" to talk to the child fields without having to "pollute" the DTO source objects with that information and it is "local" in the sense
that it given only to this field and its children and not any other field in the query.</p>
<p>Now lets look at the <code>comments</code> data fetcher and how it consumes this back channel of data</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token class-name">DataFetcher</span><span class="token plain"> commentsDataFetcher </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> environment </span><span class="token operator" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">IssueDTO</span><span class="token plain"> issueDTO </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> environment</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getSource</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">Map</span><span class="token generics punctuation" style="color:#393A34">&lt;</span><span class="token generics class-name">IssueDTO</span><span class="token generics punctuation" style="color:#393A34">,</span><span class="token generics"> </span><span class="token generics class-name">List</span><span class="token generics punctuation" style="color:#393A34">&lt;</span><span class="token generics class-name">CommentDTO</span><span class="token generics punctuation" style="color:#393A34">&gt;</span><span class="token generics punctuation" style="color:#393A34">&gt;</span><span class="token plain"> preFetchedComments </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> environment</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">getLocalContext</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token class-name">List</span><span class="token generics punctuation" style="color:#393A34">&lt;</span><span class="token generics class-name">CommentDTO</span><span class="token generics punctuation" style="color:#393A34">&gt;</span><span class="token plain"> commentDTOS </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> preFetchedComments</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">get</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">issueDTO</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token class-name">DataFetcherResult</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">newResult</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">data</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">commentDTOS</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">localContext</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">preFetchedComments</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">build</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>Notice how it got the <code>issueDTO</code> as its source object as expected but it also got a local context object which is our pre-fetched comments.  It can choose
to pass on new local context OR if it passes nothing then the previous value will bubble down to the next lot of child fields.  So you can think of <code>localContext</code>
as being inherited unless a fields data fetcher explicitly overrides it.</p>
<p>Our data fetcher is a bit more complex because of the data pre-fetching but 'localContext' allows us a nice back channel to pass data without modifying our DTO objects
that are being used in more simple data fetchers.</p>
<h1>Passing back Errors or Data or Both</h1>
<p>For completeness we will show you that you can also pass down errors or data or local context or all of them at once.</p>
<p>It is perfectly valid to fetch data in graphql and to ALSO send back errors.  Its not common but its valid. Some data is better than no data.</p>
<div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token class-name">GraphQLError</span><span class="token plain"> error </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">mkSpecialError</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Its Tuesday"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token class-name">DataFetcherResult</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">newResult</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">data</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">commentDTOS</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">build</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[GraphQL Deep Dive Part 1 - merged fields]]></title>
            <link>https://graphql-java.com/blog/deep-dive-merged-fields</link>
            <guid>https://graphql-java.com/blog/deep-dive-merged-fields</guid>
            <pubDate>Tue, 22 Jan 2019 00:00:00 GMT</pubDate>
            <description><![CDATA[Welcome to the new series "GraphQL deep dive" where we will explore advanced or unknown GraphQL topics. The plan is to discuss things mostly in a language and implementation neutral way, even if it is hosted on graphql-java.com.]]></description>
            <content:encoded><![CDATA[<p>Welcome to the new series "GraphQL deep dive" where we will explore advanced or unknown GraphQL topics. The plan is to discuss things mostly in a language and implementation neutral way, even if it is hosted on graphql-java.com.</p>
<h1>Merged Fields</h1>
<p>First thing we are looking at is "merged fields".</p>
<p>GraphQL allows for a field to be declared multiple times in a query as long as it can be merged.</p>
<p>Valid GraphQL queries are:</p>
<div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">foo</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">foo</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"123"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"123"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"123"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"123"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">id</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"123"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">name</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"123"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">id</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">name</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>Each of these queries will result in a result with just one "foo" key, not two or three.</p>
<p>Invalid Queries are:</p>
<div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">foo</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"123"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"123"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"456"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token attr-name" style="color:#00a4db">id2</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"123"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"123"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token attr-name" style="color:#00a4db">foo</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token property" style="color:#36acaa">foo2</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>The reason why they are not valid, is because the fields are different: in the first two examples the arguments differ and the third query actually has two different fields under the same key.</p>
<h1>Motivation</h1>
<p>The examples so far don't seem really useful, but it all makes sense when you add fragments:</p>
<div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token operator" style="color:#393A34">...</span><span class="token fragment function" style="color:#d73a49">myFragment1</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token operator" style="color:#393A34">...</span><span class="token fragment function" style="color:#d73a49">myFragment2</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">fragment</span><span class="token plain"> </span><span class="token fragment function" style="color:#d73a49">myFragment1</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">on</span><span class="token plain"> </span><span class="token class-name">Query</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"123"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">name</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">fragment</span><span class="token plain"> </span><span class="token fragment function" style="color:#d73a49">myFragment2</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">on</span><span class="token plain"> </span><span class="token class-name">Query</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"123"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">url</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div></code></pre></div></div>
<p>Fragments are designed to be written by different parties (for example different components in a UI) which should not know anything about each other. Requiring that every field can only be declared once would make this objective unfeasible.</p>
<p>But by allowing fields merging, as long as the fields are the same, allows fragments to be authored in an independent way from each other.</p>
<h1>Rules when fields can be merged</h1>
<p>The specific details when fields can be merged are written down in <a href="https://facebook.github.io/graphql/draft/#sec-Field-Selection-Merging" target="_blank" rel="noopener noreferrer" class="">Field Selection Merging</a> in the spec.</p>
<p>The rules are what you would expect in general and they basically say that fields must be the same. The following examples are taken from the spec and they are all valid:</p>
<div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">fragment</span><span class="token plain"> </span><span class="token fragment function" style="color:#d73a49">mergeIdenticalFields</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">on</span><span class="token plain"> </span><span class="token class-name">Dog</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">name</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">name</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">fragment</span><span class="token plain"> </span><span class="token fragment function" style="color:#d73a49">mergeIdenticalAliasesAndFields</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">on</span><span class="token plain"> </span><span class="token class-name">Dog</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token attr-name" style="color:#00a4db">otherName</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token property" style="color:#36acaa">name</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token attr-name" style="color:#00a4db">otherName</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token property" style="color:#36acaa">name</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">fragment</span><span class="token plain"> </span><span class="token fragment function" style="color:#d73a49">mergeIdenticalFieldsWithIdenticalArgs</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">on</span><span class="token plain"> </span><span class="token class-name">Dog</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">doesKnowCommand</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">dogCommand</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">SIT</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">doesKnowCommand</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">dogCommand</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">SIT</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">fragment</span><span class="token plain"> </span><span class="token fragment function" style="color:#d73a49">mergeIdenticalFieldsWithIdenticalValues</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">on</span><span class="token plain"> </span><span class="token class-name">Dog</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">doesKnowCommand</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">dogCommand</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$dogCommand</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">doesKnowCommand</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">dogCommand</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token variable" style="color:#36acaa">$dogCommand</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>The most complex case happens when you have fields in fragments on different types:</p>
<div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">fragment</span><span class="token plain"> </span><span class="token fragment function" style="color:#d73a49">safeDifferingFields</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">on</span><span class="token plain"> </span><span class="token class-name">Pet</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token operator" style="color:#393A34">...</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">on</span><span class="token plain"> </span><span class="token class-name">Dog</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attr-name" style="color:#00a4db">volume</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token property" style="color:#36acaa">barkVolume</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token operator" style="color:#393A34">...</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">on</span><span class="token plain"> </span><span class="token class-name">Cat</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attr-name" style="color:#00a4db">volume</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token property" style="color:#36acaa">meowVolume</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>This is normally invalid because <code>volume</code> is an alias for two different fields <code>barkVolume</code> and <code>meowVolume</code> but because only one of the some are actually resolved and they both return a value of the same type (we assume here that <code>barkVolume</code> and <code>meowVolume</code> are both of the same type) it is valid.</p>
<div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">fragment</span><span class="token plain"> </span><span class="token fragment function" style="color:#d73a49">safeDifferingArgs</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">on</span><span class="token plain"> </span><span class="token class-name">Pet</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token operator" style="color:#393A34">...</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">on</span><span class="token plain"> </span><span class="token class-name">Dog</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property-query">doesKnowCommand</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">dogCommand</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">SIT</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token operator" style="color:#393A34">...</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">on</span><span class="token plain"> </span><span class="token class-name">Cat</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property-query">doesKnowCommand</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">catCommand</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">JUMP</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>This is again a valid case because even if the first <code>doesKnowCommand</code> has a different argument than the second <code>doesKnowCommand</code> only one of them is actually resolved.</p>
<p>In the next example <code>someValue</code> has different types (we assume that <code>nickname</code> is a <code>String</code> and <code>meowVolume</code> is a <code>Int</code>) and therefore the query is not valid:</p>
<div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">fragment</span><span class="token plain"> </span><span class="token fragment function" style="color:#d73a49">conflictingDifferingResponses</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">on</span><span class="token plain"> </span><span class="token class-name">Pet</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token operator" style="color:#393A34">...</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">on</span><span class="token plain"> </span><span class="token class-name">Dog</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attr-name" style="color:#00a4db">someValue</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token property" style="color:#36acaa">nickname</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token operator" style="color:#393A34">...</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">on</span><span class="token plain"> </span><span class="token class-name">Cat</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attr-name" style="color:#00a4db">someValue</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token property" style="color:#36acaa">meowVolume</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<h1>Sub selections and directives</h1>
<p>One thing to keep in my mind is that the sub selections of fields are merged together. For example here <code>foo</code> is resolved once and than <code>id</code> and <code>name</code> is resolved.</p>
<div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"123"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">id</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"123"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">name</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>This query is the same as:</p>
<div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"123"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">id</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">name</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>The second thing to keep in mind is that different directives can be on each field:</p>
<div class="language-graphql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-graphql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"123"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token directive function" style="color:#d73a49">@myDirective</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">id</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property-query">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token attr-name" style="color:#00a4db">id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"123"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token directive function" style="color:#d73a49">@myOtherDirective</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">name</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>So if you want to know all directives for the current field you are resolving you actually need to look at all of the merged fields from the query.</p>
<h1>Merged fields in graphql-js and GraphQL Java</h1>
<p>In graphql-js merged fields are relevant when you implement a resolver and you need access to the specific ast field of the query. The <code>info</code> objects has a property <code>fieldNodes</code> which gives you access to all ast fields which are merged together.</p>
<p>In GraphQL Java depending on the version you are running you have <code>List&lt;Field&gt; getFields()</code> in the <code>DataFetcherEnvironment</code> or for GraphQL Java newer than <code>12.0</code> you have also <code>MergedField getMergedField()</code> which is the recommend way to access all merged fields.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[First release of GraphQL Java Spring]]></title>
            <link>https://graphql-java.com/blog/graphql-java-spring-support</link>
            <guid>https://graphql-java.com/blog/graphql-java-spring-support</guid>
            <pubDate>Sat, 01 Dec 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[Spring for GraphQL is the official and current Spring integration. The integration is a collaboration between the Spring and GraphQL Java teams, and is maintained by the Spring team.]]></description>
            <content:encoded><![CDATA[<div class="theme-admonition theme-admonition-caution admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>caution</div><div class="admonitionContent_BuS1"><p><strong><a href="https://spring.io/projects/spring-graphql" target="_blank" rel="noopener noreferrer" class="">Spring for GraphQL</a> is the official and current Spring integration.</strong> The integration is a collaboration between the Spring and GraphQL Java teams, and is maintained by the Spring team.</p><p><a href="https://www.graphql-java.com/blog/spring-for-graphql" target="_blank" rel="noopener noreferrer" class="">We recommend using Spring for GraphQL</a>, rather than the older Spring project mentioned in this blog post.</p><p>See our <a href="https://www.graphql-java.com/tutorials/getting-started-with-spring-boot" target="_blank" rel="noopener noreferrer" class="">Spring for GraphQL</a> tutorial for how to get started.</p></div></div>
<p>We are happy to release the first version of the GraphQL Java Spring (Boot) project.</p>
<p>As <a href="https://www.graphql-java.com/blog/graphql-java-aims-to-be-used-directly/" target="_blank" rel="noopener noreferrer" class="">described before</a> this project
complements the GraphQL Java core project if you build a fully operational GraphQL server with Spring.</p>
<p>Currently it supports GET and POST requests and allows for some basic customization.</p>
<p>In future we are looking into supporting more advanced features like file upload or subscriptions.</p>
<p>As always contributions are more than welcome and we are hoping to grow this project together with the
community: please open a <a href="https://github.com/graphql-java/graphql-java-spring/issues/new" target="_blank" rel="noopener noreferrer" class="">new issue</a> or leave a comment on <a href="https://spectrum.chat/graphql-java" target="_blank" rel="noopener noreferrer" class="">spectrum chat</a> about your wishes.</p>
<p>More details on how to use it can be found on the github page: <a href="https://github.com/graphql-java/graphql-java-spring" target="_blank" rel="noopener noreferrer" class="">https://github.com/graphql-java/graphql-java-spring</a></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Introducing graphql-java-extended-scalars]]></title>
            <link>https://graphql-java.com/blog/introducing-extended-scalars</link>
            <guid>https://graphql-java.com/blog/introducing-extended-scalars</guid>
            <pubDate>Sat, 24 Nov 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[One of the most common questions we get in GraphQL Java land is "can we have a datetime scalar".]]></description>
            <content:encoded><![CDATA[<p>One of the most common questions we get in GraphQL Java land is "can we have a datetime scalar".</p>
<p>This is not defined by the graphql specification per se so we are reluctant to add it to the core library and then have it turn
up later as an officially specified type.</p>
<p>But it really is a badly needed type in your GraphQL arsenal and hence <code>graphql-java-extended-scalars</code> was born</p>
<p><a href="https://github.com/graphql-java/graphql-java-extended-scalars" target="_blank" rel="noopener noreferrer" class="">https://github.com/graphql-java/graphql-java-extended-scalars</a></p>
<p>This will be a place where we can add non standard but useful extensions to GraphQL Java.</p>
<p>The major scalars we have added on day one are</p>
<ul>
<li class="">The aforementioned DateTime scalar as well as a Date and Time scalar</li>
<li class="">A Object scalar or sometimes know as a JSON scalar that allows a map of values to be returned as a scalar value</li>
<li class="">Some numeric scalars that constrain the values allowed such as <code>PositiveInt</code></li>
<li class="">A Regex scalar that allows a string to fit a regular expression</li>
<li class="">A Url scalar that produces <code>java.net.URL</code> objects at runtime</li>
<li class="">And finally an aliasing technique that allows you to create more meaningfully named scalar values</li>
</ul>
<p>We hope you find them useful.</p>
<p>Cheers,</p>
<p>Brad</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[GraphQL Java aims to be used directly]]></title>
            <link>https://graphql-java.com/blog/graphql-java-aims-to-be-used-directly</link>
            <guid>https://graphql-java.com/blog/graphql-java-aims-to-be-used-directly</guid>
            <pubDate>Sat, 10 Nov 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[There seems to be a common misconception about GraphQL Java: that you should not use it directly,]]></description>
            <content:encoded><![CDATA[<p>There seems to be a common misconception about GraphQL Java: that you should not use it directly,
but rather use another library build on top of it.</p>
<p>We think it is important to make it clear, that this is not the case: GraphQL Java aims to be a library used directly
without any additionally abstraction on top. It was always build with this goal in mind.</p>
<p>To be fair: we didn't do a very good job so far to make that clear. For example up
<a href="https://www.graphql-java.com/blog/moving-projects/" target="_blank" rel="noopener noreferrer" class="">until recently</a> we hosted several other projects which
provided abstractions on top of GraphQL Java. This was because of historical reasons and we didn't give any
guidance on when to use what. There are also currently more tutorials out there which don't use GraphQL Java directly
compared to tutorials which do.</p>
<p>The other reason people might think that GraphQL Java is not suitable is because the <a href="https://github.com/graphql-java/graphql-java" target="_blank" rel="noopener noreferrer" class="">core project</a>
doesn't provide any easy way to get a full service with HTTP endpoint up and running.
And the existing third party projects providing for example Spring Boot support
are adding abstractions.</p>
<p>The core project doesn't deal with any form of HTTP or JSON specific things and has on purpose basically no
dependencies at all. This will not change, but we recognize the need for having an easy way to get a
full service up and running. This is why we are currently working on first class Spring (Boot) support.</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>Update: You can now use <a href="https://docs.spring.io/spring-graphql/reference/" target="_blank" rel="noopener noreferrer" class="">Spring for GraphQL</a>, the official GraphQL integration. It's a collaboration between the Spring and GraphQL Java teams. See our <a href="https://www.graphql-java.com/tutorials/getting-started-with-spring-boot/" target="_blank" rel="noopener noreferrer" class="">quick start tutorial</a>.</p></div></div>
<p>This is not done yet, but it will provide an easy way to integrate GraphQL Java in a Spring (Boot) application
without adding any abstraction on top of GraphQL Java. It will also be extended over time with more advanced features
like Apollo Defer support.</p>
<p>To recap:</p>
<ol>
<li class="">GraphQL Java aims to be a first class library used directly</li>
<li class="">The <a href="https://github.com/graphql-java/graphql-java" target="_blank" rel="noopener noreferrer" class="">GraphQL Java core project</a> doesn't deal with HTTP/JSON and will continue not do it</li>
<li class="">The <a href="https://github.com/graphql-java/graphql-java-spring" target="_blank" rel="noopener noreferrer" class="">GraphQL Java Spring project</a> will complement
the core project in providing comprehensive Spring (Boot) support</li>
</ol>
<p>Cheers,</p>
<p>Andi</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[About breaking changes and Long-term support]]></title>
            <link>https://graphql-java.com/blog/breaking-changes-and-lts</link>
            <guid>https://graphql-java.com/blog/breaking-changes-and-lts</guid>
            <pubDate>Sat, 20 Oct 2018 00:00:00 GMT</pubDate>
            <description><![CDATA[We are releasing new major versions of GraphQL Java roughly every 2 months. They are major versions because we break the API in it. We do it regularly and we prioritize clean code including good naming and design very high. Actually higher than API stability.]]></description>
            <content:encoded><![CDATA[<p>We are releasing new major versions of GraphQL Java roughly every 2 months. They are major versions because we break the API in it. We do it regularly and we prioritize clean code including good naming and design very high. Actually higher than API stability.</p>
<p>We do that because we are optimizing for long-term growth: GraphQL Java is 3 1/2 years old and it is just getting started. This means more people will be positively affected from a better experience compared to the ones who need to refactor.</p>
<p>We do it also because of resource constraints: we are an open source private run project with limited time and resources. We can’t afford maintaining a badly designed project in the long-term. Every bad design, every bad naming makes adding features and adopting to new requirements harder, more time consuming and more unlikely. We also want to make external contributions as easy as possible because we can’t do it all ourself.</p>
<p>The last reason is personal and it is about fun. I don’t wanna maintain a badly designed project. I need to have fun if I wanna continue to invest a large amount of private time in GraphQL Java.</p>
<p>Does that mean we just refactor as crazy and break everything all the time? No it doesn’t. We follow some rules about breaking changes:</p>
<ul>
<li class="">
<p>We never take a functionality away. We deprecate things and make it clear that we don’t really support them anymore, but we don’t take them away without a clear alternative.</p>
</li>
<li class="">
<p>We try to favor simple breaking changes the compiler will catch. For example renaming a method is such a simple change.</p>
</li>
<li class="">
<p>We try to document in our release notes every breaking change clearly.</p>
</li>
<li class="">
<p>Even if we prioritize clean design higher than API stability in general we always weigh the benefits of the change vs the cost of adapting to it. There is no hard rule to that, but we always ask: is it worth it?</p>
</li>
</ul>
<p>But  we understand that not every Organization allows for regular updating major versions of GraphQL Java. This is why we started to maintain a Long-term support (LTS) version of GraphQL Java: 9.x. We will continue to back port all bug fixes to 9.x for some time and we will announce when we will switch to a new LTS version.</p>
<p>It is not clear yet how long this time span will be and it depends also on your feedback. <strong>Please contribute to this <a href="https://spectrum.chat/thread/196ab67d-2770-4f3f-b1b3-b056ecb3a2e1" target="_blank" rel="noopener noreferrer" class="">spectrum thread</a> and let us know what suits you best.</strong> If you have special needs and you don’t wanna discuss it in public you can also reach us via <a href="https://www.graphql-java.com/contact/" target="_blank" rel="noopener noreferrer" class="">contact form</a>.</p>
<p>Cheers,</p>
<p>Andi</p>]]></content:encoded>
        </item>
    </channel>
</rss>