<?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: Cassie Rosner</title>
    <description>The latest articles on DEV Community by Cassie Rosner (@cerosner).</description>
    <link>https://dev.to/cerosner</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F158556%2Fc2aaceb4-31b5-4733-9aaf-211fb3d4e098.gif</url>
      <title>DEV Community: Cassie Rosner</title>
      <link>https://dev.to/cerosner</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cerosner"/>
    <language>en</language>
    <item>
      <title>You want to learn GraphQL, and you want to have learned it yesterday</title>
      <dc:creator>Cassie Rosner</dc:creator>
      <pubDate>Wed, 01 May 2019 19:17:44 +0000</pubDate>
      <link>https://dev.to/cerosner/you-want-to-learn-graphql-and-you-want-to-have-learned-it-yesterday-3pk4</link>
      <guid>https://dev.to/cerosner/you-want-to-learn-graphql-and-you-want-to-have-learned-it-yesterday-3pk4</guid>
      <description>&lt;h1&gt;
  
  
  GraphQL is quickly becoming the show runner in how services leverage their APIs.
&lt;/h1&gt;

&lt;p&gt;Because it is a &lt;em&gt;specification&lt;/em&gt; rather than an all-encompassing tool, GraphQL can be tailored on top of any platform by use of individual libraries made for a variety of servers. Developers can &lt;strong&gt;describe their data&lt;/strong&gt;, ask for &lt;strong&gt;exactly what they want&lt;/strong&gt;, and &lt;strong&gt;get predictable results&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Okay, cool. So, what's the big deal?&lt;/p&gt;

&lt;h2&gt;
  
  
  Origins
&lt;/h2&gt;

&lt;p&gt;If you've seen my previous &lt;a href="https://dev.to/cerosner/the-jam-stack-57l9"&gt;post&lt;/a&gt;, you know I like to begin with an overview on how these new technologies arise and why they are so crucial to the future of software engineering.&lt;/p&gt;

&lt;p&gt;To refresh, &lt;strong&gt;Application Programming Interfaces&lt;/strong&gt; (APIs) expose specific internal data that other services can harness. Just like how user interfaces are meant to guide humans through use of an application, APIs are meant for software to interact with other software through endpoints routed via &lt;strong&gt;Universal Resource Identifiers&lt;/strong&gt; (URIs).&lt;/p&gt;

&lt;p&gt;Unlike humans, computers don't need fancy buttons or legible font-styles to navigate an API, but programmers were still left with a harsh environment to efficiently manipulate code that would command these machines to do just that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple Object Access Protocol&lt;/strong&gt; (SOAP) was pretty much all there was to construct these interfaces. It consisted of manually curated XML documents that had to abide by strict protocol specifications, and usually didn't respond with error stacks to help find existing bugs.&lt;/p&gt;

&lt;p&gt;The need for an organized, less complex standard  birthed the RESTful architecture most modern web services use today.&lt;/p&gt;

&lt;h2&gt;
  
  
  REST
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Representational State Transfer&lt;/strong&gt; (REST) is merely an adopted&lt;br&gt;
style for designing APIs over the HTTP protocol, directly accessing the delivery methods that the HTTP protocol provides: &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;These requests determine what happens to the data that gets sent and/or what data gets sent back as a response. If you want just a portion of that data, you have to define more specific URI endpoints, or add query parameters that target such distinctions. This can lead to lengthy, unused endpoint definitions and intricate queries that can easily become a headache for anyone to manage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;GET&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;                  &lt;span class="c1"&gt;// respond with all (root) data&lt;/span&gt;
&lt;span class="nx"&gt;GET&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;             &lt;span class="c1"&gt;// respond with user data&lt;/span&gt;
&lt;span class="nx"&gt;GET&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users/userId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;      &lt;span class="c1"&gt;// specified endpoint for one user's data&lt;/span&gt;
&lt;span class="nx"&gt;GET&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users?id=userId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;   &lt;span class="c1"&gt;// query string for one user's data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose you could do the filtering on the front-end if you set up your API to just send general requests, but this can slow down the application due to excess information being carried over in the payload each time.&lt;/p&gt;

&lt;p&gt;Can you see where we're going with this?&lt;/p&gt;

&lt;h2&gt;
  
  
  GraphQL
&lt;/h2&gt;

