<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Novvum</title>
    <description>The latest articles on DEV Community by Novvum (@novvum).</description>
    <link>https://dev.to/novvum</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%2Forganization%2Fprofile_image%2F790%2F314f6033-df5d-434e-a22f-b3631d144037.png</url>
      <title>DEV Community: Novvum</title>
      <link>https://dev.to/novvum</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/novvum"/>
    <language>en</language>
    <item>
      <title>How we used Gatsby Themes to build a suite of consistent websites for our company</title>
      <dc:creator>Trevor Heath</dc:creator>
      <pubDate>Mon, 07 Oct 2019 18:07:14 +0000</pubDate>
      <link>https://dev.to/novvum/how-we-used-gatsby-themes-to-build-a-suite-of-consistent-websites-for-our-company-2fpf</link>
      <guid>https://dev.to/novvum/how-we-used-gatsby-themes-to-build-a-suite-of-consistent-websites-for-our-company-2fpf</guid>
      <description>&lt;p&gt;Here at Novvum, we are a software development firm that specializes in React, GraphQL, TypeScript, Node and so much more. Therefore, we enjoy building with modern technologies like Gatsby. Sadly, up until now, our website did not follow this trend.&lt;/p&gt;

&lt;p&gt;A few months ago we decided it was time to give our site a much-needed upgrade. We always take great pride in designing and architecting cutting-edge web applications for our clients, but we hadn’t given much thought to our site and were still using a drag and drop editor for simplicity. Why? We would love to say that we were just too busy building awesome software for our clients, which is partially true, but we were also reluctant to upgrade because we needed a site that could be edited and designed by non-technical members of our team while still providing great performance and features.&lt;/p&gt;

&lt;h3&gt;
  
  
  Our requirements and motivations
&lt;/h3&gt;

&lt;p&gt;Finally, after hearing enough about how our site was not reflective of our work from our partners and friends, we decided it was time to take the plunge and upgrade all of our sites. As we set out on this multi-website rebuild, we had a few key requirements for the codebase and maintenance workflows for the project.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The components, configurations, and functionalities needed to be reusable across all our company’s sites and easily accessible for future sites.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Landing pages&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Blog&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Internal documentation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Client Portal / Auditing Platform&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each site needed to be deployable, editable and extendable on its own without affecting the other clients&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Content like blogs, audits and case studies needed to be easily edited by non-technical team members without diving into the codebase&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All site's code/logic should be available in a single monorepo, while content (markdown/MDX) files should be available on their own and abstracted from the core logic.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can tell, most of the requirements set out to simplify the experience of composing functionality across different sites while still maintaining a separation of concerns between each domain and its deployment. We also wanted to keep non-technical content editing separate from feature development. To handle this, we used a combination of the following tools and techniques. I won't dive into them all but it gives you a decent idea of our configurations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gatsby Themes&lt;/li&gt;
&lt;li&gt;Yarn Workspaces&lt;/li&gt;
&lt;li&gt;Git Submodules&lt;/li&gt;
&lt;li&gt;CI/CD with Gitlab&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, I will dive into the composition of our Gatsby themes and how we were able to tackle these requirements while simplifying the development workflow for all our websites.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gatsby Themes as building blocks
&lt;/h3&gt;

&lt;p&gt;If you haven’t heard of Gatsby it is a super-fast static site generator that allows you to use GraphQL to query your site’s configuration, assets and markdown files. It is extremely performant and customizable. Gatsby is the perfect fit for websites, blogs, eCommerce and other content focused sites because the markdown files containing content can easily be edited by technical and non-technical team members. Besides, Gatsby offers Gatsby themes that allow site functionality to be packaged as a standalone module so functionality can easily be reused. Rather than using starters or templates for every website you build, all the default configuration lives in an NPM package, that can be updated and shared across independent projects. This helped us provide a consistent yet adaptable experience across our main website/blog, client portal, and documentation website. Any changes to the underlying theme(s) will update on all current and future sites. Providing a seamless development workflow.&lt;/p&gt;

&lt;h4&gt;
  
  
  Here is how the architecture maps out:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6oYqqGeP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/2yWrY80/Large-Dark-Map.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6oYqqGeP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.ibb.co/2yWrY80/Large-Dark-Map.png" alt="Architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The diagram outlines how we are using Gatsby Themes to share components and functionality across our suite of websites.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;base-theme&lt;/code&gt; : Holds many of the core pieces of functionality across all Novvum sites. This includes theming, presentational components, utilities and more. Think of this as the more fundamental building block.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;blog-theme&lt;/code&gt; : The blog theme is what it sounds like, the theme for all blog-specific functionality. This includes the blog specific components and routing information.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;wiki-theme&lt;/code&gt; : This theme is specific to our internal documentation site and handles the routing and components needed to display out internal documentation. There is more on this theme and the motivation for its abstraction below.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;auth-theme&lt;/code&gt; : One of the more interesting themes, this theme includes all the necessary modules for authentication. Plug it in and your deployed website has auth.&lt;/p&gt;

&lt;h3&gt;
  
  
  Composing themes
&lt;/h3&gt;

&lt;p&gt;Initially, it is easy to assume Gatsby Themes are best used for styling and components. However, with some creativity, Gatsby Themes can provide a great way to share configuration, functionality, and logic for almost anything. It is not to much different from just deploying individual NPM modules.&lt;/p&gt;

&lt;p&gt;So, Rather than dive into the more fundamental use cases for themes like using them to share UI and components, I want to quickly review how our &lt;code&gt;auth-theme&lt;/code&gt; (green block) is currently being used to extend our client portal and internal documentation sites. Also, dive into how themes can provide a great abstraction for content files written in &lt;code&gt;markdown&lt;/code&gt; and &lt;code&gt;mdx&lt;/code&gt; . These are two ways we tackled our requirements in a creative way and may provide you with some inspiration.&lt;/p&gt;

&lt;h4&gt;
  
  
  Sharing logic + ui
&lt;/h4&gt;

&lt;p&gt;Sometimes sharing a site logic can be a pain and may even require redundant code across websites. However, by using the basic Gatsby Theme concepts, we can share our authentication module across all of our sites.&lt;/p&gt;

