<?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: Soney Mathew</title>
    <description>The latest articles on DEV Community by Soney Mathew (@soneymathew).</description>
    <link>https://dev.to/soneymathew</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%2F217460%2F6f786d79-77fe-4447-bce7-cb767490dc06.jpeg</url>
      <title>DEV Community: Soney Mathew</title>
      <link>https://dev.to/soneymathew</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/soneymathew"/>
    <language>en</language>
    <item>
      <title>Make sure your GraphQL Lists return predictable results!</title>
      <dc:creator>Soney Mathew</dc:creator>
      <pubDate>Mon, 03 Aug 2020 15:41:13 +0000</pubDate>
      <link>https://dev.to/soneymathew/graphql-lies-aka-lists-2lc2</link>
      <guid>https://dev.to/soneymathew/graphql-lies-aka-lists-2lc2</guid>
      <description>&lt;p&gt;Home page of &lt;a href="https://graphql.org/"&gt;https://graphql.org/&lt;/a&gt; states this fact&lt;/p&gt;

&lt;p&gt;Describe your data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Query {
 company(name: String): Company
}
type User {
  name: String
}
type Company {
  name: String
  tagline: String
  # List of board members
  boardMembers: [User] 
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Ask for what you want&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  company(name: "Acme") {
    name
    tagline
    boardMembers {
      name
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Get predictable results&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "data": {
    "company": {
      "name": "Acme",
      "tagline": "Acme is all you need!",
      "boardMembers": [
        {
          "name": "Tom"
        },
        {
          "name": "Jerry"
        }
      ]
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Are you sure? Are you sure you are getting predictable results?&lt;/p&gt;

&lt;p&gt;This API is breaking a fundamental promise given by GraphQL! You simply are not getting predictable results!&lt;/p&gt;

&lt;p&gt;As you scale the number of items returned by the list might become unpredictably large. See the image below for example, there is no predictability in the size of items returned in the list&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iE6rCwA9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ddxrqs0aksjhfj7wrmdv.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iE6rCwA9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ddxrqs0aksjhfj7wrmdv.gif" alt="Unpredictable size of the list"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Give the control back to the client, always set limits. Let the client decide how much they want to fetch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Company {
  name: String
  tagline: String
  # List of board members
  boardMembers(first:Int) : [User] 
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now client can limit the query results to exactly how much they need&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  company(name: "Acme") {
    name
    tagline
    boardMembers(first:3) {
      name
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Refer: &lt;a href="https://graphql.org/learn/pagination/#slicing"&gt;https://graphql.org/learn/pagination/#slicing&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  🙏
&lt;/h1&gt;

</description>
      <category>graphql</category>
      <category>connection</category>
      <category>limit</category>
      <category>pagination</category>
    </item>
    <item>
      <title>Compiled GraphQL - Best thing since sliced bread!</title>
      <dc:creator>Soney Mathew</dc:creator>
      <pubDate>Mon, 18 May 2020 14:51:50 +0000</pubDate>
      <link>https://dev.to/soneymathew/compiled-graphql-best-thing-since-sliced-bread-5hkh</link>
      <guid>https://dev.to/soneymathew/compiled-graphql-best-thing-since-sliced-bread-5hkh</guid>
      <description>&lt;p&gt;OT: &lt;code&gt;Daddy! It's the Best thing since sliced bread!&lt;/code&gt; is a phrase my 5 year old son keeps repeating to me these days.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This post is to explain the concept and merits of compiled GraphQL from a web developer's perspective. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once upon a time there was a Client that never changed, it always made the same request to the server. Server in turn optimised the Query to the DataStore to fetch it efficiently and return it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     ┌──────┐          ┌──────┐          ┌─────────┐
     │Client│          │Server│          │Datastore│
     └──┬───┘          └──┬───┘          └────┬────┘
        │     Request1    │                   │     
        │ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;|                   │     
        │                 │                   │     
        │                 │       Query1      │     
        │                 │  ─ ─ ─ ─ ─ ─ ─ ─ &amp;gt;│     
        │                 │                   │     
        │                 │     Record(s)     │     
        │                 │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─ ─│     
        │                 │                   │     
        │     Response1   │                   │     
        │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─|                   │     
     ┌──┴───┐          ┌──┴───┐          ┌────┴────┐
     │Client│          │Server│          │Datastore│
     └──────┘          └──────┘          └─────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Customers got the best performance possible. Then the world changed, new requirements and designs came at startling pace. Then this happened... again and again...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     ┌──────┐          ┌──────┐            ┌─────────┐
     │Client│          │Server│            │Datastore│
     └──┬───┘          └──┬───┘            └────┬────┘
        │     Request1    │                     │     
        │ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;|                     │     
        │                 │                     │     
        │                 │        Query1       │     
        │                 │ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;|     
        │                 │                     │     
        │                 │ Record(s) for Query1│     
        │                 │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─ ─ ─|      
        │                 │                     │     
        │    Response1    │                     │     
        │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─|                     │     
        │                 │                     │     
        │     Request2    │                     │     
        │ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;|                     │     
        │                 │                     │     
        │                 │        Query2       │     
        │                 │ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;|     
        │                 │                     │     
        │                 │ Record(s) for Query2│     
        │                 │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─ ─ ─      
        │                 │                     │     
        │    Response2    │                     │     
        │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─                      │     
        │                 │                     │     
        │     Request3    │                     │     
        │  ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;                     │     
        │                 │                     │     
        │                 │        Query3       │     
        │                 │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;     
        │                 │                     │     
        │                 │ Record(s) for Query3│     
        │                 │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─ ─ ─      
        │                 │                     │     
        │    Response3    │                     │     
        │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─                      │     
        │                 │                     │     
        │     Request4    │                     │     
        │  ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;                     │     
        │                 │                     │     
        │                 │        Query4       │     
        │                 │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;     
        │                 │                     │     
        │                 │ Record(s) for Query4│     
        │                 │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─ ─ ─      
        │                 │                     │     
        │    Response4    │                     │     
        │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─                      │     
     ┌──┴───┐          ┌──┴───┐            ┌────┴────┐
     │Client│          │Server│            │Datastore│
     └──────┘          └──────┘            └─────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We always delivered changes, but the customers suffered due to the request waterfalls that cause sluggish experience, Server got more stressed. Datastore suffered with all these extra queries.&lt;/p&gt;

&lt;p&gt;Then clients discovered GraphQL. My first introduction to GraphQL was as a great solution to reduce the API waterfall. Some libraries just made it super easy to glue together the backend APIs and abstract it behind a GraphQL schema. Clients rejoiced for it became this!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     ┌──────┐          ┌──────────────┐          ┌──────┐            ┌─────────┐
     │Client│          │GraphQL_Server│          │Server│            │Datastore│
     └──┬───┘          └──────┬───────┘          └──┬───┘            └────┬────┘
        │   GraphQL Request   │                     │                     │     
        │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;                     │                     │     
        │                     │                     │                     │     
        │                     │       Request1      │                     │     
        │                     │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;                     │     
        │                     │                     │                     │     
        │                     │                     │        Query1       │     
        │                     │                     │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;     
        │                     │                     │                     │     
        │                     │                     │ Record(s) for Query1│     
        │                     │                     │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─ ─ ─      
        │                     │                     │                     │     
        │                     │      Response1      │                     │     
        │                     │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─ ─ ─                      │     
        │                     │                     │                     │     
        │                     │       Request2      │                     │     
        │                     │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;                     │     
        │                     │                     │                     │     
        │                     │                     │        Query2       │     
        │                     │                     │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;     
        │                     │                     │                     │     
        │                     │                     │ Record(s) for Query2│     
        │                     │                     │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─ ─ ─      
        │                     │                     │                     │     
        │                     │      Response2      │                     │     
        │                     │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─ ─ ─                      │     
        │                     │                     │                     │     
        │                     │       Request3      │                     │     
        │                     │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;                     │     
        │                     │                     │                     │     
        │                     │                     │        Query3       │     
        │                     │                     │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;     
        │                     │                     │                     │     
        │                     │                     │ Record(s) for Query3│     
        │                     │                     │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─ ─ ─      
        │                     │                     │                     │     
        │                     │      Response3      │                     │     
        │                     │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─ ─ ─                      │     
        │                     │                     │                     │     
        │                     │       Request4      │                     │     
        │                     │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;                     │     
        │                     │                     │                     │     
        │                     │                     │        Query4       │     
        │                     │                     │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;     
        │                     │                     │                     │     
        │                     │                     │ Record(s) for Query4│     
        │                     │                     │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─ ─ ─      
        │                     │                     │                     │     
        │                     │      Response4      │                     │     
        │                     │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─ ─ ─                      │     
        │                     │                     │                     │     
        │   GraphQL Response  │                     │                     │     
        │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─ ─ ─                      │                     │     
     ┌──┴───┐          ┌──────┴───────┐          ┌──┴───┐            ┌────┴────┐
     │Client│          │GraphQL_Server│          │Server│            │Datastore│
     └──────┘          └──────────────┘          └──────┘            └─────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The High speed network between GraphQL_Server and Server improved things quite a bit. Clients moved faster when changes came their way. Some Datastores made it cheaper to fetch all-the-things in one Query. Then I saw this strategy happen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     ┌──────┐          ┌──────────────┐                                ┌─────────┐
     │Client│          │GraphQL_Server│                                │Datastore│
     └──┬───┘          └──────┬───────┘                                └────┬────┘
        │   GraphQL Request   │                                             │     
        │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;                                             │     
        │                     │                                             │     
        │                     │─ ─ ┐                                              
        │                     │    | Convert GraphQL Query to Datastore query     
        │                     │&amp;lt; ─ ┘                                              
        │                     │                                             │     
        │                     │                Optimal Query1               │     
        │                     │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;     
        │                     │                                             │     
        │                     │             Record(s) for Query1            │     
        │                     │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─      
        │                     │                                             │     
        │   GraphQL Response  │                                             │     
        │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─ ─ ─                                              │     
     ┌──┴───┐          ┌──────┴───────┐                                ┌────┴────┐
     │Client│          │GraphQL_Server│                                │Datastore│
     └──────┘          └──────────────┘                                └─────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This was very efficient when possible. But there are a few things that kept repeating every request. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The client kept building the GraphQL query for every request. &lt;/li&gt;
&lt;li&gt;The server kept translating the GraphQL Query to Datastore Query every request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compiled GraphQL is just one more step ahead in this journey to avoid this two runtime overheads that are predictable at build time.&lt;/p&gt;

&lt;p&gt;At build time, we persist the queries that get's repeated every request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     ┌────────────┐          ┌───────────┐          ┌────────────┐                       
     │Client_Build│          │Query_Store│          │Server_Build│                       
     └─────┬──────┘          └─────┬─────┘          └─────┬──────┘                       
           │────┐                                         │                              
           │    │ Generate persisted                      │                              
           │&amp;lt;───┘ Query PQ1                               │                              
           │                                              │                              
           │                       │                      │                              
           │   Persist Query PQ1   │                      │                              
           │ ──────────────────────&amp;gt;                      │                              
           │                       │                      │                              
           │                       │ Get Persisted Queries│                              
           │                       │ &amp;lt;─────────────────────                              
           │                       │                      │                              
           │                       │                      │────┐                         
           │                       │                      │    │ Generate Datastore query
           │                       │                      │&amp;lt;───┘ DQ1 from PQ1            
           │                       │                      │                              
           │                       │                      │                              
           │                       │   Persist Query      │                              
           │                       │   DQ1 Mapped to PQ1  │                              
           │                       │ &amp;lt;─────────────────────                              
     ┌─────┴──────┐          ┌─────┴─────┐          ┌─────┴──────┐                       
     │Client_Build│          │Query_Store│          │Server_Build│                       
     └────────────┘          └───────────┘          └────────────┘                                                           
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;At runtime, thus we avoid the overhead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     ┌──────┐              ┌──────────────┐                                ┌─────────┐
     │Client│              │GraphQL_Server│                                │Datastore│
     └──┬───┘              └──────┬───────┘                                └────┬────┘
        │ GraphQL Request with PQ1│                                             │     
        │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;                                             │     
        │                         │                                             │     
        │                         │─ ─ ┐                                              
        │                         │    | Lookup corresponding Datastore query DQ1     
        │                         │&amp;lt; ─ ┘                                              
        │                         │                                             │     
        │                         │           Datastore query with DQ1          │     
        │                         │  ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─&amp;gt;     
        │                         │                                             │     
        │                         │                  Record(s)                  │     
        │                         │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─      
        │                         │                                             │     
        │     GraphQL Response    │                                             │     
        │ &amp;lt;─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─                                              │     
     ┌──┴───┐              ┌──────┴───────┐                                ┌────┴────┐
     │Client│              │GraphQL_Server│                                │Datastore│
     └──────┘              └──────────────┘                                └─────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you look closely, this is the same old world we started in. The key difference is we are ever more powerful and flexible to adapt to the changing needs of the customers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;This concept can be realised using multiple implementations. I will be keen to learn what building blocks you will use to realise this? I will reserve my comments and biases for a follow up post where I will illustrate this with one or more concrete example(s).&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.kensho.com/compiled-graphql-as-a-database-query-language-72e106844282"&gt;Compiled GraphQL as a database query language&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.grandstack.io/graphql-resolveinfo-deep-dive-1b3144075866"&gt;Building Efficient GraphQL Resolvers By Generating Database Queries&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://relay.dev/docs/en/compiler-architecture"&gt;Relay Compiler Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/hasura/graphql-engine#architecture"&gt;Hasura GraphQL Engine&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nplus1nomore</category>
      <category>graphql</category>
      <category>compiled</category>
      <category>compiledgraphql</category>
    </item>
  </channel>
</rss>