&lt;p&gt;GraphQL introduces a query language (hence the "QL") to the front-end, which allows us to condense our code by always sending a &lt;code&gt;POST&lt;/code&gt; request to a single middleware endpoint: &lt;code&gt;('/graphql')&lt;/code&gt;. Unlike &lt;code&gt;GET&lt;/code&gt; requests that are read-only, the &lt;code&gt;POST&lt;/code&gt; delivery method holds a request body that we can construct our queries inside of, to then be sent and interpreted by the GraphQL specifications on the back-end.&lt;/p&gt;

&lt;p&gt;It is a typed language, which means that we can define what our data should look like before our code even runs, making sure that what is returned is exactly what we expect.&lt;/p&gt;

&lt;p&gt;Here's a GraphQL boilerplate for a super simple task app I created using Node.js, Express and PostgreSQL/Sequelize.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;bodyParser&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body-parser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;graphqlHttp&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express-graphql&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;buildSchema&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;graphql&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Tasks&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../database&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bodyParser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/graphql&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;graphqlHttp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;buildSchema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`
    type Task {
      id: ID!
      title: String!
      description: String!  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="cm"&gt;/* ! === not null */&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
    }

    input TaskInput {
      title: String!
      description: String!
    }

    type RootQuery {  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="cm"&gt;/* entry point for fetching data */&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
      tasks: [Task!]!
        &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="cm"&gt;/* returns a list (Array) of Task data types */&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="cm"&gt;/* cannot return 'null' and cannot return an Array with 'null' */&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="cm"&gt;/* add as many endpoints to this object as needed */&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
    }

    type RootMutation {  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="cm"&gt;/* entry point for manipulating data */&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
      createTask(taskInput: TaskInput!): Task!
        &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="cm"&gt;/* custom param 'taskInput' takes a TaskInput data type */&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="cm"&gt;/* returns a Task data type */&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="cm"&gt;/* add as many operations to this object as needed */&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
    }

    schema {
      query: RootQuery  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="cm"&gt;/* points to query entry point */&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
      mutation: RootMutation  &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="cm"&gt;/* points to mutation entry point */&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
    }
  `&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;rootValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;// query the database&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allTasks&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;allTasks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// return all tasks as defined in our RootQuery&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;createTask&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  &lt;span class="c1"&gt;// 'args' is an object of all listed parameters&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;taskInput&lt;/span&gt;  &lt;span class="c1"&gt;// destructuring assignment&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newTask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  &lt;span class="c1"&gt;// assign TaskInput properties to a new task object&lt;/span&gt;
        &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;description&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newTask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// query database to create the new task&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createdTask&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;createdTask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// return new task as defined in our RootMutation&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;graphiql&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;// turn on UI&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;

&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&amp;gt; I'm listening (:`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&amp;gt; http://localhost:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/graphql`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;graphqlHttp()&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This middleware function routes requests through our query parser &lt;code&gt;'/graphql'&lt;/code&gt; endpoint. The requests are handled by the schemas that we define and then forwarded to the associated resolver endpoints that we create.&lt;/p&gt;

