<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Jonas Antvorskov</title>
    <description>The latest articles on Forem by Jonas Antvorskov (@janitminds).</description>
    <link>https://forem.com/janitminds</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F507999%2Fe9a9924f-c1ba-4b40-bcac-426b694dceed.png</url>
      <title>Forem: Jonas Antvorskov</title>
      <link>https://forem.com/janitminds</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/janitminds"/>
    <language>en</language>
    <item>
      <title>Errors are results</title>
      <dc:creator>Jonas Antvorskov</dc:creator>
      <pubDate>Fri, 15 Jan 2021 11:01:57 +0000</pubDate>
      <link>https://forem.com/itminds/errors-are-results-5cn</link>
      <guid>https://forem.com/itminds/errors-are-results-5cn</guid>
      <description>&lt;h1&gt;
  
  
  Errors, Faults &amp;amp; Failures
&lt;/h1&gt;

&lt;p&gt;When writing a server, errors are inevitable, but a distinction should be made between errors caused by things outside the client's control, such as your database crashing - I'll refer to these as Faults. Errors caused by things that are within the client's control, such as attempting to get an entity the client doesn't have access to - I'll refer to these as Failures.&lt;/p&gt;

&lt;p&gt;Faults are in their nature temporal and fleeting, whether through automatic corrections made by the system itself, such as the database restarting, or fixes manually implemented by the maintainers of the system. This means that they can safely be omitted from your &lt;em&gt;GraphQL&lt;/em&gt; schema because when they occur, the client has no meaningful course of action to mitigate the problem other than waiting for the issue to be fixed.&lt;/p&gt;

&lt;p&gt;Failures, on the other hand, are persistent when attempting to get an entity the client doesn't have access to, the client does have meaningful courses of action to correct the issue, for example: not requesting the resource again or informing the user they don't have access. Because of this, it makes sense to treat these failures the same as you would a result. This means that any failures that can occur when resolving a field in a &lt;em&gt;GraphQL&lt;/em&gt; server should be declared as part of a union type expressing the possible value types of a given field.&lt;/p&gt;

&lt;h1&gt;
  
  
  Making Failures Type-safe
&lt;/h1&gt;

&lt;p&gt;In order to make failures as results type-safe without having to add extensive logic around handling errors to the majority of functions within your &lt;em&gt;GraphQL&lt;/em&gt; server, while making sure that all failure results are handled.&lt;/p&gt;

&lt;p&gt;I suggest using a &lt;a href="https://doc.rust-lang.org/rust-by-example/error/result.html"&gt;&lt;em&gt;Result&lt;/em&gt; pattern inspired by &lt;em&gt;Rust&lt;/em&gt;&lt;/a&gt;. This pattern can be used to great effect in &lt;em&gt;TypeScript&lt;/em&gt;. It allows us to have both the successful result typed and any possible failures to be typed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;getUserById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;AsyncResult&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserDataModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NotFoundError&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;InvalidIdentifierError&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;identifierService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;andThenAsync&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an example of what the Result pattern looks like, when in use. This is a function on a user service that attempts to fetch a user. First, the &lt;code&gt;identifierService&lt;/code&gt; parses the given string ID into the correct format for the underlying service. This results in an object of type &lt;code&gt;Result&amp;lt;Identifier&amp;lt;'User'&amp;gt;, InvalidIdentifierError&amp;gt;&lt;/code&gt; if the ID is valid, the result object contains that parsed ID value. If it is invalid, it contains the &lt;code&gt;InvalidIdentifierError&lt;/code&gt;. We can then call &lt;code&gt;andThenAsync&lt;/code&gt; on the result object. This is essentially a map function that is only invoked if the result isn't an error and must return a new result object. The lambda function in this example returns the type &lt;code&gt;Result&amp;lt;UserDataModel, NotFoundError&amp;gt;&lt;/code&gt;, this type is merged with the result type returned by the &lt;code&gt;identifierService&lt;/code&gt; into the final return type of the function. &lt;/p&gt;

&lt;p&gt;All of this simplifies the way failures are handled because we only need to care about them when we actually want to process the errors specifically. If we don't have any way to remedy the issue on the server, it should ultimately be returned to the client as a result, and if we don't encounter an error, we can just map an intermediate result to a new result.&lt;/p&gt;