&lt;p&gt;By simply adding the &lt;code&gt;auth-theme&lt;/code&gt; to the &lt;code&gt;Client Portal&lt;/code&gt; and &lt;code&gt;Internal Documentation&lt;/code&gt; &lt;code&gt;gatsby-configs&lt;/code&gt;, we can extend both sites to with our prepackaged, consistent authentication module. In this case, we are using Netlify Identity for simplicity but this idea would not change for other more custom implementations. In our case, the auth theme` includes helper functions for user management, sign in modals, private routes and other key authentication functionalities. Now, if we ever want to include auth on any other sites, we just add that theme to the config and we are off and running. This is the same with the styling theme and component found in the base Gatsby Theme.&lt;/p&gt;

&lt;h4&gt;
  
  
  Abstracting away content from code
&lt;/h4&gt;

&lt;p&gt;Another powerful feature of Gatsby Themes is the ability to extend themes with themes. Above you may have noticed the blue block inside the &lt;code&gt;blog-theme&lt;/code&gt; and &lt;code&gt;wiki-theme&lt;/code&gt; modules. That blue block is our &lt;code&gt;base-theme&lt;/code&gt; which provides fundamental theming and components to all of our websites including the internal documentation and blog. This may seem a bit like themeception, but let me explain our thought process:&lt;/p&gt;

&lt;p&gt;If you remember from above, one of our requirements was the ability of non-technical team members to edit and add content like blog articles and documentation without needing access to the entire codebase.&lt;/p&gt;

&lt;p&gt;Well, by creating a &lt;code&gt;blog-theme&lt;/code&gt; or &lt;code&gt;wiki-theme&lt;/code&gt; , we can abstract all of the blog and documentation logic away from the final deployed site. Here is a look at the final internal documentation site's file structure and &lt;code&gt;gatsby-config&lt;/code&gt; file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
├── public&lt;br&gt;
├── content (all .md &amp;amp; .mdx files)&lt;br&gt;
| ├── assets&lt;br&gt;
| ├── guides&lt;br&gt;
| ├── index.mdx&lt;br&gt;
| └── projects&lt;br&gt;
├── gatsby-config.js&lt;br&gt;
├── netlify.toml&lt;br&gt;
├── package.json&lt;br&gt;
├── README.md&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Woah! There is no &lt;code&gt;src&lt;/code&gt; directory, meaning there are no React components! This is made possible because all of that code lives in the separate &lt;code&gt;wiki-theme&lt;/code&gt;. This leaves the repo simple while only exposing the markdown files found in the &lt;code&gt;content&lt;/code&gt; folder. Now content creators and non-technical team members can quickly add and edit content without knowing much about how the site works. The themes even handle routing, so new &lt;code&gt;markdown&lt;/code&gt; (&lt;code&gt;mdx&lt;/code&gt; in our case) files and folders automatically create new routes that will display information properly. The only reference to the theme can be found in the &lt;code&gt;gatsby-config&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
module.exports = {&lt;br&gt;
 __experimentalThemes: [&lt;br&gt;
  {&lt;br&gt;
   resolve: "@novvum/gatsby-theme-wiki"&lt;br&gt;
  }&lt;br&gt;
 ],&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Of course, another option for reaching this level of abstraction may be to use a CMS like Contentful. However, for small and midsized teams, this works great.&lt;/p&gt;

&lt;h3&gt;
  
  
  Okay, how do you work on all these abstractions together?
&lt;/h3&gt;

&lt;p&gt;Well, that's where the monorepo, submodules, and Gitlab CI/CD comes together. With the current setup, you can interact with the codebases in a few ways.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You can directly edit content in the individual repos &lt;code&gt;blog&lt;/code&gt;, &lt;code&gt;internal documentation&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;You can directly edit site functionality in the individual repos.&lt;/li&gt;
&lt;li&gt;You can edit all codebases in unison through our master monorepo. This monorepo includes submodules for each of the deployed &lt;code&gt;sites&lt;/code&gt; as well as all the &lt;code&gt;themes&lt;/code&gt; . Here is the folder structure:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
├── clients&lt;br&gt;
| ├── audit (submodule)&lt;br&gt;
| ├── blog (submodule)&lt;br&gt;
| ├── web (submodule)&lt;br&gt;
| └── documentation (submodule)&lt;br&gt;
├── themes&lt;br&gt;
| ├── base&lt;br&gt;
| ├── blog&lt;br&gt;
| ├── gatsby-theme-auth&lt;br&gt;
| └── gatsby-theme-wiki&lt;br&gt;
├── lerna.json&lt;br&gt;
├── package.json&lt;br&gt;
├── README.md&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This monorepo provides a superuser workflow to add, edit and change each of the separate themes and sites while still maintaining a separation of concerns. If only editing one of the clients is preferred, one can just clone and work in the specific site's repository without access to the underlying themes. This offers a bunch of flexibility!&lt;/p&gt;

&lt;h3&gt;
  
  
  Great, so now what?
&lt;/h3&gt;

&lt;p&gt;Now that we have a flexible, scalable and robust underlying architecture for the Novvum suite of sites our team is confident we will be able to easily iterate, collaborate and extend our online presence without losing consistency. Need a new website? Add it to the monorepo, extend a theme and you are off an running!&lt;/p&gt;

&lt;p&gt;If you are interested in learning more about any of the underlying concepts in this article, I would love to dive into the details on my next blog. Or if you have thoughts on how to improve this, we would love to hear from you.&lt;/p&gt;

&lt;p&gt;To check out our new home go to &lt;a href="//www.novvum.io"&gt;novvum.io&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Using Artificial Intelligence to Understand Emotions in Tweets</title>
      <dc:creator>Alli Colyer</dc:creator>
      <pubDate>Tue, 27 Aug 2019 19:01:22 +0000</pubDate>
      <link>https://dev.to/novvum/using-artificial-intelligence-to-understand-emotions-in-tweets-47mf</link>
      <guid>https://dev.to/novvum/using-artificial-intelligence-to-understand-emotions-in-tweets-47mf</guid>
      <description>&lt;p&gt;Hello, internet! Yesterday I introduced &lt;a href="https://www.feelsbot.me/" rel="noopener noreferrer"&gt;Feelsbot&lt;/a&gt;. Today I'll discuss how Feelsbot uses artificial intelligence to analyze emotional sentiment in Tweets. Feelsbot can analyze Tweets of any geographical location or any public Twitter profile.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fjhfrck232gln92bg7wkt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fjhfrck232gln92bg7wkt.gif" alt="Gif of Feelsbot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Artificial Intelligence and Machine Learning?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Artificial Intelligence (AI)&lt;/strong&gt; seems to be all over the place these days, but what exactly is it? Feelsbot, which uses AI to understand tweets, is a great example to help answer this question.   &lt;/p&gt;

&lt;p&gt;AI is a field of computer science dedicated to creating machines that can make intelligent decisions. You can think of artificial intelligence as a goal. We can reach that goal through machine learning. &lt;strong&gt;Machine learning&lt;/strong&gt; is a way to teach machines how to make predictions or decisions without being explicitly programmed.&lt;/p&gt;

&lt;p&gt;Machine learning models are said to &lt;em&gt;learn&lt;/em&gt; because instead of being programmed to do things, they are &lt;em&gt;trained&lt;/em&gt;. A model is trained through being shown lots of example data points and looking for patterns in the examples. Once identified, these patterns will be used to make decisions about new pieces of data.&lt;/p&gt;

&lt;p&gt;Feelsbot uses a machine learning model created by IBM that categorizes text as being either joyful, sad, angry, disgusted, or fearful. This model was trained to detect emotion by being shown lots of examples of joyful, sad, angry, disgusted and fearful text. The patterns the model detected may involve keywords, such as “cry” or “cheer”, or they may involve the number of words in each sentence. Whatever the patterns are, they all come together to form the machine learning model. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Natural language processing&lt;/strong&gt; is a subset of AI that aims to understand human language. The machine learning model that powers Feelsbot can also be called natural language processing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inspiration for Creating Feelsbot
&lt;/h3&gt;

&lt;p&gt;There are a few reasons why I decided to create Feelsbot. First off, I was inspired by how easy it is to hop in and use some of the machine learning APIs from IBM and Google. Additionally, I wanted to create a software project to help people better understand how AI works. &lt;/p&gt;

&lt;p&gt;Feelsbot highlights a couple of important things about AI and natural language processing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Many machine learning models have a rather simplistic view of emotion, and can’t pick up on subtle things, such as sarcasm.&lt;/li&gt;
&lt;li&gt;Sometimes figures of speech can throw off the model, for example, "I'm so happy I could cry" is detected as sad with a 65% confidence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Although Feelsbot is not perfect, it’s more accurate than you might expect!  I am often surprised by how well it can categorize more ambiguous tweets. Try it out to see for yourself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F29zbbmkkxz399inhufd6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F29zbbmkkxz399inhufd6.png" alt="Image of cartoon Robot crying, celebrating and short-circuiting."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Tweets are short and often use slang which doesn’t always work well with a machine learning model trained with regular text excerpts. For this project, I did not train my own model, but it would be interesting to create a machine learning model that is trained using only tweets.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How Feelsbot Finds and Categorizes Tweets
&lt;/h3&gt;

&lt;p&gt;As mentioned before, Feelsbot is using a machine learning model from IBM to analyze emotions in tweets. Using this model, Feelsbot put tweets into five categories: joy, sadness, anger, fear, and disgust. This model only works in English, limiting the number of tweets Feelsbot can analyze. Each tweet receives a score, called a confidence score, of how strongly it matches one of those categories. Feelsbot puts tweets that have a confidence score higher than 65% into each category. Once the tweets have been categorized, the joy meter is calculated as the percentage of joyful tweets versus every other emotion.&lt;/p&gt;

&lt;p&gt;When using the map, Feelsbot uses Twitter's API to fetch the last 100 tweets that are geotagged near the location entered. If there are not many recent geotagged tweets near that location, Twitter fetches tweets of users whose profile locations are nearby. When analyzing tweets by a specific Twitter account, Feelsbot fetches the last 150 tweets by that account. Twitter profiles need to be public for Feelsbot to work.&lt;/p&gt;

&lt;h3&gt;
  
  
  What’s next for Feelsbot?
&lt;/h3&gt;

&lt;p&gt;Check out Feelsbot and let me know what you think! By request, a hashtag search is currently in the works, so keep your eyes peeled for that update. &lt;/p&gt;

&lt;p&gt;Also, I only touched the surface of what machine learning and AI are, but if you enjoyed this post and would like a more in-depth explanation, please leave a comment below!&lt;/p&gt;

&lt;h3&gt;
  
  
  Contributors
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Big thanks to &lt;a href="https://www.novvum.io/" rel="noopener noreferrer"&gt;Novvum&lt;/a&gt; for supporting the development of Feelsbot.&lt;/li&gt;
&lt;li&gt;Feelsbot was created by &lt;a href="https://twitter.com/allicolyer" rel="noopener noreferrer"&gt;Allison Colyer&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Robot drawings were created by &lt;a href="https://rubyrios.com/" rel="noopener noreferrer"&gt;Ruby Ríos&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>artificialintelligence</category>
      <category>ai</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Introducing Feelsbot: Artificially Intelligent &amp; Emotional</title>
      <dc:creator>Alli Colyer</dc:creator>
      <pubDate>Mon, 26 Aug 2019 19:18:43 +0000</pubDate>
      <link>https://dev.to/novvum/introducing-feelsbot-artificially-intelligent-emotional-389o</link>
      <guid>https://dev.to/novvum/introducing-feelsbot-artificially-intelligent-emotional-389o</guid>
      <description>&lt;p&gt;Hello, internet! This is &lt;a href="https://www.feelsbot.me/" rel="noopener noreferrer"&gt;Feelsbot&lt;/a&gt;. Feelsbot tries to understand how humans are feeling by reading their tweets. Feelsbot can analyze Tweets of any geographical location or any public Twitter profile.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fjhfrck232gln92bg7wkt.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fjhfrck232gln92bg7wkt.gif" alt="Gif of Feelsbot working"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feelsbot uses artificial intelligence to analyze emotional sentiment in Tweets. Play around with Feelsbot and let us know what you think. Did Feelsbot surprise you in any way?&lt;/p&gt;

&lt;p&gt;Stay tuned for a post tomorrow about what machine learning is and how Feelsbot is using it.&lt;/p&gt;

</description>
      <category>artificalintelligence</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>GraphQL Code-First and SDL-First, the Current Landscape in Mid-2019</title>
      <dc:creator>Rohit Ravikoti</dc:creator>
      <pubDate>Fri, 12 Jul 2019 15:39:35 +0000</pubDate>
      <link>https://dev.to/novvum/graphql-code-first-and-sdl-first-the-current-landscape-in-mid-2019-547h</link>
      <guid>https://dev.to/novvum/graphql-code-first-and-sdl-first-the-current-landscape-in-mid-2019-547h</guid>
      <description>&lt;p&gt;There has been a lot of buzz in the GraphQL community around code-first or SDL-first schema development as of late. The purpose of this blog is to shed some light on the current state of the ecosystem and help teams make a decision on which approach would be best for them.&lt;/p&gt;

&lt;p&gt;To understand where we are today, it helps to take a look at how we got here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code-first: the original way to build a graphql schema
&lt;/h2&gt;

&lt;p&gt;Facebook originally released &lt;a href="https://github.com/graphql/graphql-js" rel="noopener noreferrer"&gt;graphql-js&lt;/a&gt; as a reference implementation for the GraphQL specification. The schema is defined as a plain javascript object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { GraphQLSchema, GraphQLObjectType, GraphQLString } = require('graphql')

const schema = new GraphQLSchema({  
  query: new GraphQLObjectType({  
    name: 'Query',  
    fields: {  
      hello: {  
        type: GraphQLString,  
        args: {  
          name: { type: GraphQLString },  
        },  
        resolve: (_, args) =&amp;amp;gt; `Hello ${args.name || 'World!'}`,  
      },  
    },  
  }),  
})  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Many people in the community felt that writing a schema in this way was very verbose, and it was challenging to have a mental model of the schema while implementing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter SDL
&lt;/h2&gt;

&lt;p&gt;The Apollo team released graphql-tools, which popularized the Schema Definition Language (SDL). Here is what the same schema from above looks like defined in SDL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Query {  
  hello(name: String): String  
}  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It was much easier to understand the structure of the schema with SDL and, ultimately made the schema design process much more intuitive. The Apollo team also came up with &lt;a href="https://www.apollographql.com/docs/graphql-tools/schema-directives/" rel="noopener noreferrer"&gt;schema directives&lt;/a&gt; to accompany the SDL.&lt;/p&gt;

&lt;p&gt;One significant tradeoff for the SDL-first approach is that resolvers need to be implemented separately from the schema definition. Consequently, &lt;a href="https://www.prisma.io/blog/the-problems-of-schema-first-graphql-development-x1mn4cb0tyl3#analyzing-the-problems-of-sdl-first-development" rel="noopener noreferrer"&gt;various new challenges&lt;/a&gt; came about. Directives are also &lt;a href="https://github.com/graphql/graphql-js/issues/1343" rel="noopener noreferrer"&gt;not&lt;/a&gt; a part of the core GraphQL specification.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pendulum swings back to code-first
&lt;/h2&gt;

&lt;p&gt;Tools like &lt;a href="http://typegraphql.ml/" rel="noopener noreferrer"&gt;TypeGraphQL&lt;/a&gt; and &lt;a href="https://nexus.js.org/" rel="noopener noreferrer"&gt;GraphQL Nexus&lt;/a&gt; were released to reduce the verbosity of graphql-js and provide a much simpler way to develop schemas than the SDL approach. These tools are built with graphql-js at their core, so they do not have support for schema directives — here are issues requesting support for them in &lt;a href="https://github.com/19majkel94/type-graphql/issues/77" rel="noopener noreferrer"&gt;TypeGraphQL&lt;/a&gt; and &lt;a href="https://github.com/prisma/nexus/issues/53" rel="noopener noreferrer"&gt;GraphQL Nexus&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Federated schemas…
&lt;/h2&gt;

&lt;p&gt;The Apollo team recently introduced the &lt;a href="https://blog.apollographql.com/apollo-federation-f260cf525d21" rel="noopener noreferrer"&gt;Schema Federation&lt;/a&gt; specification for building distributed graphs. It significantly improved on a lot of the pitfalls of schema stitching and enabled a truly distributed architecture. The specification utilizes schema directives, so individual schemas can provide hints to the gateway server on how they are related to one another.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F700%2F1%2AtKMI6wsfV4IGdBudipOK7g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F700%2F1%2AtKMI6wsfV4IGdBudipOK7g.png" alt="apollofederation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The major problem here is that the code-first libraries are unable to support schema federation because they do not support directives. There have been issues submitted for &lt;a href="https://github.com/19majkel94/type-graphql/issues/351" rel="noopener noreferrer"&gt;TypeGraphQL&lt;/a&gt; and &lt;a href="https://github.com/prisma/nexus/issues/148" rel="noopener noreferrer"&gt;GraphQL Nexus&lt;/a&gt; requesting support, but there hasn’t been much progress as of yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, code-first or SDL-first?
&lt;/h2&gt;

&lt;p&gt;Innovation will come with its fair share of disruption, and the GraphQL ecosystem is no exception. There are risks and tradeoffs when selecting any toolset, and teams must carefully look at their circumstances to understand which approach suits their needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Here are a couple of suggestions:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;If your team needs schema federation or directives, then it is best to go with the SDL-first approach until the ecosystem catches up.&lt;/li&gt;
&lt;li&gt;If your team doesn’t need schema federation or directives, then it is best to go with code-first — especially if you have a large schema. It will help your team keep your codebases organized and moving quickly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What if you made the wrong choice?
&lt;/h3&gt;

&lt;p&gt;The silver lining here is that you are not necessarily stuck with the decision your team makes now. Because both approaches are fundamentally the same (you define a schema and resolvers), it is not difficult to reuse most if not all of the business logic when switching from one approach to the other. One thing to note is that it is currently much easier to start with code-first and then switch to SDL-first because of the lack of schema directive support in code-first.&lt;/p&gt;

&lt;p&gt;I hope this proved helpful for teams struggling to stay on top of everything that is happening in the GraphQL ecosystem. You can always reach out to us at &lt;a href="https://www.novvum.io/contact-us" rel="noopener noreferrer"&gt;Novvum&lt;/a&gt; for help!&lt;/p&gt;

&lt;h6&gt;
  
  
  about us: &lt;a href="https://novvum.io" rel="noopener noreferrer"&gt;Novvum&lt;/a&gt; is a modern software development agency specializing in engineering, strategy, &amp;amp; design.
&lt;/h6&gt;

</description>
      <category>graphql</category>
      <category>discuss</category>
      <category>coding</category>
      <category>development</category>
    </item>
    <item>
      <title>GraphQL Subscriptions with Nexus and React Apollo</title>
      <dc:creator>Novvum Dev Team</dc:creator>
      <pubDate>Fri, 28 Jun 2019 18:23:12 +0000</pubDate>
      <link>https://dev.to/novvum/graphql-subscriptions-with-nexus-and-react-apollo-2pdo</link>
      <guid>https://dev.to/novvum/graphql-subscriptions-with-nexus-and-react-apollo-2pdo</guid>
      <description>&lt;h4&gt;
  
  
  Introduction
&lt;/h4&gt;

&lt;p&gt;Subscriptions are a very powerful feature of GraphQL. They allow you to have a real-time connection to your database, notifying and updating your data when there are changes. Subscriptions have tons of applications, such as real-time chat applications or live comment feeds on articles.&lt;/p&gt;

&lt;p&gt;In this tutorial, we are going to create a minimal real-time chat application using GraphQL Nexus and React Apollo. Hopefully by the end of this, you’ll be a pro at using subscriptions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2ADne-esyq4HBFU25p" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2ADne-esyq4HBFU25p" alt="dev.to1"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h4&gt;
  
  
  Meat and Potatoes
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Getting Set Up
&lt;/h5&gt;

&lt;p&gt;To get started, download this repository: &lt;a href="https://github.com/hkyang995/graphql-nexus-subscription-starter-backend" rel="noopener noreferrer"&gt;https://github.com/hkyang995/graphql-nexus-subscription-starter-backend&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This project contains a schema with a single &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Post&lt;/code&gt; type- &lt;code&gt;Post&lt;/code&gt; has two fields, &lt;code&gt;author&lt;/code&gt; and &lt;code&gt;content&lt;/code&gt;. We will set up a subscription to update a live chat feed with every new post that is made.&lt;/p&gt;

&lt;p&gt;If you take a peek at &lt;code&gt;src/schema.ts&lt;/code&gt;, you’ll see two queries, &lt;/p&gt;

&lt;p&gt;&lt;code&gt;post&lt;/code&gt; and &lt;code&gt;posts&lt;/code&gt;. The &lt;code&gt;post&lt;/code&gt; query returns the single most recent post, while &lt;code&gt;posts&lt;/code&gt; returns every post in the database. And as you might have guessed, the &lt;code&gt;createPost&lt;/code&gt; mutation creates a post.&lt;/p&gt;

&lt;p&gt;Let’s get started by installing our tools: GraphQL Yoga, GraphQL Nexus, and GraphQL. We’ll be using Prisma’s demo servers to help get things set up and conveniently host all of our information. The starter file uses yarn to tie our dependencies together, so all we need to do is:  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To start the server at any time during the tutorial, use:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn dev&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now that we’ve installed everything, we can create a server with Prisma using:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;prisma init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command will walk us through the creation of the server. Feel free to choose whatever suits your needs, but for simplicity’s sake, these options will do just fine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Demo server&lt;/li&gt;
&lt;li&gt;Choose EU or US&lt;/li&gt;
&lt;li&gt;Name your shiny new service&lt;/li&gt;
&lt;li&gt;Choose a name for this stage (just the default is fine)&lt;/li&gt;
&lt;li&gt;Choose Typescript for our language of choice&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your server will be good to go after running &lt;code&gt;prisma generate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now we’re finally ready to dive into making our Subscription!&lt;/p&gt;

&lt;h5&gt;
  
  
  Creating the Subscription on the Backend
&lt;/h5&gt;

&lt;p&gt;Now that we are set up, we are ready to create our Subscription. Since each Subscription needs to return a payload (the bundle of information sent back to you), we’ll add a payload type to our schema.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const PostSubscriptionPayload = objectType({
 name: "PostSubscriptionPayload",
 definition(t) {
   t.field("node", {
     type: Post,
     nullable: true
   });
   t.list.string("updatedFields", { nullable: true });
 }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Like mentioned above, this payload type is the object type that will be returned from our subscription. The key item that we’re going to be looking at is &lt;code&gt;t.field(“node”)&lt;/code&gt;. We set its type to &lt;code&gt;Post&lt;/code&gt; so it’ll return exactly what we need, a &lt;code&gt;Post&lt;/code&gt;!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const messageSubscription = subscriptionField("post", {
 type: PostSubscriptionPayload,
 subscribe: (root, args, context) =&amp;gt; {
   return context.prisma.$subscribe.post({ mutation_in: "CREATED" }) as any;
 },
 resolve: payload =&amp;gt; {
   return payload;
 }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s the function that’s going to be doing most of the work. You might be thinking, “That’s it??” and yes, that is it! You don’t need anything else on the backend for this particular application.&lt;/p&gt;

&lt;p&gt;Here’s how this code works. We set the type to &lt;code&gt;PostSubscriptionPayload&lt;/code&gt; to return our post. You can see that we pass in an argument to the post &lt;code&gt;mutation_in: ‘CREATED’&lt;/code&gt;, which means that we’re only going to subscribe to newly created posts (as opposed to posts that are edited or deleted). Finally, we return the payload which completes our Subscription!&lt;/p&gt;

&lt;p&gt;You can test this out on your GraphQL Playground by starting it up with &lt;code&gt;yarn dev&lt;/code&gt;. When you run the Subscription, it will start listening for new posts. When you create a new post using the &lt;code&gt;createPost&lt;/code&gt; mutation, you’ll be able to see it in your Subscription’s tab.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AgwZc8WUltvUsKQgH" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AgwZc8WUltvUsKQgH" alt="gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can check out and download the completed backend code here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/hkyang995/graphql-nexus-subscription-starter-backend/tree/completed" rel="noopener noreferrer"&gt;https://github.com/hkyang995/graphql-nexus-subscription-starter-backend/tree/completed&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  Creating the Subscription on the Frontend
&lt;/h5&gt;

&lt;p&gt;We have our subscriptions working on the backend, but we’re not out of the woods yet. The next steps are to make subscriptions work on the frontend so we can see our shiny new &lt;code&gt;Posts&lt;/code&gt; in real time.&lt;/p&gt;

&lt;p&gt;To start out, let’s set up a simple UI and connect our frontend to the backend. To get started, download this repo of frontend code:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/hkyang995/graphql-nexus-subscription-starter-frontend" rel="noopener noreferrer"&gt;https://github.com/hkyang995/graphql-nexus-subscription-starter-frontend&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To run the application at any time, use &lt;code&gt;yarn start&lt;/code&gt; in the command line on the frontend folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const wsLink = new WebSocketLink({
 uri: `ws://localhost:4000/`,
 options: {
   reconnect: true
 }
});