&lt;p&gt;It takes an object with these main properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;schema&lt;/code&gt; - points to where we determine what our data should look like&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rootValue&lt;/code&gt; - points to an object of resolver functions that match our schema endpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;buildSchema()&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This function takes a multi-line template literal string that actually defines our schemas. It parses and converts that string to be used by our middleware, which sends our data to the appropriate resolvers for handling. We must adhere to GraphQL command specifications that are looking for certain keywords:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;type&lt;/code&gt; - custom objects

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;NOTE: the type names &lt;code&gt;RootQuery&lt;/code&gt;/&lt;code&gt;RootMutation&lt;/code&gt; are just by convention but they can be called anything you want, as long as your schema points to them&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;input&lt;/code&gt; - specific type of custom object&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;schema&lt;/code&gt; - takes root keywords

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;query&lt;/code&gt; - entry point for &lt;code&gt;GET&lt;/code&gt; requests&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mutation&lt;/code&gt; - entry point for &lt;code&gt;POST/PUT/DELETE&lt;/code&gt; requests&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;graphiql&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The ultimate addition to this API implementation is GraphQL's built-in debugger. &lt;code&gt;GraphiQL&lt;/code&gt; is a UI that can be accessed in the browser to accurately check our endpoints (located at &lt;code&gt;'localhost:${port}/graphql'&lt;/code&gt; while the server is running). Simply add it to the end of our middleware object and turn it on/off with a boolean.&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%2Fpzln6niea3rk7ap656rz.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%2Fpzln6niea3rk7ap656rz.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Query &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt; of all tasks (database is empty)&lt;/p&gt;
&lt;/blockquote&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%2Fcgzcgbaz2bfwrgf0ulgb.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%2Fcgzcgbaz2bfwrgf0ulgb.png"&gt;&lt;/a&gt;&lt;br&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%2F5h5l6682dsyf2mis415u.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%2F5h5l6682dsyf2mis415u.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Manually create tasks in the database&lt;/p&gt;
&lt;/blockquote&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%2F0zdek29uz2knabdwqqwy.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%2F0zdek29uz2knabdwqqwy.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Query &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;title&lt;/code&gt;, and &lt;code&gt;description&lt;/code&gt; of all tasks&lt;/p&gt;
&lt;/blockquote&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%2F2b6ocq9pqmghf6j0lg6a.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%2F2b6ocq9pqmghf6j0lg6a.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Query just the &lt;code&gt;title&lt;/code&gt; of all tasks&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;As endpoints and resolvers grow, breaking these functions into their own modules helps keep things organized, with easy-to-follow paths for maintainability of design structure and overall data quality. It's easy to compare to the standard RESTful paradigm--now we can specify &lt;em&gt;exactly&lt;/em&gt; how we want our data to look by defining variable data types, in turn allowing us to ask for completely unique combinations of data, rendering predictable responses without the overload of gratuitous traffic. This ultimately saves trips between the client-sever cycle for optimized functionality.&lt;/p&gt;

&lt;p&gt;GraphQL is the perfect example to showcase the exponential growth in refining the processes we utilize every day when accessing the web, whether you're a programmer or not!&lt;/p&gt;

&lt;h3&gt;
  
  
  The most fascinating aspect of this evolution, and just software development in general, is the  ability to continually transform; abstraction upon abstraction.
&lt;/h3&gt;

&lt;p&gt;All in the name of Developer Experience (DX), recalling a past instructor's assertion that "most developers create solutions not because they are visionaries, but because they are frustrated." Any enhancement to programming's ease-of-use will pave the way for heightened general accessibility; and the faster we can guide newcomers in grasping these concepts, the faster we can work together in finding valid solutions.&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>api</category>
      <category>softwaredevelopment</category>
      <category>rest</category>
    </item>
    <item>
      <title>The JAM Stack</title>
      <dc:creator>Cassie Rosner</dc:creator>
      <pubDate>Mon, 29 Apr 2019 22:25:33 +0000</pubDate>
      <link>https://dev.to/cerosner/the-jam-stack-57l9</link>
      <guid>https://dev.to/cerosner/the-jam-stack-57l9</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href="https://medium.com/@cerosner/the-jam-stack-f2ef148ef4de"&gt;Link&lt;/a&gt; to original post on Medium.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;i&gt;&lt;strong&gt;JAMstack&lt;/strong&gt;: noun \’jam-stak’\&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Modern web development architecture based on client-side JavaScript, reusable APIs, and prebuilt Markup.&lt;/i&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Before I begin to examine that lovely collection of technical keywords, I’d like to first lay a foundation necessary to empathize with previous archetypal models in order to envision such paradigms of the future.
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1760/1*THIjvw4Yni8JQ6QzvS71LA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1760/1*THIjvw4Yni8JQ6QzvS71LA.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Software bundles, known as “stacks,” are merely an ensemble of collaborative programs used in tandem to accomplish one cohesive goal. A typical stack usually takes an operating system, some middleware, database management, and other varying applications. &lt;strong&gt;LAMP&lt;/strong&gt; is considered one of the classics, if not the most common, which stands for the Linux operating system, the Apache HTTP server, MySQL relational-database management systems, and either the PHP, Python, or Perl programming language.&lt;/p&gt;

&lt;h3&gt;
  
  
  Constructing a stack meant selecting programs that could interact with each other across the front (client) and back (server) ends.
&lt;/h3&gt;