&lt;p&gt;When generating a new result, the pattern is also trivial to use. The following is an example of how the &lt;code&gt;identifierService.user.parse(id)&lt;/code&gt; method is implemented:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;idMatcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;(\w&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)\/(&lt;/span&gt;&lt;span class="sr"&gt;0|&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;1-9&lt;/span&gt;&lt;span class="se"&gt;][&lt;/span&gt;&lt;span class="sr"&gt;0-9&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Identifier&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Prefix&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;InvalidIdentifierError&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;idMatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;idMatcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;idMatch&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;idMatch&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prefix&lt;/span&gt;
      &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Identifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;idMatch&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
      &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;InvalidIdentifierError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the string is matched against a regex and a prefix. If it doesn't match, &lt;code&gt;Result.error()&lt;/code&gt; is called, and generates an error result. If it does match, &lt;code&gt;Result.ok()&lt;/code&gt; is called to generate a successful result.&lt;/p&gt;

&lt;h1&gt;
  
  
  Declaring the Schema
&lt;/h1&gt;

&lt;p&gt;When declaring fields on the schema where the field should be resolved with the &lt;em&gt;Result&lt;/em&gt; pattern described above, the field should resolve to a union type. As an example, this is how this would be declared using &lt;em&gt;GraphQL Nexus&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UserResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;unionType&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UserResponse&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;The type of the possible results from the user query&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;members&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GraphQLNotFoundError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GraphQLInvalidIdentifierError&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolveType&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;__typename&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, there doesn't seem to be any way to add a resolver to the union type, so we can pass it a &lt;code&gt;Result&lt;/code&gt; type object and let it unpack the object to the underlying value, thus we have to add a method to the &lt;code&gt;Result&lt;/code&gt; class which should be called on the &lt;code&gt;Result&lt;/code&gt; object returned to a field that should resolve to a union type like this.&lt;/p&gt;

&lt;p&gt;A field that resolves to a union type like this in &lt;em&gt;GraphQL Nexus&lt;/em&gt; would be declared like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;idArg&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getUserById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;collect&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the &lt;code&gt;.collect()&lt;/code&gt; function call unwraps the &lt;code&gt;AsyncResult&amp;lt;UserDataModel, NotFoundError | InvalidIdentifierError&amp;gt;&lt;/code&gt; type object to a &lt;code&gt;Promise&amp;lt;UserDataModel | NotFoundError | InvalidIdentifierError&amp;gt;&lt;/code&gt; type object.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Treating failures as results and declaring them as return options on the field level, makes it apparent and encourages the consumer of your &lt;em&gt;GraphQL&lt;/em&gt; API to handle the failures that can be encountered for any given field, and it localizes the data to where it belongs in the result data structure, instead of having it in the &lt;code&gt;errors&lt;/code&gt; array on the request-response with a path to where the error originated.&lt;/p&gt;

&lt;h1&gt;
  
  
  Resources
&lt;/h1&gt;

&lt;p&gt;A demo project utilizing all the techniques described can be found &lt;a href="https://github.com/IT-Minds-ApS/graphql-nexus-demo"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>typescript</category>
      <category>node</category>
      <category>nexus</category>
    </item>
    <item>
      <title>GraphQL as a typesafe contract for your domain!</title>
      <dc:creator>Jonas Antvorskov</dc:creator>
      <pubDate>Fri, 27 Nov 2020 09:44:15 +0000</pubDate>
      <link>https://forem.com/itminds/graphql-as-a-typesafe-contract-for-your-domain-4bik</link>
      <guid>https://forem.com/itminds/graphql-as-a-typesafe-contract-for-your-domain-4bik</guid>
      <description>&lt;h1&gt;
  
  
  Building type-safe GraphQL schemas with &lt;em&gt;@nexus/schema&lt;/em&gt; and TypeScript
&lt;/h1&gt;

&lt;p&gt;In this post, I will discuss how &lt;em&gt;@nexus/schema&lt;/em&gt; can be used to construct a typesafe GraphQL schema. I will assume that the reader has a passing familiarity with GraphQL. If interested in learning the basics of GraphQL look up GraphQL's homepage on &lt;a href="https://graphql.org/learn/"&gt;https://graphql.org/learn/&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;When writing type-safe GraphQL implementations based on &lt;em&gt;graphql-js&lt;/em&gt; in the past, the developer always had to take great care to supply the correct types to all resolvers themselves. Providing the correct types was often error prone; you either had to reference a common type export from the consuming and producing resolver, or take great care to track down all consuming and producing resolvers related to a type if it ever changed. &lt;em&gt;@nexus/schema&lt;/em&gt; seeks to make this largely a thing of the past; by combining new type constructors wrapping vanilla &lt;em&gt;graphql-js&lt;/em&gt; type constructors and allowing the developer to supply a few type imports, this allows &lt;em&gt;@nexus/schema&lt;/em&gt; to generate typescript artifacts when you run your schema. This makes it possible to see most type errors you've made in relation to your schema before even having to test it.&lt;/p&gt;

&lt;h1&gt;
  
  
  makeSchema
&lt;/h1&gt;

&lt;p&gt;The &lt;em&gt;makeSchema&lt;/em&gt; function is what ties everything together and makes the magic of &lt;em&gt;@nexus/schema&lt;/em&gt; happen. In order to generate the appropriate type artifacts this function needs to be given the correct configuration, this includes references to all types used by your schema.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;makeSchema&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;schemaTypes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;scalars&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/generated/schema.graphql&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="c1"&gt;// where to save the schema declaration artifact&lt;/span&gt;
    &lt;span class="na"&gt;typegen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/generated/typings.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="c1"&gt;// where to save the typescript schema definitions artifact&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we provide the config with all types used in the schema and instruct &lt;em&gt;@nexus/schema&lt;/em&gt; in where to output the SDL schema artifacts and the typescript typing artifacts, these generated files should ideally not be included in your git repository and should instead be generated ad-hoc in your CI pipeline.&lt;/p&gt;

&lt;p&gt;In the schema configuration you should also provide some configuration for where the Context type can be found for the schema.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;makeSchema&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="p"&gt;...,&lt;/span&gt;
  &lt;span class="na"&gt;typegenAutoConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;sources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./context.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="c1"&gt;// this points to where the RequestContext type can be imported from&lt;/span&gt;
        &lt;span class="na"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ctx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;// the alias the module containing the RequestContext type is given in the schema typings artifact&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;contextType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ctx.RequestContext&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// the path to the RequestContext in the typings artifact&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This instructs &lt;em&gt;@nexus/schema&lt;/em&gt; to import the file './context.ts' which is collocated to the file performing the &lt;code&gt;makeSchema&lt;/code&gt; function call and using the type exported from that module called &lt;code&gt;RequestContext&lt;/code&gt; as the type of the Context parameter for all resolvers in your schema.&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating schema types
&lt;/h1&gt;

&lt;p&gt;Schema types for a &lt;em&gt;@nexus/schema&lt;/em&gt; schema are constructed through the use of a set of constructor methods, each of which takes a config object; containing among other things the name of the type, and an optional description of it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;objectType&lt;/em&gt;:
This function is used for constructing the underlying &lt;em&gt;GraphQLObjectType&lt;/em&gt;. The config must be provided with a &lt;em&gt;definition&lt;/em&gt; function which takes an &lt;em&gt;ObjectDefinitionBlock&lt;/em&gt; parameter. This parameter is what is used to add fields to the type by calling methods named after the type the field should return or by calling &lt;em&gt;field&lt;/em&gt; and providing it with the correct return type of the field. Each of these functions must be provided with the name of the field that they are adding and a config for the field containing a &lt;em&gt;resolve&lt;/em&gt; function, this function becomes typesafe after the type artifacts have been generated. The &lt;em&gt;ObjectDefinitionBlock&lt;/em&gt; is also used to instructing GraphQL that the object type should implement an interface through the use of the &lt;em&gt;implements&lt;/em&gt; method.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;interfaceType&lt;/em&gt;:
The &lt;em&gt;interfaceType&lt;/em&gt; function works much the same as the &lt;em&gt;objectType&lt;/em&gt; function, it is used to construct the underlying GraphQLInterfaceType.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;unionType&lt;/em&gt;:
This function is used to constructing the underlying &lt;em&gt;GraphQLUnionType&lt;/em&gt;. The config for this type must be provided with a &lt;em&gt;definition&lt;/em&gt; function which takes a &lt;em&gt;UnionDefinitionBlock&lt;/em&gt;. This is used to add members to the type through the &lt;em&gt;members&lt;/em&gt; method, and instructing &lt;em&gt;graphql-js&lt;/em&gt; in how to determine which member type a given object, returned to a field that should resolve to the union type, should resolve to.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;extendType&lt;/em&gt;:
This function is used to append an existing object type. It should be given a config containing the type that is being extended and a &lt;em&gt;definition&lt;/em&gt; function like &lt;em&gt;objectType&lt;/em&gt; which adds any new fields.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;queryField&lt;/em&gt;:
This is a decorated version of the &lt;em&gt;extendType&lt;/em&gt; function which only acts on the &lt;em&gt;Query&lt;/em&gt; type and thus is only given the &lt;em&gt;definition&lt;/em&gt; function. It should be used to declare any queries possible in the schema.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;mutationField&lt;/em&gt;:
This is a decorated version of the &lt;em&gt;extendType&lt;/em&gt; function which only acts on the &lt;em&gt;Mutation&lt;/em&gt; type and thus is only given the &lt;em&gt;definition&lt;/em&gt; function. It should be used to declare any mutations possible in the schema.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;enumType&lt;/em&gt;:
The &lt;em&gt;enumType&lt;/em&gt; function is used to construct the GraphQLEnumType. This function must be given the set of members of the enum through the &lt;em&gt;members&lt;/em&gt; property.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;scalarType&lt;/em&gt;:
The &lt;em&gt;scalarType&lt;/em&gt; function is used to construct scalar types. These types have special handling, if &lt;em&gt;asNexusMethod&lt;/em&gt; is set to true in their config they will become available on the &lt;em&gt;ObjectDefinitionBlock&lt;/em&gt; type. The config should also specify 3 functions:

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;parseLiteral&lt;/em&gt;:
This function is used to parse the value of the field if written in the SDL.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;parseValue&lt;/em&gt;:
This function is used to parse the value of the field if given as a parameter.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;serialize&lt;/em&gt;:
This function is used to transform the value given to the field to a scalar value to be transferred to the client.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  rootTyping
&lt;/h2&gt;

&lt;p&gt;You should only specify the rootTyping property when declaring an object, interface, or scalar type, when specifying other types &lt;em&gt;@nexus/schema&lt;/em&gt; is smart enough to infer the correct type &lt;em&gt;graphql-js&lt;/em&gt; will be expecting. Specifying another type for these cases is more likely to trip you up than to give you any benefit.&lt;/p&gt;

&lt;p&gt;When specifying the rootTyping I always use &lt;em&gt;__filename&lt;/em&gt; for the path property. This variable contains the absolute path to the current module. This means that if I ever move the file, I don't have to worry about changing the file import paths manually - I simply have to generate new artifacts. If the declaration of a schema type is not collocated with its root type; I suggest placing the &lt;em&gt;RootTypingImport&lt;/em&gt; with the type declaration and importing that constant to the schema type declaration in order to maintain this behavior.&lt;/p&gt;

&lt;h1&gt;
  
  
  Runtime
&lt;/h1&gt;

&lt;p&gt;Setting up a runtime configuration for running a &lt;em&gt;@nexus/schema&lt;/em&gt; server is made a lot easier by using &lt;em&gt;ts-node&lt;/em&gt;, it removes the need for adding &lt;em&gt;.js&lt;/em&gt; and &lt;em&gt;.js.map&lt;/em&gt; files to your &lt;em&gt;.gitignore&lt;/em&gt; and having to filter them out in your editor of choice; or outputting your typescript compilation to a separate &lt;em&gt;dist&lt;/em&gt; folder, and thus doesn't change the value of the &lt;em&gt;__filename&lt;/em&gt; variables in the runtime.&lt;/p&gt;

&lt;h1&gt;
  
  
  Generating artifacts and making changes
&lt;/h1&gt;

&lt;p&gt;When working on your schema you will from time to time need to verify that the changes you've made to the schema are typed correctly before finalizing all the schema changes you're making to the server. To do this, you need to generate new artifacts for the schema. This can be simplified by adding a check to the &lt;code&gt;makeSchema&lt;/code&gt; constructor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;makeSchema&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="p"&gt;...,&lt;/span&gt;
  &lt;span class="na"&gt;shouldExitAfterGenerateArtifacts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--nexus-exit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="c1"&gt;// if the --nexus-exit param is given to the process, exit after the schema artifacts have been generated&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And using the following script to generate the type artifacts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"generate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yarn ts-node ./src/server --nexus-exit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script will run the schema up to the point where the artifacts are generated, and then exit. This is useful behavior when working on the schema since the correctness of the types can only truly be ascertained after the new artifacts are generated. This script would also be useful to run as a step in your CI process, as it allows you to remove the generated artifacts from your git repository improving clarity of pull requests.&lt;/p&gt;

&lt;p&gt;Sometimes you will need to make changes to your schema, or how some field should be resolved. This can be a hassle if you've already generated the type artifacts for the schema earlier, and you're running on &lt;em&gt;ts-node&lt;/em&gt;. To resolve this issue, use the following script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"generate:force"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yarn ts-node --log-error ./src/server --nexus-exit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the &lt;em&gt;--log-error&lt;/em&gt; flag set, &lt;em&gt;ts-node&lt;/em&gt; will find just any type errors and still execute the script. This means, you can generate your new type artifacts even when in the middle of making a large set of changes where your server won't compile correctly until all changes are finalized, giving you invaluable type checking for the changes you've already made. The errors reported by the script should generally be ignored though, since they will be based on the old type artifacts.&lt;/p&gt;

&lt;h1&gt;
  
  
  Resources
&lt;/h1&gt;

&lt;p&gt;A demo project utilizing all the techniques described can be found &lt;a href="https://github.com/IT-Minds-ApS/graphql-nexus-demo"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>typescript</category>
      <category>node</category>
      <category>nexus</category>
    </item>
  </channel>
</rss>