const httpLink = createHttpLink({
 uri: "http://localhost:4000/"
});

const link = split(
 ({ query }) =&amp;gt; {
   const { kind, operation } = getMainDefinition(query);
   return kind === "OperationDefinition" &amp;amp;&amp;amp; operation === "subscription";
 },
 wsLink,
 httpLink
);

const client = new ApolloClient({
 link,
 cache: new InMemoryCache()
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you take a look at &lt;code&gt;src/App.js&lt;/code&gt;, you’ll see that we’re using Apollo to connect our frontend with our backend. The backend server is set to &lt;code&gt;localhost:4000&lt;/code&gt;, which can be changed if your server is being hosted elsewhere. We’re also connecting a WebSocket to all of this so we are able to get our subscriptions in real time.&lt;/p&gt;

&lt;p&gt;Most of the legwork is being done in our components function, &lt;code&gt;src/AppContents.js&lt;/code&gt;. In this file, there is a function that takes the input and does a mutation to push the Post to our server. In &lt;code&gt;src/ChatBox.js&lt;/code&gt;, we query for the &lt;code&gt;Posts&lt;/code&gt; that already exist and display them to the user.&lt;/p&gt;

&lt;p&gt;For now, we can write out messages and submit them, but the chat box won’t update unless we refresh. To fix this, we will set up our Subscription on the frontend.&lt;/p&gt;

&lt;p&gt;Using one of our imported packages, &lt;code&gt;graphql-tag&lt;/code&gt; (&lt;code&gt;gql&lt;/code&gt;), we can set up a subscription on the frontend like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const NEW_POST_SUBSCRIPTION = gql`
 subscription PostSubscription {
   post {
     node {
       content
       id
       author
     }
   }
 }
`;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we defined our subscription on the backend, we only need to specify what we want to grab from it on the frontend. Here we’re getting the content, id, and author.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Query query={GET_EXISTING_POSTS}&amp;gt;
               {({ subscribeToMore, loading, error, data }) =&amp;gt; {
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;subscribeToMore&lt;/code&gt; function comes packaged in Apollo GraphQL, and is going to be our best friend on the frontend, as it’s going to get our Subscriptions to work. We can pass it through in our query function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ChatView
  data={data}
  subscribeToMore={() =&amp;gt;
    subscribeToMore({
      document: NEW_POST_SUBSCRIPTION,
      updateQuery: (prev, { subscriptionData }) =&amp;gt; {
        if (!subscriptionData.data) return prev;
        const { node } = subscriptionData.data.post;
        return Object.assign({}, prev, {
          posts: [...prev.posts, node]
        });
      }
    })
   }
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we’re passing the &lt;code&gt;subscribeToMore&lt;/code&gt; function into our &lt;code&gt;ChatView&lt;/code&gt; component. Let’s break down how this all works.&lt;/p&gt;

&lt;p&gt;We’re passing the subscription into the &lt;code&gt;document&lt;/code&gt; field, and &lt;code&gt;updateQuery&lt;/code&gt; is a function that runs every time our query is updated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { node } = subscriptionData.data.post;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can pull out the node from the subscription data, which contains all of the information about the post: the content, the post id, and the author of the post.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return Object.assign({}, prev, {
  posts: [...prev.posts, node]
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the very end, we’re updating our &lt;code&gt;posts&lt;/code&gt; by setting it equal to its previous values, along with the new node we got from the subscription.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  componentDidMount() {
    this.props.subscribeToMore();
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last thing we need to do is add the &lt;code&gt;subscribeToMore&lt;/code&gt; function into the &lt;code&gt;ChatView&lt;/code&gt; component’s &lt;code&gt;componentDidMount&lt;/code&gt; function. This will allow it to update whenever it needs to.&lt;/p&gt;

&lt;p&gt;And there you have it! Now whenever a message is sent, your subscription will update the frontend.&lt;/p&gt;

&lt;p&gt;The completed code can be found here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/hkyang995/graphql-nexus-subscription-starter-frontend/tree/completed" rel="noopener noreferrer"&gt;https://github.com/hkyang995/graphql-nexus-subscription-starter-frontend/tree/completed&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;In this tutorial, we built a real-time chat application using GraphQL subscriptions. With this under your belt, subscriptions will appear less daunting for more complex applications.&lt;/p&gt;

&lt;p&gt;If you have any questions, comments, concerns, or just want to tell me about your day, feel free to leave a comment. For more content like this, feel free to follow &lt;a href="https://twitter.com/novvumio" rel="noopener noreferrer"&gt;Novvum&lt;/a&gt; on Twitter. Thank you!&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>react</category>
      <category>nexus</category>
      <category>subscriptions</category>
    </item>
    <item>
      <title>JustGraphQL: Your One-Stop-Shop for GraphQL Resources, Tools, &amp; Articles</title>
      <dc:creator>Novvum Dev Team</dc:creator>
      <pubDate>Tue, 18 Jun 2019 19:29:21 +0000</pubDate>
      <link>https://dev.to/novvum/justgraphql-your-one-stop-shop-for-graphql-resources-tools-articles-20hj</link>
      <guid>https://dev.to/novvum/justgraphql-your-one-stop-shop-for-graphql-resources-tools-articles-20hj</guid>
      <description>&lt;p&gt;As part of our mission to make GraphQL more accessible and easier to learn we a have created &lt;a href="https://www.justgraphql.com/"&gt;JustGraphQL&lt;/a&gt;: a website that will bring together the best of the GraphQL community in an easy to navigate way. If you would like to contribute or spotlight your projects or resources feel free to &lt;a href="https://www.novvum.io/contact-us"&gt;reach out&lt;/a&gt;.&lt;/p&gt;

&lt;h6&gt;
  
  
  about us: &lt;a href="https://novvum.io"&gt;Novvum&lt;/a&gt; is a modern software development agency specializing in both engineering, strategy, &amp;amp; design.
&lt;/h6&gt;

</description>
      <category>graphql</category>
    </item>
    <item>
      <title>36 GraphQL Concepts: An Easy Way to Learn GraphQL!</title>
      <dc:creator>Kelsey Yim</dc:creator>
      <pubDate>Tue, 18 Jun 2019 19:28:52 +0000</pubDate>
      <link>https://dev.to/novvum/36-graphql-concepts-an-easy-way-to-learn-graphql-16bp</link>
      <guid>https://dev.to/novvum/36-graphql-concepts-an-easy-way-to-learn-graphql-16bp</guid>
      <description>&lt;p&gt;We’ve compiled a list of the best articles and videos for learning the 36 most important concepts of GraphQL. With a few students on our team, we quickly realized it’s difficult for a beginner developer to distinguish what resources were accurate and actually helped them learn.&lt;/p&gt;

&lt;p&gt;So our team decided that we wanted to make it easier for newcomers to understand GraphQL! We put together a list of helpful tutorials, examples, and articles explaining low-level and high-level concepts and tossed it on Github! &lt;/p&gt;

&lt;h5&gt;
  
  
  Github Repo:
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://github.com/Novvum/36-graphql-concepts"&gt;https://github.com/Novvum/36-graphql-concepts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have any interesting and useful resources you’d like to add, feel free to make a pull request on our repository. We’d love to collaborate and create a reliable source of information for new or advanced developers.&lt;/p&gt;

&lt;h6&gt;
  
  
  about us: &lt;a href="https://novvum.io"&gt;Novvum&lt;/a&gt; is a modern software development agency specializing in both engineering, strategy, &amp;amp; design.
&lt;/h6&gt;

</description>
      <category>graphql</category>
    </item>
    <item>
      <title>Python + Marvel + GraphQL = PyMarvelQL</title>
      <dc:creator>Jorge Carlos</dc:creator>
      <pubDate>Mon, 03 Jun 2019 17:08:01 +0000</pubDate>
      <link>https://dev.to/novvum/python-marvel-graphql-pymarvelql-3ia7</link>
      <guid>https://dev.to/novvum/python-marvel-graphql-pymarvelql-3ia7</guid>
      <description>&lt;h1&gt;Introduction 🌋&lt;/h1&gt;

&lt;p&gt;With the release of Avengers Endgame, there was no better time to build PyMarvelQL, a program that allows you to query the Marvel Database using GraphQL.&lt;/p&gt;

&lt;p&gt;PyMarvelQL allows you to send GraphQL queries to Marvel’s REST API to get information about characters, comic series, stories, creators and much more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z8-2o-ZL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AABLw585PPvYD3vFQyvwEeQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z8-2o-ZL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AABLw585PPvYD3vFQyvwEeQ.gif" alt="Alt text of image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;Try it out 😲&lt;/h1&gt;

&lt;p&gt;Here is a query for characters with names starting with Captain. The query getCharacter() accepts the parameter nameStartsWith, which can be set to any value you want. Inside the query, you can include any fields that you want to fetch from the Marvel API. The available queries and parameters are based on the Marvel API documentation.&lt;/p&gt;

&lt;p&gt;If you would like to download this tool head on over to this &lt;a href="https://github.com/Novvum/MarvelQL/tree/master/packages/python"&gt;Github repository.&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;How it works 🏗&lt;/h1&gt;

&lt;p&gt;PyMarvelQL is built with 5 tools — Graphene 2.1, Python 3.7, Flask, flask-graphql, and Marvelous. Flask and Graphene are the main tools in this project. flask-graphQl is used to host a local GraphQL server, and Graphene is used to create the GraphQL resolvers and Object Types that allow the user to query the JSON data from the Marvel database.&lt;/p&gt;

&lt;h1&gt;Flask and Flask-GraphQL 🧪&lt;/h1&gt;

&lt;p&gt;“Flask is a web framework for python that provides you with tools, libraries, and technologies that allow you to build a web application.” This project relies on Flask to support running GraphiQL in the browser. It uses GraphQLView from the flask-graphql package to add a /graphql endpoint to the flask app. This is what the setup file looks like for flask-graphql.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hDDL0DB9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2ANtEVlqNULDqGXMZhcpI9ag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hDDL0DB9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2ANtEVlqNULDqGXMZhcpI9ag.png" alt="Alt text of image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Navigate to the /graphql endpoint to visit the GraphiQL playground to query comics, characters, creators and events.&lt;/p&gt;

&lt;h1&gt;Marvelous 🦸&lt;/h1&gt;

&lt;p&gt;“Marvelous is an Marvel API wrapper for python”. PyMarvelQL uses Marvelous to call a Marvel endpoint and retrieve a JSON object with all of the data needed for the resolvers. PyMarvelQL ships with our API key, but you can register for your own by visiting Marvel’s website. After getting an API key, you can fetch JSON objects like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZNmN75q4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AavcU_DY4oKYZLFQqEQecDw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZNmN75q4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AavcU_DY4oKYZLFQqEQecDw.png" alt="Alt text of image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The variable m contains an instance of the marvelous API that fetches data in the Marvel database data in the Marvel database. As shown above, the function accessData returns a JSON object depending on what the variable name is.&lt;/p&gt;

&lt;h1&gt;Graphene-Python 2.1 👌&lt;/h1&gt;

&lt;p&gt;“Graphene-Python is a library for building GraphQL APIs in Python easily, its main goal is to provide a simple but extendable API for making developers’ lives easier.” One of the main features of Graphene is that it allows us to create resolver methods and ObjectTypes. The resolver methods in PyGraphQL return JSON Data to the queries. For example, when fetching for Marvel characters the accessData function(mentioned above) is called and the JSON object is stored in the variable characters. Afterwards, the data is returned using these two functions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PpT1Zj-m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AC-hFWME7L0GZirxLMtqCyQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PpT1Zj-m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AC-hFWME7L0GZirxLMtqCyQ.png" alt="Alt text of image"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rVjva1Jj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2Az3xaYTdqlYuwqju9JozZKw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rVjva1Jj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2Az3xaYTdqlYuwqju9JozZKw.png" alt="Alt text of image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These helper functions read the object as a string and return the query as an object. An ObjectType is also essential to returning the data that is being queried. As stated in Graphene documentation, “it is the single definitive source of information about your data. It contains the essential fields and behaviors of the data you’re querying.”&lt;/p&gt;

&lt;p&gt;When creating an ObjectType, you must create the “fields and behaviors” exactly the same as how it is presented in the API’s documentation. This will ensure that the data will be returned correctly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7UTVnpqC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2A0AFRp6MQu9SbiKc4HomW8A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7UTVnpqC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2A0AFRp6MQu9SbiKc4HomW8A.png" alt="Alt text of image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For instance, the &lt;a href="https://developer.marvel.com/&amp;lt;br&amp;gt;%0A"&gt;Marvel API Documentation&lt;/a&gt; lists the fields that the Creator object has.. Most importantly, it shows what data type a field is. Using that information, you can create an ObjectType like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IKokSy-_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AJ7yzmvgy7gL8yioAbQPQxw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IKokSy-_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1600/1%2AJ7yzmvgy7gL8yioAbQPQxw.png" alt="Alt text of image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As shown above, the ObjectType is similar to the way Marvel creates their Creator class. The main difference is that the datatype of each field is declared with Graphene functions: String(), List(), and Field(). A detailed explanation of all the different Graphene functions can be found in its  &lt;a href="https://docs.graphene-python.org/en/latest/types/scalars/"&gt;documentation.&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;Contact Us&lt;/h1&gt;

&lt;p&gt;If you like PyMarvelQL, please follow us on twitter &lt;a href="https://twitter.com/novvumio"&gt;(@novvumio)&lt;/a&gt; and give us a star 🌟 on &lt;a href="https://github.com/Novvum/MarvelQL/tree/master/packages/python"&gt;Github!&lt;/a&gt; If you find any issues, we’d love to fix them! You can submit them &lt;a href="https://github.com/Novvum/MarvelQL/issues"&gt;here.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>marvel</category>
      <category>graphql</category>
      <category>graphene</category>
    </item>
    <item>
      <title>How to Query Enums with GraphQL using Introspection</title>
      <dc:creator>Novvum Dev Team</dc:creator>
      <pubDate>Tue, 21 May 2019 18:36:40 +0000</pubDate>
      <link>https://dev.to/novvum/how-to-query-enums-with-graphql-using-introspection-25e</link>
      <guid>https://dev.to/novvum/how-to-query-enums-with-graphql-using-introspection-25e</guid>
      <description>&lt;h4&gt;
  
  
  Why use Introspection to Query Enums?
&lt;/h4&gt;

&lt;p&gt;When you are working on a project that allows users to pick an option, such as a school name, it is best to query for these values from your database instead of storing them on a list. This is because if new options are added you won’t have to worry about updating a list on the frontend. Moreover, if you needed to use these values in another file you could simply call the enum query.&lt;/p&gt;

&lt;h4&gt;
  
  
  What’s Introspection?
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://graphql.org/learn/introspection/"&gt;&lt;em&gt;Introspection&lt;/em&gt;&lt;/a&gt;&lt;em&gt; allows you to ask a GraphQL schema for information about what queries it supports.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the introspection system, there are 6 introspection types we can use __Schema, __Type, __TypeKind, __Field, __InputValue, __EnumValue, __Directive. To query the enums you need to use the __Type query resolver.&lt;/p&gt;

&lt;h4&gt;
  
  
  Using __Type
&lt;/h4&gt;

&lt;p&gt;For this example, I will be using an enum that stores the names of 7 universities.&lt;/p&gt;

&lt;p&gt;‍&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hvY7UPxl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cafa6760245ec3131e7848f_1%2AEJmTOk6FJN3_G5c4nbO2KA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hvY7UPxl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cafa6760245ec3131e7848f_1%2AEJmTOk6FJN3_G5c4nbO2KA.png" alt="school names"&gt;&lt;/a&gt;&lt;br&gt;
‍&lt;/p&gt;

&lt;p&gt;Here’s how to query this enum:&lt;/p&gt;

&lt;p&gt;‍&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r346iWin--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cafa6760313532657af984c_1%2Af0QbU0nW73OubeQlFqDNNA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r346iWin--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cafa6760313532657af984c_1%2Af0QbU0nW73OubeQlFqDNNA.png" alt="query 1"&gt;&lt;/a&gt;&lt;br&gt;
‍&lt;/p&gt;

&lt;p&gt;The __type query resolver requires the name parameter. This parameter allows you to search your schema for items such as objects and enums based on their name.&lt;/p&gt;

&lt;p&gt;Once you run this query your result should look like this:&lt;/p&gt;

&lt;p&gt;‍&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7jY2ONIy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cafa676023e3220240429dd_1%2AsOneJtoocq389v0mqzY11A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7jY2ONIy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cafa676023e3220240429dd_1%2AsOneJtoocq389v0mqzY11A.png" alt="query results"&gt;&lt;/a&gt;&lt;br&gt;
‍&lt;/p&gt;

&lt;p&gt;This returns the name of the enum with all of its values. To use these values, store them in a variable when querying the enums. The statement should look like this:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;items = data.&lt;/em&gt;&lt;em&gt;type.enumValues&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Application on React Frontend
&lt;/h4&gt;

&lt;p&gt;This example illustrates how to apply the enum query on a dropdown menu created with&lt;a href="https://material-ui.com/"&gt;material-ui &lt;/a&gt;components. The enum items are stored in the list menuItems and then passed to the dropdown component with the map method. Thus, every time the user interacts with the dropdown menu the query will be called and all the values stored in the menuItems will be displayed.&lt;/p&gt;

&lt;p&gt;‍&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pKwa1stW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cafa676d7cf7f307cf538b6_1%2ACDgbS1Im41gqLL54Ud22vw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pKwa1stW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cafa676d7cf7f307cf538b6_1%2ACDgbS1Im41gqLL54Ud22vw.png" alt="menu items"&gt;&lt;/a&gt;&lt;br&gt;
‍&lt;/p&gt;

&lt;p&gt;The end result should look like this&lt;/p&gt;

&lt;p&gt;‍&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kD385--8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cafa676585c21d07c378f50_1%2AM1Ew9f_GGJ-G_62bEYHong.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kD385--8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cafa676585c21d07c378f50_1%2AM1Ew9f_GGJ-G_62bEYHong.gif" alt="end result"&gt;&lt;/a&gt;&lt;br&gt;
‍&lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;Using introspection is easy and it’s a great way to reduce the number of variables that store the same information in your database. The best thing about using introspection is that no changes need to be done to the frontend to update the list being displayed.&lt;/p&gt;

&lt;p&gt;If you want to learn more about introspection, I found this article helpful, &lt;a href="https://graphqlmastery.com/blog/graphql-introspection-and-introspection-queries"&gt;GraphQL Introspection and Introspection Queries&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to learn more about GraphQL, I found these helpful concepts, &lt;a href="https://github.com/Novvum/36-graphql-concepts"&gt;36-GraphQL-concepts&lt;/a&gt;.&lt;/p&gt;

&lt;h6&gt;
  
  
  about us: &lt;a href="https://novvum.io"&gt;Novvum&lt;/a&gt; is a modern software development agency specializing in both engineering, strategy, &amp;amp; design.
&lt;/h6&gt;

</description>
      <category>graphql</category>
      <category>introspection</category>
      <category>enums</category>
    </item>
    <item>
      <title>TypeGraphQL and GraphQL Nexus — A Look at Code-First APIs 👀</title>
      <dc:creator>Novvum Dev Team</dc:creator>
      <pubDate>Tue, 07 May 2019 19:15:14 +0000</pubDate>
      <link>https://dev.to/novvum/typegraphql-and-graphql-nexus-a-look-at-code-first-apis-6k0</link>
      <guid>https://dev.to/novvum/typegraphql-and-graphql-nexus-a-look-at-code-first-apis-6k0</guid>
      <description>&lt;p&gt;Ever since the Prisma team &lt;a href="https://www.prisma.io/blog/introducing-graphql-nexus-code-first-graphql-server-development-ll6s1yy5cxl5/"&gt;announced GraphQL Nexus&lt;/a&gt;, there has been much interest in code-first schema development. Here at &lt;a href="https://www.novvum.io/"&gt;Novvum&lt;/a&gt;, we think this is a massive step in the right direction, but there has been a lot of confusion over how &lt;a href="https://nexus.js.org/"&gt;Nexus&lt;/a&gt; differs from &lt;a href="https://typegraphql.ml/"&gt;TypeGraphQL&lt;/a&gt;. This post aims to break down the differences and hopefully clarify the confusion.&lt;/p&gt;

&lt;h4&gt;
  
  
  Code-first: A programmatic API for constructing GraphQL schemas
&lt;/h4&gt;

&lt;p&gt;Before we get started, let’s recap why code-first schema development came to be. A popular approach in the Node.js ecosystem for writing a GraphQL server is schema-first or SDL-first. In the schema-first convention, you first define a schema in a Schema Definition Language (SDL) and write resolvers separately. If you were using TypeScript, you would need to define the schema types a second time to be used in your code. Therefore, making a change in the schema requires changes in three different places — the SDL, the resolvers, and the TypeScript types.&lt;/p&gt;

&lt;p&gt;In code-first, the schema is defined &lt;em&gt;in&lt;/em&gt; the code, and the SDL gets generated as an &lt;em&gt;artifact&lt;/em&gt;. You no longer need to keep track of schema changes in multiple locations! 🎊 Which brings us to Nexus and TypeGraphQL. Both libraries aim to help with code-first schema development, but they differ significantly in how they work.&lt;/p&gt;

&lt;h4&gt;
  
  
  Comparing APIs of GraphQL Nexus and TypeGraphQL 🗒
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Types
&lt;/h5&gt;

&lt;p&gt;When building a GraphQL schema, a lot of time is spent writing types. Because of this, both Nexus and TypeGraphQL try to make this process as simple as possible.&lt;/p&gt;

&lt;p&gt;Given the following SDL type:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kNfnvIgN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cb61ac138605d021abd5a79_1%2A9NrTjz7jWH94dh7S2jqS-A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kNfnvIgN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cb61ac138605d021abd5a79_1%2A9NrTjz7jWH94dh7S2jqS-A.png" alt="SDL type image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is how it would be defined in TypeGraphQL and GraphQL Nexus respectively:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CGv6vZqp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cb61ac1d3250d9f255975d0_1%2A8cYgWicNS9zPz_sd52krxQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CGv6vZqp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cb61ac1d3250d9f255975d0_1%2A8cYgWicNS9zPz_sd52krxQ.png" alt="TypeGraphQL1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7wngqk2J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cb61ac1a8c107273dcce60b_1%2ATEQjRCLll5xlov1T8BvGjA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7wngqk2J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cb61ac1a8c107273dcce60b_1%2ATEQjRCLll5xlov1T8BvGjA.png" alt="Nexus1"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h6&gt;
  
  
  TypeGraphQL | Top GraphQL Nexus | Bottom
&lt;/h6&gt;

&lt;p&gt;As you can see, the APIs of the two libraries are very different. TypeGraphQL uses classes and relies on an experimental TypeScript feature called &lt;a href="https://www.typescriptlang.org/docs/handbook/decorators.html"&gt;decorators&lt;/a&gt; (the lines of code that start with the @ symbol). GraphQL Nexus uses native JavaScript syntax.&lt;/p&gt;

&lt;p&gt;With TypeGraphQL, the TypeScript type is simply the User class that we write. It also integrates well with other decorator-based libraries like &lt;a href="https://github.com/typeorm/typeorm"&gt;TypeORM&lt;/a&gt;, &lt;a href="https://github.com/RobinBuschmann/sequelize-typescript"&gt;sequelize-typescript&lt;/a&gt; or &lt;a href="https://github.com/szokodiakos/typegoose"&gt;Typegoose&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On the other hand, Nexus auto-generates type-definitions as we develop, and infers them in our code, giving us IDE completion and type error catching out of the box. It also has seamless integration with various databases with the upcoming &lt;a href="https://github.com/prisma/yoga2"&gt;Yoga 2&lt;/a&gt;. UPDATE: &lt;a href="https://www.prisma.io/blog/using-graphql-nexus-with-a-database-pmyl3660ncst"&gt;Here&lt;/a&gt; is a blog post outlining how to integrate GraphQL Nexus with Prisma.&lt;/p&gt;

&lt;h5&gt;
  
  
  Resolvers
&lt;/h5&gt;

&lt;p&gt;Okay, so both libraries are very straightforward when it comes to defining types and eliminating redundant code between the schema definition and TypeScript types. Now, how would we write the resolvers? This is where the two libraries take very different approaches.&lt;/p&gt;

&lt;p&gt;Here is how we would add resolvers for our User type in both libraries:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uhMhJFDV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cb61ac1cc44c0b52e3b7b03_1%2AEUoMvvGBGHf0g5hdcuwePQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uhMhJFDV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cb61ac1cc44c0b52e3b7b03_1%2AEUoMvvGBGHf0g5hdcuwePQ.png" alt="Resolver1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--15TclLId--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cb61ac1de49b87d4c9c90d0_1%2Au90eCZeVUxQ7dVC4PN3n0A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--15TclLId--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://assets.website-files.com/5c2fa00d1b7e00754f79fd3e/5cb61ac1de49b87d4c9c90d0_1%2Au90eCZeVUxQ7dVC4PN3n0A.png" alt="Resolver2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  TypeGraphQL | Top: GraphQL Nexus | Bottom
&lt;/h6&gt;

&lt;p&gt;With TypeGraphQL, the resolvers live separately from the type definition, similar to the SDL-first paradigm (EDIT: I stand &lt;a href="https://twitter.com/typegraphql/status/1118946711102197760"&gt;corrected&lt;/a&gt;. It is possible to &lt;a href="https://github.com/19majkel94/type-graphql/blob/v0.17.1/examples/simple-usage/recipe-type.ts#L25-L33"&gt;define resolvers in the same location&lt;/a&gt; as the type definition). The resolver for the posts field is defined using the @FieldResolver() decorator. You would add fields for the root Query and Mutation by using the @Query(returns =&amp;gt; User) and @Mutation(returns =&amp;gt; User) decorators respectively.&lt;/p&gt;

&lt;p&gt;With GraphQL Nexus, the resolvers are part of the type definition. Another bonus is that we get code completion as we write the resolvers since Nexus is auto-generating the TypeScript types for the resolvers.&lt;/p&gt;

&lt;h4&gt;
  
  
  A Closer Look at the API Design Decisions 🔭
&lt;/h4&gt;

&lt;p&gt;I will let the two libraries speak for themselves from their docs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://typegraphql.ml/docs/introduction.html#why"&gt;TypeGraphQL&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;To add a new field to our entity, we have to jump through all the files: modify the entity class, then modify the schema, and finally update the interface. The same goes with inputs or arguments: it’s easy to forget to update one of them or make a mistake with a type. Also, what if we’ve made a typo in a field name? The rename feature (F2) won’t work correctly.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;TypeGraphQL comes to address these issues, based on experience from over a year of developing GraphQL APIs in TypeScript. The main idea is to have only one source of truth by defining the schema using classes and a bit of decorator help. Additional features like dependency injection, validation and auth guards help with common tasks that would normally have to be handled by ourselves.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nexus.js.org/docs/why-graphql-nexus"&gt;GraphQL Nexus&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The core idea of GraphQL Nexus draws from basing the schema off the SDL — keeping things declarative and simple to understand. It allows you to reference the type names as string literals rather than always needing to import to reference types (you can do that too if you prefer).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By combining automatic type generation with some of the more powerful features of TypeScript — type merging, conditional types, and type inference, we can know exactly which type names we are referring to and able to use throughout our code. We can know both the parameters and the return type of resolvers without providing any type annotation. It takes a little getting used to, but it ends up leading to a great feedback loop of the types annotating themselves.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Summary: Which One to Choose?
&lt;/h4&gt;

&lt;p&gt;I hope these examples helped you understand how different the two libraries are. Let’s take a look at some of the tradeoffs of each library.&lt;/p&gt;

&lt;h5&gt;
  
  
  TypeGraphQL
&lt;/h5&gt;

&lt;p&gt;Pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduces the number of places to keep track of your schema from three to two or one. TypeScript types and schema types are combined, but resolvers can either be defined separately or alongside the type definition.&lt;/li&gt;
&lt;li&gt;Has been around longer, so at the time of writing, it has more features like field validation and authorization.&lt;/li&gt;
&lt;li&gt;What you see is what you get when it comes to TypeScript types.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Works only with TypeScript since it relies on &lt;a href="https://github.com/rbuckton/reflect-metadata"&gt;metadata reflection&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The way we annotate types feels redundant when defining fields and resolvers which could lead to silent mismatch errors. More details &lt;a href="https://github.com/19majkel94/type-graphql/issues/296"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;NOTE: If you are currently using TypeGraphQL and it is providing value for you or your team, please &lt;a href="https://opencollective.com/typegraphql"&gt;donate&lt;/a&gt; to them!&lt;/p&gt;

&lt;h5&gt;
  
  
  GraphQL Nexus
&lt;/h5&gt;

&lt;p&gt;Pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduces the number of places to keep track of your schema from three to one. The schema and TypeScript types and resolvers are in one place.&lt;/li&gt;
&lt;li&gt;Sticks to using standard JavaScript syntax and generates TypeScript types, so it works with both languages.&lt;/li&gt;
&lt;li&gt;Autocompletion and type-checking support for IDEs provide a great developer experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The younger of the two libraries, so it is missing some useful features. Some are on &lt;a href="https://nexus.js.org/docs/future-features"&gt;the horizon&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Since it relies on type generation, the server has to be running while developing. More info &lt;a href="https://github.com/prisma/nexus/issues/77"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Which one we prefer 🙌
&lt;/h4&gt;

&lt;p&gt;At Novvum, we have been using Nexus pretty extensively, and we migrated &lt;a href="https://github.com/Novvum/MarvelQL"&gt;MarvelQL&lt;/a&gt;, a GraphQL wrapper around the Marvel API, to use it. After also trying TypeGraphQL, we feel that Nexus has been much friendlier to work with, given us more flexibility, and enabled us to move more quickly. However, this is what works well for us, and we understand that all teams operate differently.&lt;/p&gt;

&lt;h4&gt;
  
  
  Let us know what you think ✍️
&lt;/h4&gt;

&lt;p&gt;I hope this post proved helpful for those who were not sure of what the differences were between the two libraries. If there is still confusion, please &lt;a href="https://www.novvum.io/contact-us"&gt;reach out&lt;/a&gt; to us! &lt;/p&gt;

&lt;h6&gt;
  
  
  about us: &lt;a href="https://www.novvum.io/"&gt;Novvum&lt;/a&gt; is a modern software development agency specializing in both engineering, strategy, &amp;amp; design.
&lt;/h6&gt;

</description>
      <category>graphql</category>
      <category>codefirst</category>
      <category>typegraphql</category>
      <category>graphqlnexus</category>
    </item>
    <item>
      <title>Implementing Authentication using JWT, Bcrypt and GraphQL Nexus</title>
      <dc:creator>Novvum Dev Team</dc:creator>
      <pubDate>Thu, 02 May 2019 21:13:55 +0000</pubDate>
      <link>https://dev.to/novvum/implementing-authentication-using-jwt-bcrypt-and-graphql-nexus-29n6</link>
      <guid>https://dev.to/novvum/implementing-authentication-using-jwt-bcrypt-and-graphql-nexus-29n6</guid>
      <description>&lt;p&gt;You’ve finished coding the skeleton for your application, but it’s missing one thing — authentication. This can be added using &lt;a href="https://jwt.io/"&gt;JSON Web Tokens&lt;/a&gt; and Bcrypt. The basis of this tutorial should be similar for most schema construction frameworks, but we will be using &lt;a href="https://nexus.js.org/"&gt;GraphQL Nexus&lt;/a&gt;. We’re also using &lt;a href="https://www.prisma.io/"&gt;Prisma&lt;/a&gt; as our ORM, but any other ORM or database would work.&lt;/p&gt;

&lt;p&gt;This tutorial assumes you have knowledge of GraphQL mutations, queries, resolvers, and context- If you don’t know GraphQL, &lt;a href="https://howtographql.com/"&gt;How to GraphQL&lt;/a&gt; is a great place to start.&lt;/p&gt;

&lt;p&gt;The final application will allow users to create an account and log in by storing and using a JSON Web Token. JWTs are strings that contain information to transfer between parties and are a great way to authenticate users because they can securely store user information and provide a digital signature.&lt;/p&gt;

&lt;p&gt;Our application will allow users to log in and register using these JWTs. On the backend, we will create a payload, add a JWT secret, and set up login and signup mutations to properly generate authorization headers. On the frontend, we’ll pass an authorization token into our headers, and set up our queries to get the current logged in user.&lt;/p&gt;

&lt;h4&gt;
  
  
  Backend
&lt;/h4&gt;

&lt;h4&gt;
  
  
  1. Installing Our Tools 🛠
&lt;/h4&gt;

&lt;p&gt;First thing’s first, we’ll need to install Bcrypt and JSON Web Tokens!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add bcrypt jsonwebtoken
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now you’re ready to get started✨&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Creating our JWT Secret 🗝️
&lt;/h4&gt;

&lt;p&gt;We can set up our JWT secret- in our &lt;code&gt;config.ts&lt;/code&gt; file, the following was added:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default {  
  ...  
  jwt: {  
    JWT_SECRET: 'super-secret',  
  },  
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Creating the Payload 🚚
&lt;/h4&gt;

&lt;p&gt;For us to properly return the token and user information to the requester, we need to set up a payload.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const UserLoginPayload = objectType({  
  name: 'UserLoginPayload',  
  definition: t =&amp;amp;gt; {  
    t.field('user', {  
      type: 'User',  
    })  
    t.string('token')  
  },  
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What we’re doing here is creating an object type named  &lt;code&gt;userLoginPayload&lt;/code&gt;. We define the type as being able to return our &lt;code&gt;User&lt;/code&gt; field, along with the token generated when the user registers or logs in.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Setting up the Login and Signup Mutations 🚪🚶
&lt;/h4&gt;

&lt;p&gt;To set up user registration and login, we create two new mutation fields, &lt;code&gt;userLogin&lt;/code&gt; and &lt;code&gt;userRegister&lt;/code&gt;. We can set the return type to &lt;code&gt;UserLoginPayload&lt;/code&gt; to return the &lt;code&gt;User&lt;/code&gt; and a &lt;code&gt;token&lt;/code&gt;, and our arguments are the username and password collected from a form in the frontend. Here is what the mutations would look like in GraphQL Nexus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const userLogin = mutationField('userLogin', {  
  type: UserLoginPayload,  
  args: {  
    username: stringArg({ required: true }),  
    password: stringArg({ required: true }),  
  },  
})

export const userRegister = mutationField('userRegister', {  
  type: UserLoginPayload,  
  args: {  
    username: stringArg({ required: true }),  
    password: stringArg({ required: true }),  
  },  
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After this, a resolver is added to the mutations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const userLogin = mutationField('userLogin', {  
  type: UserLoginPayload,  
  args: {  
    username: stringArg({ required: true }),  
    password: stringArg({ required: true }),  
  },  
  resolve: async (root, args, context, info) =&amp;amp;gt; {  
    try {  
      const { password, ...user } = await context.prisma.user({  
        where: {  
          userName: args.username,  
        },  
      })  
      var validpass = await bcrypt.compareSync(args.password, password)  
      if (validpass) {  
        const token = jwt.sign(user, config.jwt.JWT_SECRET)  
        return {  
          user: user,  
          token,  
        }  
      }  
      return null  
    } catch (e) {  
      console.log(e)  
    }  
  },  
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We’ve added our resolver. This might be a bit overwhelming, so let’s break it up into pieces.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { password, ...user } = await context.prisma.user({  
        where: {  
          userName: args.username,  
        },  
      })
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here, we’re trying to get &lt;code&gt;User&lt;/code&gt; data. &lt;code&gt;await context.prisma.users({where: {userName: args.username}&lt;/code&gt; gets our &lt;code&gt;User&lt;/code&gt; information from the database, storing the information in &lt;code&gt;password, ...user&lt;/code&gt;. We've separated the password so it won't be included in our user variable or the JSON Web Token data, as shown in the next step.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var validpass = await bcrypt.compareSync(args.password, password)  
      if (validpass) {  
        const token = jwt.sign(user, config.jwt.JWT_SECRET)  
        return {  
          user: user,  
          token,  
        }  
      }  
      return null
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We use Bcrypt to compare to see if our password values are equal. If the passwords match, a JWT is generated using our JWT secret from the config file and &lt;code&gt;user&lt;/code&gt;. (If we didn't separate the password data beforehand, it would have been returned with the user data and stored in the JWT 😱!) Though at last, we're now returning our payload (the &lt;code&gt;user&lt;/code&gt; data along with the JWT)!&lt;/p&gt;

&lt;p&gt;The process for registration is relatively similar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const userRegister = mutationField('userRegister', {  
  type: UserLoginPayload,  
  args: {  
    username: stringArg({ required: true }),  
    password: stringArg({ required: true }),  
  },  
  resolve: async (root, args, context) =&amp;amp;gt; {  
    try {  
      const existingUser = await context.prisma.user({  
        where: {  
          userName: args.username,  
        },  
      })  
      if (existingUser) {  
        throw new Error('ERROR: Username already used.')  
      }  
      var hash = bcrypt.hashSync(args.password, 10)

      const { password, ...register } = await context.prisma.createUser({  
        userName: args.username,  
        password: hash,  
      })  
      const token = jwt.sign(register, config.jwt.JWT_SECRET)  
      return {  
        user: register,  
        token: token,  
      }  
    } catch (e) {  
      console.log(e)  
      return null  
    }  
  },  
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let’s break this up again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const existingUser = await context.prisma.user({  
        where: {  
          userName: args.username,  
        },  
      })  
      if (existingUser) {  
        throw new Error('ERROR: Username already used.')  
      }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Previously, we queried to see if a username existed. This is relatively the same, only now we are throwing an error if something is returned because each username should be unique.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var hash = bcrypt.hashSync(args.password, 10)

      const { password, ...register } = await context.prisma.createUser({  
        userName: args.username,  
        password: hash,  
      })
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We hash the password passed into the form using bcrypt, passing in the password and the salt length we want to generate. After that, the &lt;code&gt;createUser&lt;/code&gt; mutation makes a new user with our username and newly hashed password.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const token = jwt.sign(register, config.jwt.JWT_SECRET)  
      return {  
        user: register,  
        token: token,  
      }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The payload is generated and returned in the same way as the user login.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Adding User to the Context 🧮
&lt;/h4&gt;

&lt;p&gt;Our user can now log in and register! Now we can create a query and viewer field to return that information to the frontend.&lt;/p&gt;

&lt;p&gt;Let’s start out by adding the current user to the context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export interface Context {  
  prisma: Prisma  
  currentUser: User  
}

export default async ({ req }) =&amp;amp;gt; {  
  const currentUser = await getUser(  
    req.get('Authorization'),  
    config.jwt,  
    prisma,  
  )  
  return {  
    prisma,  
    currentUser  
  }  
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here, we’re adding the variable &lt;code&gt;currentUser&lt;/code&gt; of type &lt;code&gt;User&lt;/code&gt; to be exported from our &lt;code&gt;Context&lt;/code&gt;. We can use a &lt;code&gt;getUser&lt;/code&gt; function (we'll go over how to make this function in the next step- in summary, it returns our &lt;code&gt;User&lt;/code&gt; type) to return our user's information by passing in our token with &lt;code&gt;req.get('Authorization')&lt;/code&gt; (which fetches our token from our header), our JWT secret, and the Prisma client.&lt;/p&gt;

&lt;h4&gt;
  
  
  6. Creating a getUser Function 👶
&lt;/h4&gt;

&lt;p&gt;Because we want to query for user information in our application, we need to get our user’s token from the headers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default async (authorization, secrets, prisma: Prisma) =&amp;amp;gt; {  
  const bearerLength = 'Bearer '.length  
  if (authorization &amp;amp;&amp;amp; authorization.length &amp;amp;gt; bearerLength) {  
    const token = authorization.slice(bearerLength)  
    const { ok, result } = await new Promise(resolve =&amp;amp;gt;  
      jwt.verify(token, secrets.JWT_SECRET, (err, result) =&amp;amp;gt; {  
        if (err) {  
          resolve({  
            ok: false,  
            result: err,  
          })  
        } else {  
          resolve({  
            ok: true,  
            result,  
          })  
        }  
      }),  
    )  
    if (ok) {  
      const user = await prisma.user({  
        id: result.id,  
      })  
      return user  
    } else {  
      console.error(result)  
      return null  
    }  
  }  
  return null  
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let’s go through this step by step.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const bearerLength = 'Bearer '.length  
  if (authorization &amp;amp;&amp;amp; authorization.length &amp;amp;gt; bearerLength) {  
    const token = authorization.slice(bearerLength)  
    ...  
  }  
  return null  
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here we have some basic error checking to see if the token is longer than our &lt;code&gt;Bearer&lt;/code&gt; string- If it is, we can extract the token by slicing off the &lt;code&gt;Bearer&lt;/code&gt; string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { ok, result } = await new Promise(resolve =&amp;amp;gt;  
      jwt.verify(token, secrets.JWT_SECRET, (err, result) =&amp;amp;gt; {  
        if (err) {  
          resolve({  
            ok: false,  
            result: err,  
          })  
        } else {  
          resolve({  
            ok: true,  
            result,  
          })  
        }  
      })  
    )
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now we are verifying the token with our secret, and resolving our promise with whether the passed in token was valid or not, along with the &lt;code&gt;result&lt;/code&gt; from our JWT (which is our &lt;code&gt;user&lt;/code&gt; type).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (ok) {  
      const user = await prisma.user({  
        id: result.id,  
      })  
      return user  
    } else {  
      console.error(result)  
      return null  
    }  
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Lastly, if the token was valid, we query for the user with the ID we got from our token and return it!&lt;/p&gt;

&lt;h4&gt;
  
  
  7. Creating a User Query and Viewer Field 🔬
&lt;/h4&gt;

&lt;p&gt;We can create a viewer field and user query so we are able to query for the currently logged in user’s information in our application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;t.string('getCurrentUser', {  
  resolve: async (root, args, context, info) =&amp;amp;gt; {  
    return context.prisma.user  
  },  
})
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can create a new query, &lt;code&gt;getCurrentUser&lt;/code&gt;- this returns the value of what we got in our &lt;code&gt;Context&lt;/code&gt; function, making it so we can now easily query for whatever user is currently logged in!&lt;/p&gt;

&lt;p&gt;Lastly, we should add a &lt;code&gt;viewer&lt;/code&gt; field to our query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;t.field('viewer', {  
      type: 'User',  
      nullable: true,  
      resolve: (root, args, context) =&amp;amp;gt; {  
        return context.currentUser  
      },  
    })
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This simply returns the &lt;code&gt;currentUser&lt;/code&gt; that we added to our context.&lt;/p&gt;

&lt;h4&gt;
  
  
  Frontend
&lt;/h4&gt;

&lt;h4&gt;
  
  
  1. Login and Registration 💎
&lt;/h4&gt;

&lt;p&gt;Now that our backend is complete, we can implement a simple frontend solution using the resolvers we created in the backend.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const SIGNUP_MUTATION = gql`  
  mutation UserRegister($username: String!, $password: String!) {  
    userRegister(username: $username, password: $password) {  
      user {  
        id  
        userName  
      }  
      token  
    }  
  }  
`;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Here is a simple signup mutation that creates a new user when the form is submitted. We are using the &lt;code&gt;userRegister&lt;/code&gt; function that we created on the backend, and simply passing in a username and password while returning any desired information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;amp;lt;Mutation  
    mutation={SIGNUP_MUTATION}  
    onCompleted={data =&amp;amp;gt; _confirm(data)}  
  &amp;amp;gt;  
...  
&amp;amp;lt;/Mutation&amp;amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, we can add the signup mutation to our &lt;code&gt;Mutation&lt;/code&gt; component provided by &lt;code&gt;react-apollo&lt;/code&gt;. When the mutation is completed, we call the function &lt;code&gt;_confirm&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_confirm = async data =&amp;amp;gt; {  
  const { token } = data.userLogin;  
  this._saveUserData(token);  
};

_saveUserData = async token =&amp;amp;gt; {  
  try {  
    await AsyncStorage.setItem(AUTH_TOKEN, token);  
  } catch (e) {  
    console.log("ERROR: ", e);  
  }  
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;What our &lt;code&gt;_confirm&lt;/code&gt; function does is take the &lt;code&gt;data&lt;/code&gt; we were returned from our mutation and extracts the token from it, passing it to &lt;code&gt;_saveUserData&lt;/code&gt;. This function stores the &lt;code&gt;token&lt;/code&gt; in &lt;code&gt;AsyncStorage&lt;/code&gt; (if you're not developing using Native, the token would be stored in &lt;code&gt;LocalStorage&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;WARNING: As a side note, using localStorage to store our JWT isn’t the best practice in production- you can read more about that &lt;a href="https://github.com/howtographql/howtographql/issues/550"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;The process for logging in is extremely similar, we would just swap out our &lt;code&gt;SIGNUP_MUTATION&lt;/code&gt; with our &lt;code&gt;LOGIN_MUTATION&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Inserting the token into the header 💯
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const authLink = setContext(async (_, { headers }) =&amp;amp;gt; {  
  const token = await AsyncStorage.getItem(AUTH_TOKEN);  
  return {  
    headers: {  
      ...headers,  
      authorization: token ? `Bearer ${token}` : ""  
    }  
  };  
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We are using &lt;code&gt;apollo-link-context&lt;/code&gt;'s &lt;code&gt;setContext&lt;/code&gt; function to set the headers of our application. We are getting our authorization token from &lt;code&gt;AsyncStorage&lt;/code&gt; and then storing it in our header.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Querying for User Info 🙆
&lt;/h4&gt;

&lt;p&gt;Because of all of our hard work, we can query for the user’s information anywhere we want in the app- Yep, it’s that simple!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const GET_USER = gql`  
  query getUser {  
    viewer {  
      id  
    }  
  }  
`;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;And with that, your authentication is now set up! We have now created resolvers to return the desired payload and can query for the current logged in user anywhere in the application. This tutorial was inspired by Spencer Carli’s great tutorial, &lt;a href="https://medium.com/handlebar-labs/graphql-authentication-with-react-native-apollo-part-1-2-9613aacd80b3"&gt;GraphQL Authentication with React Native &amp;amp; Apollo&lt;/a&gt; — give it a look if you’d like a more in-depth look on the things we went over in this tutorial. If you have any questions or suggestions, feel free to leave a comment, reach out to us on &lt;a href="http://twitter.com/novvumio"&gt;Twitter&lt;/a&gt;, or over on &lt;a href="http://novvum.io"&gt;our website&lt;/a&gt;. Thank you!&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>javascript</category>
      <category>authentication</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Introducing GraphQL Birdseye 🦅</title>
      <dc:creator>Novvum Dev Team</dc:creator>
      <pubDate>Tue, 30 Apr 2019 19:06:52 +0000</pubDate>
      <link>https://dev.to/novvum/introducing-graphql-birdseye-33i6</link>
      <guid>https://dev.to/novvum/introducing-graphql-birdseye-33i6</guid>
      <description>&lt;p&gt;We are proud to officially release &lt;a href="https://github.com/Novvum/graphql-birdseye" rel="noopener noreferrer"&gt;graphql-birdseye&lt;/a&gt;! Birdseye allows you to view any GraphQL schema as a dynamic and interactive graph. Try it out on our &lt;a href="https://birdseye.novvum.io/" rel="noopener noreferrer"&gt;demo site&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.website-files.com%2F5c2fa00d1b7e00754f79fd3e%2F5cbf5dcf3045160bf4fcbeca_1%2AQcqM1X6b4wlo2AUWHn_5zQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.website-files.com%2F5c2fa00d1b7e00754f79fd3e%2F5cbf5dcf3045160bf4fcbeca_1%2AQcqM1X6b4wlo2AUWHn_5zQ.gif" alt="birdseye demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Birdseye uses a “fog of war” 🌁 navigation style which dynamically zooms to show a portion of the schema at a time. This significantly simplifies the process of finding related types when compared to displaying the entire schema at once.&lt;/p&gt;

&lt;h4&gt;
  
  
  Getting started
&lt;/h4&gt;

&lt;p&gt;You can get started with birdseye by reading the instructions &lt;a href="https://github.com/Novvum/graphql-birdseye#installation" rel="noopener noreferrer"&gt;here&lt;/a&gt;. The library is currently available as a React component, but if we get requests for other frameworks like Angular or Vue, we would be happy to work on those as well 🙂.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why we built it
&lt;/h4&gt;

&lt;p&gt;We were inspired to make a GraphQL schema visualization tool that can you can add to other sites and packages. We have seen a couple of other excellent tools like &lt;a href="https://brbb.github.io/graphql-rover/" rel="noopener noreferrer"&gt;graphql-rover&lt;/a&gt;, &lt;a href="https://www.npmjs.com/package/graphql-voyager" rel="noopener noreferrer"&gt;graphql-voyager&lt;/a&gt; and &lt;a href="https://graphqleditor.com/" rel="noopener noreferrer"&gt;graphql editor&lt;/a&gt;. We originally planned to integrate voyager with &lt;a href="https://github.com/prisma/graphql-playground" rel="noopener noreferrer"&gt;graphql-playground&lt;/a&gt;, but it would have added 1.2 MB to the package. This bundle size made the library very difficult to integrate with any other tools.&lt;/p&gt;

&lt;p&gt;To solve this problem we created Birdseye which is &lt;em&gt;lightweight&lt;/em&gt; and works well with other tools. In this process, we also made some helpful changes to the user experience (📣 to &lt;a href="https://www.prisma.io/" rel="noopener noreferrer"&gt;Prisma&lt;/a&gt; for helping brainstorm the “fog of war” navigation).&lt;/p&gt;

&lt;h4&gt;
  
  
  How we built it
&lt;/h4&gt;

&lt;p&gt;When we first started, we spent the first month trying out various diagramming libraries like &lt;a href="https://github.com/tgdwyer/WebCola" rel="noopener noreferrer"&gt;WebCola&lt;/a&gt;, &lt;a href="http://js.cytoscape.org/" rel="noopener noreferrer"&gt;Cytoscape.js&lt;/a&gt;, &lt;a href="https://github.com/dagrejs/dagre" rel="noopener noreferrer"&gt;dagre&lt;/a&gt; and many more. Some libraries supported a portion of the features while others supported a different subset. At this point, we considered building our own visualization library, and we quickly realized how crazy that would be 😅.&lt;/p&gt;

&lt;p&gt;We decided to keep looking and finally came across &lt;a href="https://resources.jointjs.com/docs/jointjs/v2.2/joint.html" rel="noopener noreferrer"&gt;JointJS&lt;/a&gt; 🎊. It gave us a nice API to be able to define custom shapes and provided excellent layout and link routing algorithms. It also gave us the ability to modify these algorithms according to our needs. Best of all, it added very little to the bundle size (~70kb).&lt;/p&gt;

&lt;p&gt;Having settled on JointJS, the rest of the project focused on understanding the API in more detail and using it to build out the library. Some of the other tools we used to make this happen were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.typescriptlang.org/" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt;: our go-to language whenever we can use it. The type-safety saves us from a lot of trouble by catching simple issues early on.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://rollupjs.org/guide/en" rel="noopener noreferrer"&gt;Rollup&lt;/a&gt;: A bundler that specializes in packaging libraries.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ariutta/svg-pan-zoom" rel="noopener noreferrer"&gt;svg-pan-zoom&lt;/a&gt;: Simple pan/zoom solution for SVGs in HTML. It adds events listeners for mouse scroll, double-click, and pan.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Where we go from here
&lt;/h4&gt;

&lt;p&gt;We are committed to improving this library and make it the go-to for visualizing your schema. We would love to hear your feedback so we can make it even better and we always welcome contributions. Some things we are planning to work on are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Improve performance for larger schemas&lt;/li&gt;
&lt;li&gt;Option to toggle zoom navigation style&lt;/li&gt;
&lt;li&gt;Smoother UI transitions and interactions&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Tell us what you think 🤔
&lt;/h4&gt;

&lt;p&gt;If you like Birdseye, please follow us on twitter (&lt;a href="https://twitter.com/novvumio" rel="noopener noreferrer"&gt;@novvumio&lt;/a&gt;) and give us a star 🌟 on &lt;a href="https://github.com/Novvum/graphql-birdseye" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;! If you find any issues, we’d love to fix them! You can submit them &lt;a href="https://github.com/Novvum/graphql-birdseye/issues" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h6&gt;
  
  
  about us: &lt;a href="https://novvum.io" rel="noopener noreferrer"&gt;Novvum&lt;/a&gt; is a modern software development agency specializing in both engineering, strategy, &amp;amp; design.
&lt;/h6&gt;

</description>
      <category>graphql</category>
      <category>react</category>
      <category>visualization</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