&lt;p&gt;Then along came the &lt;strong&gt;MEAN&lt;/strong&gt; stack — MongoDB, Express.js, AngularJS, and Node.js — which allowed for all components involved to run on just a single programming language: JavaScript. Due to the integration of server-side scripting thanks to Node.js, JavaScript has become an extremely powerful and versatile tool since it can now function on both sides of the stack. Other software solutions can be made from this basic foundation, as I would consider myself skilled in the &lt;strong&gt;NERP&lt;/strong&gt; stack — a Node.js server, Express.js middleware, the React application framework, and PostgreSQL object-relational database management systems (accessed by Sequelize.js)— which is just another combination of JS-centric platforms that was explicitly taught at my time attending the Grace Hopper program under Fullstack Academy.&lt;/p&gt;

&lt;p&gt;The exponential growth of the internet and progressing web services have subsequently shifted the needs of users and developers alike, where higher performance, fierce security, and improved scaling capabilities are all increasingly becoming industry standard. And now cue the &lt;strong&gt;JAM&lt;/strong&gt; stack:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn-images-1.medium.com/max/1760/1*T-bYhp8ZVm6Gc4NSIwQhdA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://cdn-images-1.medium.com/max/1760/1*T-bYhp8ZVm6Gc4NSIwQhdA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript
&lt;/h2&gt;

&lt;p&gt;While we know JS can live across the stack, it’s typically stationed on the frontend by use of frameworks like React, Vue, or Angular. These decorative JS building blocks provide infrastructure for reactive web pages, most notably &lt;strong&gt;SPA&lt;/strong&gt;s (single page applications) that dynamically update through user interaction, processing request/response cycles on the client side. The fluidity of these updates renders smooth and clear user interfaces since the majority of the work occurs right on the browser. However, this can lead to poor &lt;strong&gt;SEO&lt;/strong&gt; (search engine optimization) because these pages access additional data by AJAX requests solely on the frontend, so it’s difficult for Google search bots to scan anything other than a bundler’s entry point at runtime (and we are all well aware of the newly universally-accepted mathematical theorem: more clicks = more $$$).&lt;/p&gt;

&lt;h2&gt;
  
  
  APIs
&lt;/h2&gt;

&lt;p&gt;Application programming interfaces are basically UIs but for software instead of humans. It enables software to essentially “talk” to each other, and handles all the backend, dynamic interactions when implemented in a JAM stack. Without the need of a local server database and excess plugins, hackers are less capable of infiltrating a protected system, especially if an API can leverage a third-party’s heightened security parameters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Markup
&lt;/h2&gt;

&lt;p&gt;Considered the actual content of a website pre-API requests (like general text and images), markup can be delegated to non-programmers in larger scaled projects due to its relatively simple formatting. &lt;strong&gt;SSG&lt;/strong&gt;s (static site generators, like Gatsby.js which works alongside React) are crucial cogs in the mix as they convert markup files into static HTML pages that are built along with the client on startup, delivering a server-side application that loads fast and search engines can parse efficiently, yet still hold the elegant performance of a SPA.&lt;/p&gt;




&lt;h3&gt;
  
  
  JavaScript, APIs, and Markup text are three distinct sets of tools; individual parts that can be constructed to bring out the best in one another.
&lt;/h3&gt;

&lt;p&gt;The way software bundles are conceptualized in this technological climate will continue to change as we discover faster and cheaper ways to deliver content to the masses. The metamorphosis now revolves around these three umbrella-ed enterprises, with each division consisting of many sub-parts adept in solving the problems that they were made to solve. The mixing and matching of components ensures that developers themselves are making the most out of their environments and unique skillsets. The possibilities are quite endless.&lt;/p&gt;

&lt;p&gt;The official JAMstack website specifically states on its home page:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;When we talk about “The Stack,” we no longer talk about operating systems, specific web servers, backend programming languages, or databases.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The JAMstack is not about specific technologies. It’s a new way of building websites and apps that delivers better performance, higher security, lower cost of scaling, and a better developer experience.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With the myriad platforms, languages, and frameworks present in the world today — with many more in development even as you read this, or those left wandering our collective consciousness just waiting to be extrapolated — it can be quite intimidating for a newcomer to familiarize themselves with such an influx of seemingly vital information. Seems like the JAM stack and its abstraction of a once strictly-bound solutions template is something we’d best harness in our perceptual scope.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>api</category>
      <category>jamstack</category>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
