<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Apollo GraphQL - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Apollo GraphQL - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Thu, 21 May 2026 16:11:22 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/apollo/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Orchestrating AWS Lambda with GraphQL and Apollo Connectors ]]>
                </title>
                <description>
                    <![CDATA[ AWS Lambda is a computing service that enables you to run arbitrary code functions without needing to provision, manage, or scale servers. It’s often used in the logic tier of a multi-tier architecture to handle tasks such as processing files in S3 o... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-orchestrate-aws-lambda-with-graphql-and-apollo-connectors/</link>
                <guid isPermaLink="false">67e2d5e080e11112e050be00</guid>
                
                    <category>
                        <![CDATA[ GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ aws lambda ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Microservices ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Apollo GraphQL ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Rob Walters ]]>
                </dc:creator>
                <pubDate>Tue, 25 Mar 2025 16:12:16 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1742917115054/07184be6-5384-4861-a676-b72c06ff7c65.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>AWS Lambda is a computing service that enables you to run arbitrary code functions without needing to provision, manage, or scale servers. It’s often used in the logic tier of a multi-tier architecture to handle tasks such as processing files in S3 or performing CRUD operations on a database.</p>
<p>AWS also offers an API Gateway, allowing developers to invoke AWS Lambda functions, which provides enhanced security and performance features like rate limiting. But even with the API Gateway, you have to coordinate these microservices, as your client applications likely each have unique data needs. Data might need to be transformed, filtered, or combined before it is returned to the client. </p>
<p>These orchestration tasks can reduce your productivity and take time and effort away from solving the business problem your application is trying to solve. </p>
<p>Apollo GraphQL is an API orchestration layer that helps teams ship new features faster and more independently by composing any number of underlying services and data sources into a single endpoint. This allows clients on-demand access to precisely what the experience needs, regardless of the source of that data.</p>
<p>This article will teach you how to orchestrate AWS Lambda functions using Apollo GraphQL. Specifically, here’s what we will cover:</p>
<ul>
<li><p><a class="post-section-overview" href="#heading-graphql-primer">GraphQL Primer</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-tutorial-overview">Tutorial Overview</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-section-1-create-the-aws-resources">Section 1: Create the AWS Resources</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-section-2-create-an-apollo-connector">Section 2: Create an Apollo Connector</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-section-3-how-to-use-apollo-sandbox">Section 3: How to Use Apollo Sandbox</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-summary">Summary</a></p>
</li>
</ul>
<h2 id="heading-graphql-primer">GraphQL Primer</h2>
<p>For those unfamiliar with GraphQL, here’s a primer that offers some background on the challenges GraphQL addresses and how data is typically managed through REST APIs in GraphQL before the emergence of Apollo Connectors. If you’re familiar with GraphQL, feel free to skip this section.</p>
<p>GraphQL is a query language for APIs. This query language and corresponding runtime enable clients to specify exactly the data they require, minimizing over-fetching and under-fetching.</p>
<p>In contrast to REST, which necessitates multiple endpoints for various data requirements, GraphQL streamlines queries into a single request, enhancing performance and reducing network latency.</p>
<p>GraphQL also uses a strongly typed schema. This improves API documentation and makes validation, early error detection, and immersive developer tooling easy. </p>
<p>To illustrate the difference between REST APIs and GraphQL, consider the following REST API call: /user/123</p>
<p>Response:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"id"</span>: <span class="hljs-number">123</span>,
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Alice Johnson"</span>,
  <span class="hljs-attr">"email"</span>: <span class="hljs-string">"alice@example.com"</span>,
  <span class="hljs-attr">"phone"</span>: <span class="hljs-string">"555-1234"</span>,
  <span class="hljs-attr">"address"</span>: {
    <span class="hljs-attr">"street"</span>: <span class="hljs-string">"123 Main St"</span>,
    <span class="hljs-attr">"city"</span>: <span class="hljs-string">"Springfield"</span>,
    <span class="hljs-attr">"state"</span>: <span class="hljs-string">"IL"</span>,
    <span class="hljs-attr">"zip"</span>: <span class="hljs-string">"62704"</span>
  },
  <span class="hljs-attr">"createdAt"</span>: <span class="hljs-string">"2022-01-01T12:00:00Z"</span>,
  <span class="hljs-attr">"updatedAt"</span>: <span class="hljs-string">"2022-05-15T14:30:00Z"</span>,
  <span class="hljs-attr">"isAdmin"</span>: <span class="hljs-literal">false</span>
}
</code></pre>
<p>If you were only interested in the name and email, using REST would be a lot of data returned from the network to the client for no reason. Using GraphQL, the GraphQL query to return the name and email would be the following:</p>
<pre><code class="lang-graphql"><span class="hljs-keyword">query</span> {
  user(<span class="hljs-symbol">id:</span> <span class="hljs-number">123</span>) {
    name
    email
  }
}
</code></pre>
<p>The result set is just the data the client needs:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"data"</span>: {
    <span class="hljs-attr">"user"</span>: {
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Alice Johnson"</span>,
      <span class="hljs-attr">"email"</span>: <span class="hljs-string">"alice@example.com"</span>
    }
  }
}
</code></pre>
<p>This is a simple example showing the benefit of not over-fetching data, but GraphQL has many other advantages. One of them is the separation between client and server. Since both parties leverage and respect the GraphQL type schema, both teams can operate more independently with the back end defining where the data resides and the front end only asking for data it needs.    </p>
<p>So how does GraphQL know how to populate data for every field in your schema? It does this through <a target="_blank" href="https://www.apollographql.com/docs/apollo-server/data/resolvers">resolvers</a>. Resolvers can fetch data from a back-end databases or third-party API such as REST APIs, gRPC, and so on. These functions comprise procedural code compiled and maintained for each field in the schema. Thus, one field can have a resolver that queries a REST API and another can query a gRPC endpoint.</p>
<p>To illustrate resolvers, consider the example above. Let’s add a field, status, that queries a REST API to determine if the user is full-time, part-time, or terminated. </p>
<p>First we have defined our schema as:</p>
<pre><code class="lang-graphql"><span class="hljs-keyword">type</span> User {
  <span class="hljs-symbol">id:</span> ID!
  <span class="hljs-symbol">name:</span> String!
  <span class="hljs-symbol">email:</span> String!
  <span class="hljs-symbol">status:</span> String!  <span class="hljs-comment"># Need this from an external REST API</span>
}

<span class="hljs-keyword">type</span> Query {
  user(<span class="hljs-symbol">id:</span> ID!): User
}
</code></pre>
<p>The user query in this case will accept a user id and return a type User. The resolver function to support the data fetching resembles the following:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> resolvers = {
  <span class="hljs-attr">Query</span>: {
    <span class="hljs-attr">user</span>: <span class="hljs-keyword">async</span> (_, { id }) =&gt; {
      <span class="hljs-comment">// Fetch user details from one REST API</span>
      <span class="hljs-keyword">const</span> userResponse = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`https://api.company.com/users/<span class="hljs-subst">${id}</span>`</span>);
      <span class="hljs-keyword">const</span> userData = <span class="hljs-keyword">await</span> userResponse.json();

      <span class="hljs-comment">// Fetch employee status from another REST API</span>
      <span class="hljs-keyword">const</span> statusResponse = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`https://api.company.com/employees/<span class="hljs-subst">${id}</span>/status`</span>);
      <span class="hljs-keyword">const</span> statusData = <span class="hljs-keyword">await</span> statusResponse.json();

      <span class="hljs-keyword">return</span> {
        <span class="hljs-attr">id</span>: userData.id,
        <span class="hljs-attr">name</span>: userData.name,
        <span class="hljs-attr">email</span>: userData.email,
        <span class="hljs-attr">status</span>: statusData.status, <span class="hljs-comment">// e.g., "Full-Time", "Part-Time", "Terminated"</span>
      };
    },
  },
};
</code></pre>
<p>Notice that not only are there two fetches needed to obtain the information the query requires, but we also need to write procedural code and deploy it.</p>
<p>A better approach would be to declaratively specify to GraphQL where the REST API is located and what data to return. Apollo Connectors is the solution to this challenge, simplifying the process and allowing you to declaratively integrate REST API data without requiring code compilation and maintenance.</p>
<p>Now that you have a general idea of GraphQL and the challenges it addresses, let’s delve into the example we will build out.</p>
<h2 id="heading-tutorial-overview">Tutorial Overview</h2>
<p>In this tutorial, you will create two AWS Lambda functions that return product information, which are described as follows:</p>
<p>Products Request:</p>
<p>POST /2015-03-31/functions/products/invocations</p>
<p>Response:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"statusCode"</span>: <span class="hljs-number">200</span>,
  <span class="hljs-attr">"body"</span>: [
    {
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"RANQi6AZkUXCbZ"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"OG Olive Putter - Blade"</span>,
      <span class="hljs-attr">"description"</span>: <span class="hljs-string">"The traditional Block in a blade shape is made from a solid block of Olive wood. The head weight is approximately 360 grams with the addition of pure tungsten weights. Paired with a walnut center-line and white accents colors."</span>,
      <span class="hljs-attr">"image"</span>: <span class="hljs-string">"https://keynote-strapi-production.up.railway.app/uploads/thumbnail_IMG_9102_3119483fac.png"</span>
    },
    {
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"RANYrWRy876AA5"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Butter Knife Olive Putter- Blade"</span>,
      <span class="hljs-attr">"description"</span>: <span class="hljs-string">"The traditional Block in a extremely thin blade shape (~1\") is made from a solid block of Olive wood. The head weight is approximately 330 grams with the addition of pure tungsten weights."</span>,
      <span class="hljs-attr">"image"</span>: <span class="hljs-string">"https://keynote-strapi-production.up.railway.app/uploads/thumbnail_IMG_9104_97c221e79c.png"</span>
    },...
</code></pre>
<p>Product-price request:</p>
<p>POST: /2015-03-31/functions/product-price/invocations</p>
<p>Response:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"default_price"</span>: <span class="hljs-number">49900</span>,
  <span class="hljs-attr">"is_active"</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">"currency"</span>: <span class="hljs-string">"usd"</span>,
  <span class="hljs-attr">"billing_schema"</span>: <span class="hljs-string">"per_unit"</span>,
  <span class="hljs-attr">"recurring"</span>: {
    <span class="hljs-attr">"interval"</span>: <span class="hljs-number">0</span>,
    <span class="hljs-attr">"interval_count"</span>: <span class="hljs-number">3</span>
  }
}
</code></pre>
<p>To expose these two lambda microservices, you need to create API Gateway triggers. This involves either setting up a distinct API Gateway for each lambda or consolidating them under one or a few API Gateway instances with specified routes for each lambda.</p>
<p>Creating a trigger may feel tedious and repetitive in a microservices setup. But there is an alternative available. You could directly invoke those functions via REST using the InvokeFunction permission assigned to an IAM user. This article will show you this method and guide you through function creation, necessary AWS IAM permissions, and configuring the Apollo Connector to invoke the function.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>To follow along in this tutorial, you will need to have a basic understanding of AWS Lambda functions as well as AWS security. You’ll also need access to the following:</p>
<ul>
<li><p>An AWS account with permissions to create IAM Users and Policies</p>
</li>
<li><p>An Apollo GraphQL account, you can <a target="_blank" href="https://studio.apollographql.com/signup">sign up for a free plan here</a>.</p>
</li>
</ul>
<p>We will also use the following tools:</p>
<ul>
<li><p><a target="_blank" href="https://code.visualstudio.com/">VS Code</a>: Microsoft VS Code is a free source code editor from Microsoft</p>
</li>
<li><p><a target="_blank" href="https://www.apollographql.com/docs/rover/getting-started?utm_campaign=2025-03-20_installing-rover-doc-march2025awareness&amp;utm_medium=blog&amp;utm_source=freecodecamp">Apollo Rover CLI</a>: Rover is the command-line interface for managing and maintaining graphs</p>
</li>
<li><p><a target="_blank" href="https://studio.apollographql.com/signup?utm_campaign=2025-03-19_studio-signup-march2025awareness&amp;utm_medium=blog&amp;utm_source=freecodecamp">Apollo Studio</a>: A web-based portal used for managing all aspects of your graph </p>
</li>
<li><p><a target="_blank" href="https://www.apollographql.com/connectors-mapping-playground?utm_campaign=2025-03-20_connectors-mapping-playground-march2025awareness&amp;utm_medium=blog&amp;utm_source=freecodecamp">Apollo Connectors Mapping Playground</a>: A website that takes a JSON document and helps developers create the selection mapping used with Apollo Connectors</p>
</li>
</ul>
<h2 id="heading-section-1-create-the-aws-resources">Section 1: Create the AWS Resources</h2>
<p>First, let’s configure our AWS environment, starting with security. In our scenario, we will create an IAM User, “ConnectorUser,” with access to an AWS Policy, “ConnectorLambdaPolicy,” with the minimum permissions needed to access the AWS Lambda functions.</p>
<p>Note that you could create user groups and assign permission policies to those groups in a production environment. But for this article, we are reducing the number of administrative steps to focus on the core integration with GraphQL.</p>
<h3 id="heading-step-1-create-an-aws-policy">Step 1: Create an AWS Policy</h3>
<p>To create a policy, navigate to IAM within the AWS Management console, then select “Policies” under Access Management. Click “Create Policy”. This will open the policy editor page, as shown below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742755417676/1025d04f-a712-4311-9669-ac38bd2fee50.jpeg" alt="specify permissions" class="image--center mx-auto" width="1558" height="720" loading="lazy"></p>
<p>Choose the “Lambda” service and under the Access level select “InvokeFunction” from the Write drop down menu as shown below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742755482285/1be204db-7b39-4c8f-ac7c-d461032f6887.jpeg" alt="InvokeFunction checkmarked" class="image--center mx-auto" width="1534" height="910" loading="lazy"></p>
<p>Under the Resources menu, you can choose either All ARNs or a specific option. It's a best practice to be as granular as possible when defining security configurations. In this example, let’s limit our selection to the “us-east-1” region by clicking on the “Specific” option and then “Add ARNs.” Enter “us-east-1” in the resource region and select “Any function name.”</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742755564740/99e47ac8-4ce9-4ff3-94b6-105308526f56.jpeg" alt="Specify ARN dialog" class="image--center mx-auto" width="1598" height="824" loading="lazy"></p>
<p>With the policy created, we can assign an IAM user to that policy.</p>
<h3 id="heading-step-2-create-the-iam-user-and-attach-a-policy">Step 2: Create the IAM User and Attach a Policy</h3>
<p>Click on Users under “Access Management” then Create User. Provide a name for the user, “ConnectorUser”.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742755638499/ad782c39-a78f-4d68-b834-4e58dea9e35b.jpeg" alt="Permission policy" class="image--center mx-auto" width="1566" height="570" loading="lazy"></p>
<p>Next, select “Attach policies directly,” choose the policy we just created, “ConnectorLambdaPolicy,” and click “Create User.”</p>
<h3 id="heading-step-3-create-aws-lambda-functions">Step 3: Create AWS Lambda Functions</h3>
<p>In your AWS console, create a new NodeJS AWS Lambda function, “products”.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742754922858/b2a307c2-8b43-4417-b022-0113803a3b5d.jpeg" alt="AWS create function dialog" class="image--center mx-auto" width="1856" height="1036" loading="lazy"></p>
<p>Select “Node.JS” for the runtime then click “Create function”. Once created, paste in the the function code <a target="_blank" href="https://gist.github.com/RWaltersMA/25264ff22a5cbc26814a00dbb78a16e2">from this Gist</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742755096066/90e96036-41cd-4b45-8841-0bb3acb5af6b.jpeg" alt="AWS function showing code source" class="image--center mx-auto" width="1990" height="1000" loading="lazy"></p>
<p>Repeat this process, creating another function for, “product-price” and use the function code <a target="_blank" href="https://gist.github.com/RWaltersMA/d75d9eb02264829c1392dbdf7f238bad">from this Gist</a>.</p>
<h2 id="heading-section-2-create-an-apollo-connector">Section 2: Create an Apollo Connector</h2>
<p>In this section, we will install the Apollo Rover CLI tool, create an Apollo Studio free tier account, and clone the Apollo Connectors repository. If you already have an Apollo environment available, you can skip steps 1 and 2.</p>
<h3 id="heading-step-1-install-rover">Step 1: Install Rover</h3>
<p>Rover is the command-line interface for managing and maintaining graphs. It also provides a modern hot-reloading experience for developing and running your connectors locally. If you don’t have Rover installed, install it by <a target="_blank" href="https://www.apollographql.com/docs/rover/getting-started?utm_campaign=2025-03-20_installing-rover-doc-march2025awareness&amp;utm_medium=blog&amp;utm_source=freecodecamp">following the steps here</a>.</p>
<h3 id="heading-step-2-create-an-apollo-studio-free-tier-account">Step 2: Create an Apollo Studio Free Tier Account</h3>
<p>Apollo Studio is a cloud-based management platform designed to explore, deliver, and collaborate on graphs. If you do not have an Apollo Studio account, create one on a free plan <a target="_blank" href="https://studio.apollographql.com/signup?utm_campaign=2025-03-19_studio-signup-march2025awareness&amp;utm_medium=blog&amp;utm_source=freecodecamp">by navigating here</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742755870123/4b38b025-064c-4a9a-b836-53a563152e43.jpeg" alt="Apollo Studio" class="image--center mx-auto" width="1560" height="753" loading="lazy"></p>
<h3 id="heading-step-3-clone-the-apollo-connectors-repository">Step 3: Clone the Apollo Connectors Repository</h3>
<p>To help you start your first Apollo Connector, a GitHub repository provides sample connectors and a template script. When run, this script will create all the necessary files and configurations you need to begin. </p>
<p>Go ahead and <a target="_blank" href="https://github.com/apollographql/connectors-community">clone the repository from here</a>.</p>
<p>Note: While not required, I recommended using VS Code, as this repo leverages VS Code-specific settings files.</p>
<h3 id="heading-step-4-create-a-env-file">Step 4: Create a .env File</h3>
<p>Before you run the Create Connectors template script, create a .env locally with a user API key from your Apollo Studio. You can <a target="_blank" href="https://studio.apollographql.com/user-settings/api-keys">create and obtain this key here</a>. Populating this .env file will add this API key to the connector template you create in the next step.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742755977271/860ef610-e802-4ec1-9cca-e881881a0968.jpeg" alt=".env file" class="image--center mx-auto" width="1554" height="109" loading="lazy"></p>
<h3 id="heading-step-5-create-your-new-connector-from-a-template">Step 5: Create Your New Connector from a Template</h3>
<p>Execute <code>npm start</code> and provide a location to create the connector template. You can use default values for the remaining questions.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742756030015/e6c3b535-8657-4a77-b353-b8546cfa9ac5.jpeg" alt="npmstart" class="image--center mx-auto" width="1536" height="402" loading="lazy"></p>
<p>This script will create all the necessary files to run a local Apollo GraphQL instance in the specified directory. Load the newly created connector using VS Code or your preferred code editor. You will return to this editor soon, but first, we need to obtain some access keys from AWS.</p>
<h3 id="heading-step-6-create-an-aws-access-key">Step 6: Create an AWS Access Key</h3>
<p>Since we connect to AWS using SigV4, we must create an AWS access key and enter the KEY values in the settings.json file. Return to the AWS IAM Console and select the <em>ConnectorUser</em> you created in Step 1.  Create a new access key by clicking on “Create access key”. </p>
<p>You will be presented with multiple options as far as where the use of this key will originate. Since we are first running locally, select “Third-party service” and then continue the wizard until you are presented with the key and secret key as shown below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742756092209/e7b33bd2-f6ca-4e78-bf83-8ed357860abd.jpeg" alt="retrieve access key dialog" class="image--center mx-auto" width="1548" height="344" loading="lazy"></p>
<p>Add the access key and secret access key to the settings.json file as “AWS_ACCESS_KEY_ID” and “AWS_SECRET_ACCESS_KEY” respectively.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742756152443/31906e19-625d-446f-adde-b9618e8df61a.jpeg" alt="vscode settings file" class="image--center mx-auto" width="1140" height="624" loading="lazy"></p>
<p>You'll need to reload the window since VS Code only loads these files under the .vscode directory once. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742756203631/8fb467fc-e8de-4f16-8907-622a12017d4f.jpeg" alt="vscode task window showing reload option" class="image--center mx-auto" width="1552" height="162" loading="lazy"></p>
<p>Note: In this step, we saved the key to the settings.json file. While this is acceptable for development, consider saving environment variables in .env files.</p>
<h3 id="heading-step-7-configure-the-graph">Step 7: Configure the Graph</h3>
<p>The supergraph.yaml file is used to define all the subgraphs that are part of this federation. Modify the <strong>supergraph.yaml</strong> file as follows:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">federation_version:</span> <span class="hljs-string">=2.10.0</span>
<span class="hljs-attr">subgraphs:</span>
  <span class="hljs-attr">awsconnector:</span>
    <span class="hljs-attr">routing_url:</span> <span class="hljs-string">http://lambda</span>
    <span class="hljs-attr">schema:</span>
      <span class="hljs-attr">file:</span> <span class="hljs-string">connector.graphql</span>
</code></pre>
<h3 id="heading-step-8-configure-apollo-router">Step 8: Configure Apollo Router</h3>
<p>Apollo Router supports AWS SigV4 authentication. To configure the connector to use this, modify the <strong>router.yaml</strong> file and add an authentication section as follows:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">authentication:</span>
  <span class="hljs-attr">connector:</span>
    <span class="hljs-attr">sources:</span>
      <span class="hljs-attr">awsconnector.lambda:</span>   <span class="hljs-comment"># subgraph name . connector source name</span>
        <span class="hljs-attr">aws_sig_v4:</span>
          <span class="hljs-attr">default_chain:</span>
            <span class="hljs-attr">region:</span> <span class="hljs-string">"us-east-1"</span>
            <span class="hljs-attr">service_name:</span> <span class="hljs-string">"lambda"</span>
</code></pre>
<p>There are other AWS security configuration options available, including using assume role. The full documentation for subgraph authentication <a target="_blank" href="https://www.apollographql.com/docs/graphos/routing/security/subgraph-authentication">is available here</a>. </p>
<h3 id="heading-step-9-build-the-connector">Step 9: Build the connector</h3>
<p>Now that we have configured the environment variables and authentication information, we are ready to build the connector. Open the <code>connector.graphql</code> file and erase the contents. Next, copy the following extend schema:</p>
<pre><code class="lang-graphql">extend <span class="hljs-keyword">schema</span>
  <span class="hljs-meta">@link</span>(
    <span class="hljs-symbol">url:</span> <span class="hljs-string">"https://specs.apollo.dev/federation/v2.10"</span>
    <span class="hljs-symbol">import:</span> [<span class="hljs-string">"@key"</span>]
  )
  <span class="hljs-meta">@link</span>(
    <span class="hljs-symbol">url:</span> <span class="hljs-string">"https://specs.apollo.dev/connect/v0.1"</span>
    <span class="hljs-symbol">import:</span> [<span class="hljs-string">"@source"</span>, <span class="hljs-string">"@connect"</span>]
  )

  <span class="hljs-meta">@source</span>(
    <span class="hljs-symbol">name:</span> <span class="hljs-string">"lambda"</span>
    <span class="hljs-symbol">http:</span> { <span class="hljs-symbol">baseURL:</span> <span class="hljs-string">"https://lambda.us-east-1.amazonaws.com"</span> }
  )
</code></pre>
<p><strong>Extend schema</strong> is used to link the Apollo Connectors directives into the current schema. In this article we are defining the base URL of our lambda function. If your REST API has HTTP headers that apply to all references of this source, such as Content-Length restrictions, you can add them here in the @source declaration. Next, let’s define the Product schema:</p>
<pre><code class="lang-graphql"><span class="hljs-keyword">type</span> Product {
  <span class="hljs-symbol">id:</span> ID!
  <span class="hljs-symbol">name:</span> String
  <span class="hljs-symbol">description:</span> String
  <span class="hljs-symbol">image:</span> String
  <span class="hljs-symbol">price:</span> Price
    <span class="hljs-meta">@connect</span>(
      <span class="hljs-symbol">source:</span> <span class="hljs-string">"lambda"</span>
      <span class="hljs-symbol">http:</span> {
        <span class="hljs-symbol">POST:</span> <span class="hljs-string">"/2015-03-31/functions/product-price/invocations"</span>
        <span class="hljs-symbol">body:</span> <span class="hljs-string">""</span><span class="hljs-string">"
        product_id: $this.id
        "</span><span class="hljs-string">""</span>
      }
      <span class="hljs-symbol">selection:</span> <span class="hljs-string">""</span><span class="hljs-string">"
      amount: default_price
      isActive: is_active
      currency
      recurringInterval: recurring.interval -&gt; match(
        [0,"</span>ONE_TIME<span class="hljs-string">"],
        [1,"</span>DAILY<span class="hljs-string">"],
        [2,"</span>MONTHLY<span class="hljs-string">"],
        [3,"</span>ANNUALLY<span class="hljs-string">"],
      )
      recurringCount: recurring.interval_count
      "</span><span class="hljs-string">""</span>
    )
}
</code></pre>
<p>Notice our query Products has an @connect directive that defines, at a minimum, the source name. Here, you can add the HTTP-specific configuration you need for this field, such as Authorizations headers. In this scenario, since we only defined a baseUrl in the extend schema section, we need to put the specific URL for the InvokeFunction, which is <strong>/2015-03-31/functions/product-price/invocations</strong>.</p>
<p>The selection field allows you to transform and map values returned from the REST API using the mapping definition defined in the selection field. While a complete discussion of selection mapping is beyond the scope of this article, check out the documentation for a detailed look at <a target="_blank" href="https://www.apollographql.com/docs/graphos/schema-design/connectors/responses?utm_campaign=2025-03-20_mapping-graphql-responses-doc-march2025awareness&amp;utm_medium=blog&amp;utm_source=freecodecamp">Mapping GraphQL Responses</a>.  Apollo <a target="_blank" href="https://www.apollographql.com/connectors-mapping-playground?utm_campaign=2025-03-20_connectors-mapping-playground-march2025awareness&amp;utm_medium=blog&amp;utm_source=freecodecamp">provides a free online tool</a> that makes building mappings intuitive and fast.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742756290237/91d17c59-a2d0-4a22-8acf-1faec0c0f36f.jpeg" alt="connectors mapping playground" class="image--center mx-auto" width="1560" height="984" loading="lazy"></p>
<p>Next, let’s define the Price schema and products Query.</p>
<pre><code class="lang-graphql"><span class="hljs-keyword">type</span> Price {
  <span class="hljs-symbol">amount:</span> Float
  <span class="hljs-symbol">isActive:</span> Boolean
  <span class="hljs-symbol">currency:</span> String
  <span class="hljs-symbol">recurringInterval:</span> RecurringInterval
  <span class="hljs-symbol">recurringCount:</span> Int
}
<span class="hljs-keyword">enum</span> RecurringInterval {
  ONE_TIME
  DAILY
  MONTHLY
  ANNUALLY
}

<span class="hljs-keyword">type</span> Query {
  <span class="hljs-symbol">products:</span> [Product]
    <span class="hljs-comment"># https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html</span>
    <span class="hljs-meta">@connect</span>(
      <span class="hljs-symbol">source:</span> <span class="hljs-string">"lambda"</span>
      <span class="hljs-symbol">http:</span> { <span class="hljs-symbol">POST:</span> <span class="hljs-string">"/2015-03-31/functions/products/invocations"</span> }
      <span class="hljs-symbol">selection:</span> <span class="hljs-string">""</span><span class="hljs-string">"
      $.body {
        id
        name
        description
        image
      }
      "</span><span class="hljs-string">""</span>
    )
}
</code></pre>
<p>Now we're ready to run our connector and issue queries to our graph! The complete configuration script is available <a target="_blank" href="https://gist.github.com/RWaltersMA/e44813a89c748e175d6997f659162b33.">at this Gist</a>.</p>
<h3 id="heading-step-10-run-the-connector">Step 10: Run the Connector</h3>
<p>If you're using VS Code, the repository includes a tasks.json file that adds a “rover dev” task, which launches Rover locally. </p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"version"</span>: <span class="hljs-string">"2.0.0"</span>,
    <span class="hljs-attr">"tasks"</span>: [{
        <span class="hljs-attr">"label"</span>: <span class="hljs-string">"rover dev"</span>,
        <span class="hljs-attr">"command"</span>: <span class="hljs-string">"rover"</span>, <span class="hljs-comment">// Could be any other shell command</span>
        <span class="hljs-attr">"args"</span>: [<span class="hljs-string">"dev"</span>, <span class="hljs-string">"--supergraph-config"</span>,<span class="hljs-string">"supergraph.yaml"</span>, <span class="hljs-string">"--router-config"</span>,<span class="hljs-string">"router.yaml"</span>],
        <span class="hljs-attr">"type"</span>: <span class="hljs-string">"shell"</span>,
        <span class="hljs-attr">"problemMatcher"</span>: [],
    }]
}
</code></pre>
<p> If you are not using VS Code, you can start your graph by executing <code>rover dev –supergraph-config supergraph.yaml –router-config router.yaml</code> from a terminal window.</p>
<p>If everything is configured correctly, you’ll see the following:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742756354078/9fab875a-d064-4723-be91-8ca0d6243b59.jpeg" alt="running rover dev command " class="image--center mx-auto" width="1558" height="390" loading="lazy"></p>
<h2 id="heading-section-3-how-to-use-apollo-sandbox">Section 3: How to Use Apollo Sandbox</h2>
<p>The <code>rover dev</code> command you launched in the previous step configures a local Apollo Router instance for <a target="_blank" href="https://www.apollographql.com/docs/graphos/reference/router/configuration?utm_campaign=2025-03-20_router-configuration-doc-march2025awareness&amp;utm_medium=blog&amp;utm_source=freecodecamp#-dev">development mode</a>. This mode makes it easy for developers to create, execute, and debug ad-hoc GraphQL queries using the Apollo Sandbox web portal. This portal is located at <a target="_blank" href="http://localhost:4000">http://localhost:4000</a> by default.</p>
<p>Launch the portal and click on the products field. This will populate the Operation pane with all the available fields in the schema. In the operation pane, you can modify and build your GraphQL query. Clicking the Run button (which displays the query name, Products, in our example) will execute the query and show the results in the Response panel, as illustrated in the figure above.</p>
<p>In this example, you can see that data has been returned from our AWS Lambda function. To confirm, you can view the query plan by selecting "Query Plan” from the Response drop-down menu.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742756499055/822467d7-0694-423e-baef-450a8d0dd64e.jpeg" alt="query plan menu item" class="image--center mx-auto" width="590" height="566" loading="lazy"></p>
<p>The query plan illustrates the orchestration of our two AWS Lambda functions that fetch product and product price data.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742756540147/af32d615-029a-4f6f-a489-96ee9950e630.jpeg" alt="query plan" class="image--center mx-auto" width="1542" height="1010" loading="lazy"></p>
<p>A helpful debugging feature is the Connectors Debugger, available in the drop-down as shown in the previous figure.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1742756614481/c9b311e3-ab5d-4927-9457-e9a7d242fbdf.jpeg" alt="debugger showing request overview" class="image--center mx-auto" width="775" height="818" loading="lazy"></p>
<p>The Connection Debugger provides a comprehensive view of the HTTP request, including headers, body, response code, and the selection mapping used in the query. If you’re experiencing difficulties running queries, use this debugger – it will save you a lot of time.</p>
<h2 id="heading-summary">Summary</h2>
<p>In this article, you learned how to: </p>
<ul>
<li><p>Set up AWS IAM User, Policies, and Lambda functions</p>
</li>
<li><p>Create an Apollo Connector to obtain data from an AWS Lambda function</p>
</li>
<li><p>Configure the Apollo Router </p>
</li>
<li><p>Execute and debug queries using Apollo Sandbox</p>
</li>
</ul>
<p>Integrating AWS Lambda with Apollo Connectors offers a simplified, resolver-free method for incorporating cloud functions into your GraphQL API. By utilizing Apollo Connectors, you can declaratively link REST-based Lambda functions to your supergraph while ensuring secure authentication with AWS SigV4.</p>
<p>You can learn more about Apollo Connectors from the following resources:</p>
<ol>
<li><p>Tutorial: <a target="_blank" href="https://www.apollographql.com/tutorials/connectors-intro-rest?utm_campaign=2025-03-20_connectors-intro-rest-odyssey-march2025awareness&amp;utm_medium=blog&amp;utm_source=freecodecamp">GraphQL meets REST, with Apollo Connectors</a></p>
</li>
<li><p>Blog: Discover how Apollo Connectors integrate with Apollo Federation through insights from Apollo's Founder &amp; CTO: <a target="_blank" href="https://www.apollographql.com/blog/api-orchestration-with-graphql?utm_campaign=2025-03-20_api-orchestration-with-graphql-march2025awareness&amp;utm_medium=blog&amp;utm_source=freecodecamp">REST API Orchestration with GraphQL</a>.</p>
</li>
<li><p>Blog: Delve into the engineering journey behind Apollo Connectors and the process of their creation: <a target="_blank" href="https://www.apollographql.com/blog/our-journey-to-apollo-connectors?utm_campaign=2025-03-20_our-journey-to-apollo-connectors-march2025awareness&amp;utm_medium=blog&amp;utm_source=freecodecamp">Our Journey to Apollo Connectors</a></p>
</li>
<li><p>Webinar: <a target="_blank" href="https://www.apollographql.com/events/new-innovations-from-apollo-dont-miss-out?utm_campaign=2025-03-20_new-innovations-from-apollo-dont-miss-out-march2025awareness&amp;utm_medium=blog&amp;utm_source=freecodecamp">Apollo Connectors GA Launch Webinar</a></p>
</li>
</ol>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Pokemon App with GraphQL and Apollo ]]>
                </title>
                <description>
                    <![CDATA[ Pokemon is a Japanese media franchise consisting of video games, animated series and films, a trading card game, and other related media. In this blog, we will be building with a Pokemon GraphQL API that gives us data about different Pokemons. We wil... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-pokemon-app-with-graphql-and-apollo/</link>
                <guid isPermaLink="false">66c8c949e9e57963a5d82ad0</guid>
                
                    <category>
                        <![CDATA[ Apollo GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ projects ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Segun Ajibola ]]>
                </dc:creator>
                <pubDate>Wed, 03 Apr 2024 12:28:07 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/04/Parameters-vs-Arguments--2-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Pokemon is a Japanese media franchise consisting of video games, animated series and films, a trading card game, and other related media.</p>
<p>In this blog, we will be building with a Pokemon GraphQL API that gives us data about different Pokemons.</p>
<p>We will be using Apollo and GraphQL to handle the data fetching, and React for building our front-end application.</p>
<p>No worries if you don't know these technologies, I will be walking you through the basics as you read on.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<p>You should have these in your computer to follow along:</p>
<ul>
<li>Nodejs v18+</li>
<li>A code editor</li>
<li>A web browser</li>
</ul>
<p>Let's create our React app.</p>
<h3 id="heading-react-application-setup">React Application Setup</h3>
<p>To create your React app, navigate to your terminal, and use the Command Prompt. Open your Command Prompt and choose your preferred location for creating your React project. Let's go with Desktop.</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> Desktop
</code></pre>
<p>The above command will navigate to your Desktop.</p>
<pre><code class="lang-bash">npm create vite@latest pokemon-app -- --template react
</code></pre>
<p><code>npm create vite@latest</code> will start to build a new project using Vite. But we attached the name of our project (<code>pokemon-app</code>) and the technology or framework our app will be using (<code>-- -- template react</code>). </p>
<p>You can set another template like <code>svelte</code>, <code>vanilla</code> or <code>vue</code> and the project will be created using that framework. Read more about Vite on <a target="_blank" href="https://vitejs.dev/guide/">its official website</a>.</p>
<p>After the Vite installation, run the following commands:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> pokemon-app
npm install
npm run dev
</code></pre>
<p>We'll use the commands above to finish the React setup.</p>
<p>Run the first command, <code>cd pokemon-app</code>, to navigate to the <strong>pokeman-app</strong> folder.</p>
<p>Run <code>code .</code> to open the folder in your code editor.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1711666709423/593e293d-af0b-4cbd-b4ac-83d0c8213446.png" alt="Image" width="1270" height="960" loading="lazy">
<em>modal displaying over VSCode to accept that you trust the authors of the files opened in VSCode</em></p>
<p>Mark the trust the author checkbox if that pops up.</p>
<p>Open your code editor's terminal. If you are running VSCode on Windows, the shortcut is `Ctrl + `` .</p>
<p>Run the other 2 commands in the terminal one after the other.</p>
<pre><code class="lang-bash">npm install
</code></pre>
<pre><code class="lang-bash">npm run dev
</code></pre>
<p>Your project should be running in the browser now.</p>
<p>We will be managing our data fetching using GraphQL and Apollo.</p>
<h2 id="heading-how-to-use-graphql-and-apollo">How to Use GraphQL and Apollo</h2>
<p>GraphQL is a query language for APIs and a runtime for fulfilling queries with your existing data. It allows you to request only the data you need in your application and nothing more, making it very efficient and flexible.</p>
<p>Apollo is a state management library that allows you to manage local and remote data with GraphQL. It can be used to fetch, cache, and modify application data, all while automatically updating your UI.</p>
<p>Let's install the packages you need.</p>
<h3 id="heading-installing-packages">Installing Packages</h3>
<p>Run the command below in your terminal to install the Apollo client.</p>
<pre><code class="lang-bash">npm install @apollo/client
</code></pre>
<p>Navigate to your <strong>main.jsx</strong> file and import these:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">"react-dom/client"</span>;
<span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">"./App.jsx"</span>;
<span class="hljs-keyword">import</span> {
  ApolloProvider,
  ApolloClient,
  InMemoryCache,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"@apollo/client"</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">"./index.css"</span>;
</code></pre>
<p>You have imported React and ReactDOM for DOM manipulation.</p>
<p><code>ApolloClient</code> is responsible for managing your application's data fetching and state management. It handles sending GraphQL queries and mutations to your GraphQL server and caching the results.</p>
<p><code>ApolloProvider</code> will be used to wrap your React application to provide the Apollo Client instance to all your components so that your application can access data fetched through Apollo Client.</p>
<p><code>InMemoryCache</code> is a cache implementation to store the results of GraphQL queries in memory for efficient access and retrieval.</p>
<p>You have also imported <strong>index.css</strong> to style your application.</p>
<h3 id="heading-how-to-create-an-apollo-client">How to Create an Apollo Client</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> ApolloClient({
  <span class="hljs-attr">uri</span>: <span class="hljs-string">"https://graphql-pokemon2.vercel.app/"</span>,
  <span class="hljs-attr">cache</span>: <span class="hljs-keyword">new</span> InMemoryCache(),
});
</code></pre>
<p>The code above creates a new instance of <code>ApolloClient</code> with the some configurations:</p>
<ol>
<li><code>uri</code>: This specifies the URL of your GraphQL API endpoint. This is the endpoint where your Apollo Client will send GraphQL queries and mutations.</li>
<li><code>cache</code>: This configures the cache implementation for Apollo Client to use an in-memory cache to access data and store the result of GraphQL queries, reducing the need to re-fetch data from the server.</li>
</ol>
<p>You can now wrap your <code>&lt;App /&gt;</code> component with <code>ApolloProvider</code>:</p>
<pre><code class="lang-javascript">ReactDOM.createRoot(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"root"</span>)).render(
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">React.StrictMode</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ApolloProvider</span> <span class="hljs-attr">client</span>=<span class="hljs-string">{client}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">ApolloProvider</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">React.StrictMode</span>&gt;</span></span>
);
</code></pre>
<p>Note that <code>client</code> props was also passed to provide your application with <code>ApolloClient</code> configuration.</p>
<p>Go to your <strong>App.jsx</strong> component and input this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { PokemonsContainer } <span class="hljs-keyword">from</span> <span class="hljs-string">"./components/PokemonsContainer"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">PokemonsContainer</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></span>
  );
}
</code></pre>
<p>You imported React and <code>PokemonsContainer</code> will be created. The <code>PokemonsContainer</code> component was wrapped in main tag and will be rendered when the component is pasted in the DOM.</p>
<p>Let's create the <code>PokemonsContainer</code> component in a file located in <strong>components</strong> folder. That is:</p>
<p>📂 src/components/PokemonsContainer.jsx</p>
<h3 id="heading-pokemons-container-component">Pokemons Container Component</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { useQuery } <span class="hljs-keyword">from</span> <span class="hljs-string">"@apollo/client"</span>;
<span class="hljs-keyword">import</span> { Pokemon } <span class="hljs-keyword">from</span> <span class="hljs-string">"../components/Pokemon"</span>;
<span class="hljs-keyword">import</span> { GET_POKEMONS } <span class="hljs-keyword">from</span> <span class="hljs-string">"../graphql/get-pokemons"</span>;
</code></pre>
<p>The <code>useQuery</code> from <code>@apollo/client</code> is used for executing queries in an Apollo application. To do that, <code>useQuery()</code> is called and a GraphQL query string is passed as a argument. When your component renders, <code>useQuery</code> returns an object from Apollo Client that contains <code>loading</code>, <code>error</code>, and <code>data</code> properties that you can use to render your UI.</p>
<p><code>Pokemon</code> component was imported to render a user interface for a Pokemon, this will be built shortly.</p>
<p><code>GET_POKEMONS</code> was also imported. This will contain a GraphQL query.</p>
<p>After importing the above functions, continue building your page.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PokemonsContainer</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { loading, error, data } = useQuery(GET_POKEMONS, {
    <span class="hljs-attr">variables</span>: { <span class="hljs-attr">first</span>: <span class="hljs-number">5</span> },
  });

  <span class="hljs-keyword">if</span> (loading) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>;
  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Error: {error.message}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span>;

  <span class="hljs-keyword">const</span> pokemons = data?.pokemons || [];
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"container"</span>&gt;</span>
      {pokemons &amp;&amp;
        pokemons.map((pokemon) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">Pokemon</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{pokemon.id}</span> <span class="hljs-attr">pokemon</span>=<span class="hljs-string">{pokemon}</span> /&gt;</span>
        ))}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>As mentioned earlier, <code>useQuery</code> returns an object from Apollo Client that contains <code>loading</code>, <code>error</code>, and <code>data</code> properties. They are destructured here so you can access them in the page.</p>
<p>Notice that we're providing a configuration option (<code>variables</code>) to the <code>useQuery</code> hook. <code>{ variables: { first: 5 } }</code> was also passed as the second argument. The <code>variables</code> option is an object that contains all of the variables we want to pass to our GraphQL query. In this case, we passed an object <code>{ first: 5 }</code> to specify that we want the first five Pokemons.</p>
<p>If the query is still loading, <code>&lt;p&gt;Loading...&lt;/p&gt;</code> is returned to signify the user while <code>&lt;p&gt;Error: {error.message}&lt;/p&gt;</code> will be returned if there is an error.</p>
<p>The <code>pokemons</code> constant was created to hold the value of the Pokemons property of the data object. If <code>data.pokemons</code> is not available, the <code>pokemons</code> constant will be an empty array.</p>
<p>A div is returned with a <code>classname</code> of <code>container</code> which checks if <code>pokemons</code> is available and maps the array over the <code>Pokemon</code> component.</p>
<p>Let's create the <code>Pokemon</code> component:</p>
<p>📂src/components/Pokemon.jsx</p>
<h2 id="heading-pokemon-component">Pokemon Component</h2>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Pokemon</span>(<span class="hljs-params">{ pokemon }</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"pokemon"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"pokemon__name"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{pokemon.name}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"pokemon__meta"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>{pokemon.maxHP}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>{pokemon.maxCP}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"pokemon__image"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{pokemon.image}</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">{pokemon.name}</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"pokemon__attacks"</span>&gt;</span>
        {pokemon.attacks.special.slice(0, 3).map((attack) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{</span>`${<span class="hljs-attr">attack.name</span>}<span class="hljs-attr">-</span>${<span class="hljs-attr">attack.damage</span>}`}&gt;</span>{attack.name}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        ))}
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>The structure of an instance of a Pokemon is defined here with the classname for styling. The <code>name</code>, <code>maxHP</code>, <code>maxCP</code>, <code>image</code> and <code>attacks</code> array will be rendered.</p>
<p>Let's create the <code>GET_POKEMONS</code> GraphQL query.</p>
<p>📂src/graphql/get-pokemons</p>
<h2 id="heading-graphql-query">GraphQL Query</h2>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> gql <span class="hljs-keyword">from</span> <span class="hljs-string">"graphql-tag"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> GET_POKEMONS = gql<span class="hljs-string">`
  query pokemons($first: Int!) {
    pokemons(first: $first) {
      id
      name
      image
      maxHP
      maxCP
      attacks {
        special {
          name
          damage
        }
      }
    }
  }
`</span>;
</code></pre>
<p>You imported <code>gql</code> from <code>graphql-tag</code> and created a GraphQL query named <code>GET_POKEMONS</code>.</p>
<p>The <code>pokemons</code> query function was wrapped in strings for the <code>gql</code> function to parse them into query documents.</p>
<p><code>$first: Int!</code> means that your query is expecting a variable called <code>first</code>, which is an integer, and the <code>!</code> symbol after the <code>Int</code> means that the variable is required.</p>
<p>Recall that we created the <code>variables</code> object in the <code>PokemonsContainer</code> component, it's here below.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> { loading, error, data } = useQuery(GET_POKEMONS, {
   <span class="hljs-attr">variables</span>: { <span class="hljs-attr">first</span>: <span class="hljs-number">5</span> },
 });
</code></pre>
<p><code>pokemons(first: $first)</code> was also declared. <code>$first</code> will be assigned to 5 here (we passed in 9 in the above code snippet). Thus, the array will contain only 5 objects. Each object will contain <code>id</code>, <code>name</code>, <code>image</code>, <code>maxHP</code>, <code>maxCP</code>, and attacks object which will contain the special object containing name and damage.</p>
<p>The GraphQL server might contain more properties but will only return the properties listed above. That is one of the cool functionalities of GraqhQL – it gives you only the data you request for.</p>
<h2 id="heading-styling-our-application">Styling our Application</h2>
<p>Your <strong>index.css</strong> should contain this:</p>
<pre><code class="lang-css"><span class="hljs-comment">/* RESETS
=========================================== */</span>
<span class="hljs-selector-tag">html</span> {
  <span class="hljs-attribute">-webkit-box-sizing</span>: border-box;
  <span class="hljs-attribute">box-sizing</span>: border-box;
}

*,
*<span class="hljs-selector-pseudo">:before</span>,
*<span class="hljs-selector-pseudo">:after</span> {
  <span class="hljs-attribute">-webkit-box-sizing</span>: inherit;
  <span class="hljs-attribute">box-sizing</span>: inherit;
}

<span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">20px</span> <span class="hljs-number">0</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span> <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">line-height</span>: <span class="hljs-number">1</span>;
  <span class="hljs-attribute">font-family</span>: <span class="hljs-string">"Segoe UI"</span>, Tahoma, Geneva, Verdana, sans-serif;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#202020</span>;
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#fbfbfb</span>;
  <span class="hljs-attribute">font-smooth</span>: always;
  <span class="hljs-attribute">-webkit-font-smoothing</span>: antialiased;
  <span class="hljs-attribute">-moz-osx-font-smoothing</span>: grayscale;
}

<span class="hljs-comment">/* POKEMON APPLICATION
=========================================== */</span>
<span class="hljs-selector-class">.container</span> {
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">max-width</span>: <span class="hljs-number">80%</span>;
  <span class="hljs-attribute">margin</span>: auto;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">100vh</span>;
  <span class="hljs-attribute">justify-content</span>: space-between;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">gap</span>: <span class="hljs-number">10px</span>;
}

<span class="hljs-selector-class">.container</span> <span class="hljs-selector-tag">p</span> {
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
}

<span class="hljs-selector-class">.container</span> <span class="hljs-selector-class">.pokemon</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">20%</span>;
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#fff</span>;
  <span class="hljs-attribute">background-clip</span>: border-box;
  <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.125</span>);
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">0.25rem</span>;
  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">0.125rem</span> <span class="hljs-number">0.25rem</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.075</span>);
  <span class="hljs-attribute">overflow</span>: hidden;
  <span class="hljs-comment">/* margin: 5px; */</span>
}

<span class="hljs-selector-class">.container</span> <span class="hljs-selector-class">.pokemon__name</span> {
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#ecd018</span>;
  <span class="hljs-attribute">text-align</span>: center;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">10px</span>;
}

<span class="hljs-selector-class">.container</span> <span class="hljs-selector-class">.pokemon__name</span> <span class="hljs-selector-tag">p</span> {
  <span class="hljs-attribute">text-transform</span>: uppercase;
  <span class="hljs-attribute">font-weight</span>: bold;
  <span class="hljs-attribute">color</span>: white;
  <span class="hljs-attribute">letter-spacing</span>: <span class="hljs-number">4px</span>;
  <span class="hljs-attribute">text-shadow</span>: <span class="hljs-number">0px</span> <span class="hljs-number">1px</span> <span class="hljs-number">2px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.4</span>);
}

<span class="hljs-selector-class">.container</span> <span class="hljs-selector-class">.pokemon__image</span> {
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">min-height</span>: <span class="hljs-number">300px</span>;
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">justify-content</span>: center;
}

<span class="hljs-selector-class">.container</span> <span class="hljs-selector-class">.pokemon__image</span> <span class="hljs-selector-tag">img</span> {
  <span class="hljs-attribute">max-width</span>: <span class="hljs-number">100%</span>;
  <span class="hljs-attribute">height</span>: auto;
}

<span class="hljs-selector-class">.container</span> <span class="hljs-selector-class">.pokemon__attacks</span> {
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">padding-left</span>: <span class="hljs-number">10px</span>;
  <span class="hljs-attribute">padding-right</span>: <span class="hljs-number">10px</span>;
  <span class="hljs-attribute">justify-content</span>: space-between;
}

<span class="hljs-selector-class">.container</span> <span class="hljs-selector-class">.pokemon__attacks</span> <span class="hljs-selector-tag">span</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">32%</span>;
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#f16820</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">3px</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">7px</span>;
  <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">700</span>;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
  <span class="hljs-attribute">padding-left</span>: <span class="hljs-number">10px</span>;
  <span class="hljs-attribute">padding-right</span>: <span class="hljs-number">10px</span>;
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">12px</span>;
  <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">10px</span>;
  <span class="hljs-attribute">word-wrap</span>: break-word;
  <span class="hljs-attribute">text-align</span>: center;
  <span class="hljs-attribute">line-height</span>: <span class="hljs-number">15px</span>;
}

<span class="hljs-selector-class">.container</span> <span class="hljs-selector-class">.pokemon__meta</span> {
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">justify-content</span>: space-between;
  <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">10px</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span> <span class="hljs-number">10px</span>;
}

<span class="hljs-selector-class">.container</span> <span class="hljs-selector-class">.pokemon__meta</span> <span class="hljs-selector-tag">span</span> {
  <span class="hljs-attribute">color</span>: white;
  <span class="hljs-attribute">text-shadow</span>: <span class="hljs-number">0px</span> <span class="hljs-number">1px</span> <span class="hljs-number">2px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.4</span>);
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#7bb7b7</span>;
  <span class="hljs-attribute">font-weight</span>: bold;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">5px</span> <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">5px</span>;
}
</code></pre>
<p>All things done right, you should have this in your browser:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1712103327205/94a0fc27-6e6e-4441-b7e7-c3e3df005383.png" alt="Image" width="1920" height="978" loading="lazy">
<em>a picture showing the five pokemons data in the browser</em></p>
<p>You can get the GitHub code here: <a target="_blank" href="https://github.com/segunajibola/pokemon-graphql">https://github.com/segunajibola/pokemon-graphql</a></p>
<p>You can also view the live site hosted on Vercel here: <a target="_blank" href="http://pokemonsapp.vercel.app"><strong>pokemonsapp.vercel.app</strong></a></p>
<p>Check my portfolio of projects: <a target="_blank" href="https://segunajibola.com">segunajibola.com</a></p>
<h2 id="heading-conclusionhttpspokemonsappvercelapp"><a target="_blank" href="https://pokemonsapp.vercel.app/">Conclusion</a></h2>
<p>That will be all. I hope you found value here as you learn more about the web.</p>
<p>If you enjoyed this article and want to see more content related to JavaScript and web development, then follow me here, <a target="_blank" href="https://x.com/intent/follow?screen_name=iamsegunajibola">Twitter (X)</a> or connect on <a target="_blank" href="https://www.linkedin.com/mwlite/in/segun-ajibola-511502175">LinkedIn</a>. I'd be happy to count you as one of my ever-growing group of awesome friends on the internet.</p>
<p>You can also join my <a target="_blank" href="https://chat.whatsapp.com/E57KqFYQK9B1woySXTaqKr">WhatsApp developer community</a> and <a target="_blank" href="https://chat.whatsapp.com/KH7r2EA6kMgHuHwVfM4VFB">OpenSource community</a> of 330+ developers learning and building cool projects.</p>
<p>If you also want to support me, you can also <a target="_blank" href="https://www.buymeacoffee.com/segunajibola">buy me a cup of coffee</a>.</p>
<p>Thanks and bye. 👋</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Get Started with GraphQL and Node.js ]]>
                </title>
                <description>
                    <![CDATA[ By Ramón Morcillo The main purpose of this server-client Node.js project is to help other people understand how GraphQL exposes data from the Server and how the Client fetches it.  I have tried to make it as simple as possible - if you want to dive i... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/get-started-with-graphql-and-nodejs/</link>
                <guid isPermaLink="false">66d460c78812486a37369d44</guid>
                
                    <category>
                        <![CDATA[ Apollo GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Tutorial ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 23 Feb 2021 18:21:36 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/02/getting-started-with-graphql.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ramón Morcillo</p>
<p>The main purpose of this server-client <a target="_blank" href="https://nodejs.org/en/">Node.js</a> project is to help other people <strong>understand how GraphQL exposes data from the Server and how the Client fetches it</strong>. </p>
<p>I have tried to make it as simple as possible - if you want to dive into the code of the project you can find it <a target="_blank" href="https://github.com/reymon359/graphql-hello-world-server">here</a>.</p>
<p>Now, straight to the point: <a target="_blank" href="https://graphql.org/">GraphQL</a> is a <strong>query language for <a target="_blank" href="https://en.wikipedia.org/wiki/Application_programming_interface">APIs</a></strong> developed and <a target="_blank" href="https://engineering.fb.com/core-data/graphql-a-data-query-language/">open-sourced by Facebook</a> to speed up the request process.</p>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Representational_state_transfer">REST</a> has been a popular way to expose data from a server. But instead of having <strong>multiple endpoints</strong> that return fixed data structures, GraphQL just has <strong>a single endpoint</strong>. And it is the client's job to specify what data it needs from it.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li>Getting started</li>
<li>How to Define the Schema</li>
<li>How to Add the Resolver function</li>
<li>How to Set up the Server</li>
<li>How to Set up the Client</li>
<li>How to Fetch Data from the Server</li>
<li>How to Display the Data</li>
<li>Conclusion</li>
<li>Useful resources<ul>
<li>Docs 📚</li>
<li>Learn 📝</li>
<li>Tools 🔧</li>
<li>IDEs 💻</li>
<li>Extras 🍍</li>
</ul>
</li>
</ul>
<h2 id="heading-getting-started">Getting started</h2>
<p>The first step is to <a target="_blank" href="https://nodejs.org/en/download/">download and install Node.js</a> in case you haven't already. Once you have it installed let's begin with the directory structure. </p>
<p>The project will be composed of <strong>two directories</strong>, one for the Client and another for the Server. I have chosen to keep both inside the project root directory, but then you can split it into two separate projects or any way you want.</p>
<pre><code class="lang-text">📁 project
├── 📁 client
└── 📁 server
</code></pre>
<p>Now we will initialize the project in the server directory. Change the location to the server folder in your terminal and run <code>npm init</code> to fill in the project info and generate the <strong>package.json</strong> file. </p>
<p>Or you can <code>npm init -y</code> which tells the generator to use the defaults (instead of asking questions and simply generating an empty npm project without going through an interactive process).</p>
<p>The next step will be to install <a target="_blank" href="https://github.com/graphql/graphql-js">GraphQL.js</a> and <a target="_blank" href="https://github.com/apollographql/apollo-server">Apollo Server</a> to our server. GraphQL.js will provide two important capabilities:</p>
<ul>
<li>Building a type schema, which we will do in the <a class="post-section-overview" href="#define-the-schema">next step</a>.</li>
<li>Serving queries against that type schema.</li>
</ul>
<p>To install it just run <code>npm install graphql</code>. I am assuming you are using a version of NPM equal or higher than <strong>5.0.0</strong> so you <a target="_blank" href="https://blog.npmjs.org/post/161081169345/v500">do not need</a> to add <code>--save</code> when installing a dependency to be saved in the <code>package.json</code>.</p>
<p>Apollo Server, on the other hand, will help us to implement the GraphQL functionalities. It is part of the <a target="_blank" href="https://www.apollographql.com/">Apollo Data Graph Platform</a>.</p>
<blockquote>
<p>Apollo is a platform for building a data graph, a communication layer that seamlessly connects your application clients (such as React and iOS apps) to your back-end services. Is an implementation of GraphQL designed for the needs of product engineering teams building modern, data-driven applications. - <a target="_blank" href="https://www.apollographql.com/docs/">Apollo Documentation</a></p>
</blockquote>
<p>What you need to know about Apollo, at least for now, is that it’s a community that builds on top of GraphQL and provides different <strong>tools to help you build your projects</strong>. The tools provided by Apollo are mainly 2: Client and Server.</p>
<ul>
<li><p><strong>Apollo Client</strong> helps your Frontend communicate with a GraphQL API. It has support for the most popular frameworks such as React, Vue, or Angular and native development on iOS and Android.</p>
</li>
<li><p><strong>Apollo Server</strong> is the GraphQL server layer in your backend that delivers the responses back to the client requests.</p>
</li>
</ul>
<p>Now that you understand Apollo better and why we will use it, let's continue setting up GraphQL.</p>
<h2 id="heading-how-to-define-the-schema">How to Define the Schema</h2>
<p>A GraphQL Schema is at the core of any GraphQL server implementation. It <strong>describes the shape of your data</strong>, defining it with a hierarchy of <strong>types</strong> with fields that are populated from your data source. It also specifies which <strong>queries</strong> and <strong>mutations</strong> are available, so the client knows about the information that can be requested or sent.</p>
<p>For example, if we wanted to build a music application, our simplest schema, usually defined in a <code>schema.graphql</code> file, would contain two <strong>Object types</strong>: <code>Song</code> and <code>Author</code>, like this:</p>
<pre><code class="lang-js">type Song {
  <span class="hljs-attr">title</span>: <span class="hljs-built_in">String</span>
  <span class="hljs-attr">author</span>: Author
}

type Author {
  <span class="hljs-attr">name</span>: <span class="hljs-built_in">String</span>
  <span class="hljs-attr">songs</span>: [Song]
}
</code></pre>
<p>Then we would have a <strong>Query type</strong> to define the available queries: <code>getSongs</code> and <code>getAuthors</code>, each returning a list of the corresponding type.</p>
<pre><code class="lang-js">type Query {
  <span class="hljs-attr">getSongs</span>: [Song]
  <span class="hljs-attr">getAuthors</span>: [Author]
}
</code></pre>
<p>To keep it as simple as possible, our schema will have just <strong>a single Query</strong> type which will return a <code>String</code>.</p>
<pre><code class="lang-js">type Query {
  <span class="hljs-attr">greeting</span>: <span class="hljs-built_in">String</span>
}
</code></pre>
<p>We can use <strong>any programming language</strong> to create a GraphQL schema and <strong>build an interface around it</strong>, but as I explained before we will use Apollo server to execute GraphQL queries. </p>
<p>So we create a new <code>server.js</code> file in the server directory to define the Schema on it.</p>
<pre><code class="lang-text">📁 project
├── 📁 client
└── 📁 server
    └── 📄 server.js
</code></pre>
<p>Now we install apollo-server by running <code>npm install apollo-server</code>.</p>
<p>We have to import the <strong>tag function</strong> <code>gql</code> from <strong>apollo-server</strong> to parse the schema this way: <code>const {gql} = require('apollo-server');</code> and then declare a <code>typeDefs</code> constant which is an <a target="_blank" href="https://en.wikipedia.org/wiki/Abstract_syntax_tree">abstract syntax tree</a> of the Graphql code.</p>
<blockquote>
<p>When a GraphQL server receives a query to process, it generally comes in as a String. This string must be tokenized and parsed into a representation that the machine understands. This representation is called an abstract syntax tree.</p>
</blockquote>
<p>If you want to learn more about abstract syntax trees, <a target="_blank" href="https://astexplorer.net/">AST Explorer</a> is an online tool that lets you explore the syntax tree created by a chosen language as a parser.</p>
<p>The <code>server.js</code> file would look like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { gql } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'apollo-server'</span>);

<span class="hljs-keyword">const</span> typeDefs = gql<span class="hljs-string">`
  type Query {
    greeting: String
  }
`</span>;
</code></pre>
<h2 id="heading-how-to-add-the-resolver-function">How to Add the Resolver Function</h2>
<p>Now that we have defined our Schema, we need a way to answer the client requests for that data: the <strong>resolvers</strong>.</p>
<p><strong>A resolver is a function that handles the data for each one of the fields of your schema</strong>. You can send that data to the client by <strong>fetching a back-end database</strong> or a third-party <strong>API</strong>, among others.</p>
<p>They have to <strong>match the type definitions of the Schema</strong>. In our case, we just have one type definition, Query, which returns a greeting of type <code>String</code>, so we will define a resolver for the <code>greeting</code> field, like so:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> resolvers = {
  <span class="hljs-attr">Query</span>: {
    <span class="hljs-attr">greeting</span>: <span class="hljs-function">() =&gt;</span> <span class="hljs-string">'Hello GraphQL world!👋'</span>,
  },
};
</code></pre>
<p>As I explained at the beginning, we will keep this example as simple as possible. But keep in mind that in a real case <strong>here is where you have to make the queries</strong> to the database, external API, or from whichever one you intend to extract the query data.</p>
<h2 id="heading-how-to-set-up-the-server">How to Set up the Server</h2>
<p>In the same <code>server.js</code>, we define and create a new <code>ApolloServer</code> object, passing the <code>Schema</code> (typeDefs) and <code>resolvers</code> as parameters.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { ApolloServer, gql } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'apollo-server'</span>);

<span class="hljs-keyword">const</span> server = <span class="hljs-keyword">new</span> ApolloServer({ typeDefs, resolvers });
</code></pre>
<p>Then calling the <code>listen</code> method we start the server on the <code>port</code> that we specify in the params.</p>
<pre><code class="lang-js">server
  .listen({ <span class="hljs-attr">port</span>: <span class="hljs-number">9000</span> })
  .then(<span class="hljs-function"><span class="hljs-params">serverInfo</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Server running at <span class="hljs-subst">${serverInfo.url}</span>`</span>));
</code></pre>
<p>We can also <strong>destructure</strong> the ServerInfo <code>url</code> when logging it.</p>
<pre><code class="lang-js">server
  .listen({ <span class="hljs-attr">port</span>: <span class="hljs-number">9000</span> })
  .then(<span class="hljs-function">(<span class="hljs-params">{ url }</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Server running at <span class="hljs-subst">${url}</span>`</span>));
</code></pre>
<p>The <code>server.js</code> file should look like this right now:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { ApolloServer, gql } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'apollo-server'</span>);

<span class="hljs-keyword">const</span> typeDefs = gql<span class="hljs-string">`
  type Query {
    greeting: String
  }
`</span>;

<span class="hljs-keyword">const</span> resolvers = {
  <span class="hljs-attr">Query</span>: {
    <span class="hljs-attr">greeting</span>: <span class="hljs-function">() =&gt;</span> <span class="hljs-string">'Hello GraphQL world!👋'</span>,
  },
};

<span class="hljs-keyword">const</span> server = <span class="hljs-keyword">new</span> ApolloServer({ typeDefs, resolvers });
server
  .listen({ <span class="hljs-attr">port</span>: <span class="hljs-number">9000</span> })
  .then(<span class="hljs-function">(<span class="hljs-params">{ url }</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Server running at <span class="hljs-subst">${url}</span>`</span>));
</code></pre>
<p>Now if we run <code>node server/server.js</code> we will finally have our GraphQL server up and running!🎉</p>
<p>You can go and check it out on <a target="_blank" href="http://localhost:9000/">http://localhost:9000/</a></p>
<pre><code class="lang-bash">~/graphql-hello-world-server
&gt; node server/server.js
Server running at http://localhost:9000/
</code></pre>
<p>If this is your first time using GraphQL, you may be thinking <strong>what is this application I am seeing in front of me if we have not written a single line of client code?</strong>.</p>
<p>The answer to that question is the <strong>GraphQL Playground</strong>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/graphql-playground.png" alt="GraphQL Playground. Source: https://github.com/prisma-labs/graphql-playground" width="600" height="400" loading="lazy"></p>
<blockquote>
<p><a target="_blank" href="https://github.com/prisma-labs/graphql-playground">GraphQL Playground</a> is a graphical, interactive, in-browser GraphQL IDE, created by <a target="_blank" href="https://www.prisma.io/">Prisma</a> and based on <a target="_blank" href="https://github.com/graphql/graphiql">GraphiQL</a>. - <a target="_blank" href="https://www.apollographql.com/docs/apollo-server/testing/graphql-playground/">Apollo docs</a></p>
</blockquote>
<p>But what does that mean? It means that this is an environment where we can perform Queries, Mutations, or Subscriptions to our schema and interact with its data.</p>
<p>If you have worked with <strong>RESTful</strong> requests before this would be some kind of equivalent to <a target="_blank" href="https://www.postman.com/">Postman</a>. It's just that here you <strong>do not have to download and configure anything</strong>, it just <strong>comes by default</strong> with Apollo!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/awesome-chris-pratt.gif" alt="Awesome" width="600" height="400" loading="lazy">
So let's try it out!</p>
<ol>
<li>On the left panel write the <code>greeting</code> query we defined in our schema.</li>
<li>Then press the ▶ button that is in the middle.</li>
<li>And <em>Voila!</em> On the right panel appears the data we defined in our resolver to return.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/greeting-query-on-playground.gif" alt="Writting query on GraphQl Playground" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-set-up-the-client">How to Set up the Client</h2>
<p>Now that we have our server up and running, let's focus on the client part. We will start by creating a <code>client.html</code> file inside our client folder.</p>
<pre><code class="lang-text">📁 project
├── 📁 client
|   └── 📄 client.html
└── 📁 server
    └── 📄 server.js
</code></pre>
<p>The <code>index.html</code> file will have the basics of any <code>HTML</code> file and a loading header <code>&lt;h1&gt;Loading...&lt;/h1&gt;</code> to show the user something while we request the data from the server.</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Hello World GraphQL Client<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"app.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<h2 id="heading-how-to-fetch-data-from-the-server">How to Fetch Data from the Server</h2>
<p>First off, in the same client folder, we create an <code>app.js</code> file where we will write the client logic to fetch the data from the server.</p>
<pre><code class="lang-text">📁 project
├── 📁 client
|   └── 📄 client.html
|   └── 📄 app.js
└── 📁 server
    └── 📄 server.js
</code></pre>
<p>Inside it, we set the server URL to the one from which we will make the request.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> GRAPHQL_URL = <span class="hljs-string">'http://localhost:9000/'</span>;
</code></pre>
<p>Next, we define our async function <code>fetchGreeting()</code> to fetch the greeting from the server. We will use the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch">fetch API</a> to perform the HTTP request which by default returns a promise to which we can subscribe and get the answer asynchronously.</p>
<pre><code class="lang-js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchGreeting</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(GRAPHQL_URL, {
    <span class="hljs-attr">method</span>: <span class="hljs-string">'POST'</span>,
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'application/json'</span>,
    },
    <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({
      <span class="hljs-attr">query</span>: <span class="hljs-string">`
        query {
          greeting
        }
      `</span>,
    }),
  });

  <span class="hljs-keyword">const</span> responseBody = <span class="hljs-keyword">await</span> response.json();
  <span class="hljs-built_in">console</span>.log(responseBody);
}
</code></pre>
<p>A detail to take into account is that the method of the request is <code>POST</code>. This can confuse us if we are used to working with <code>RESTful</code> because this same request made in <code>RESTful</code>, where we just want to read information from the server, would usually be done with the method <code>GET</code>.</p>
<p>The thing is that with GraphQL we always make <code>POST</code> requests where we pass <strong>the query in the payload</strong> (body).</p>
<p>Finally, we just call our method <code>fetchGreeting();</code></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> GRAPHQL_URL = <span class="hljs-string">'http://localhost:9000/'</span>;

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchGreeting</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(GRAPHQL_URL, {
    <span class="hljs-attr">method</span>: <span class="hljs-string">'POST'</span>,
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'application/json'</span>,
    },
    <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({
      <span class="hljs-attr">query</span>: <span class="hljs-string">`
        query {
          greeting
        }
      `</span>,
    }),
  });

  <span class="hljs-keyword">const</span> responseBody = <span class="hljs-keyword">await</span> response.json();
  <span class="hljs-built_in">console</span>.log(responseBody);
}

fetchGreeting();
</code></pre>
<p>If you open the file in your browser and see the <strong>console on the developer tools</strong> you can see that we actually got the greeting data from the query 🙌!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/fetching-data-from-server-3.png" alt="Fetching data from the server" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-display-the-data">How to Display the Data</h2>
<p>Now that we have successfully gotten the data from the server, lets <strong>update the loading title</strong>. The first thing we will do is destructure the response and return just the <code>data</code> from it.</p>
<p>Just replace this part of the code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> responseBody = <span class="hljs-keyword">await</span> response.json();
<span class="hljs-built_in">console</span>.log(responseBody);
</code></pre>
<p>With this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { data } = <span class="hljs-keyword">await</span> response.json();
<span class="hljs-keyword">return</span> data;
</code></pre>
<p>Then we will update the title with the <code>greeting</code> returned <strong>inside the data from the response</strong></p>
<pre><code class="lang-js">fetchGreeting().then(<span class="hljs-function">(<span class="hljs-params">{ greeting }</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> title = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'h1'</span>);
  title.textContent = greeting;
});
</code></pre>
<p>So our <code>app.js</code> file will end up having this look:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> GRAPHQL_URL = <span class="hljs-string">'http://localhost:9000/'</span>;

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchGreeting</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(GRAPHQL_URL, {
    <span class="hljs-attr">method</span>: <span class="hljs-string">'POST'</span>,
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-string">'content-type'</span>: <span class="hljs-string">'application/json'</span>,
    },
    <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({
      <span class="hljs-attr">query</span>: <span class="hljs-string">`
        query {
          greeting
        }
      `</span>,
    }),
  });

  <span class="hljs-keyword">const</span> { data } = <span class="hljs-keyword">await</span> response.json();
  <span class="hljs-keyword">return</span> data;
}

fetchGreeting().then(<span class="hljs-function">(<span class="hljs-params">{ greeting }</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> title = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'h1'</span>);
  title.textContent = greeting;
});
</code></pre>
<p>Our <code>index.html</code> will have the loading title updated with the data fetched from our server!🎉</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/02/displaying-the-data.png" alt="Displaying the data" width="600" height="400" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I hope you enjoyed the post and that this project has helped show you <strong>how graphql works under the hood</strong>, at least in a very simple way. </p>
<p>I know there are a lot of things that I have not explained or that I could have gone deeper into. But like any <code>hello world</code> project, this was intended for people who are beginners with it, so I wanted to keep it as simple as possible.</p>
<p>I'm looking forward to learning more about GraphQL and using it in future projects. If you've got any questions, suggestions, or feedback in general, don't hesitate to reach out on any of the social networks from <a target="_blank" href="https://ramonmorcillo.com">my site</a> or <a target="_blank" href="mailto:hey@ramonmorcillo.com">by mail</a>.</p>
<h2 id="heading-useful-graphql-resources">Useful GraphQL Resources</h2>
<p>Here is a collection of links and resources which have been useful for me to improve and learn more about GraphQL</p>
<h3 id="heading-docs">Docs 📚</h3>
<ul>
<li><a target="_blank" href="https://github.com/reymon359/graphql-hello-world-server">Project source code</a> - The Github repository with all the code from the project.</li>
<li><a target="_blank" href="https://graphql.org/">GraphQL main site</a> - GraphQL main site.</li>
<li><a target="_blank" href="https://graphql.org/">Apollo documentation</a> - The Apollo platform docs.</li>
</ul>
<h3 id="heading-learn">Learn 📝</h3>
<ul>
<li><a target="_blank" href="https://www.howtographql.com/">How to GraphQL</a> - Free and open-source tutorials to learn all around GraphQL to go from zero to production.</li>
<li><a target="_blank" href="https://www.udemy.com/course/graphql-by-example/">GraphQL by Example</a> - Great course where you learn GraphQL by writing full-stack JavaScript applications with Node.js, Express, Apollo Server, React, Apollo Client.</li>
<li><a target="_blank" href="https://graphql.org/learn/">Introduction to GraphQL</a> - A series of articles to learn about GraphQL, how it works, and how to use it.</li>
</ul>
<h3 id="heading-tools">Tools 🔧</h3>
<ul>
<li><a target="_blank" href="https://www.apollographql.com/">Apollo GraphQL</a> - Main site of the Apollo GraphQL implementation.</li>
<li><a target="_blank" href="https://github.com/prisma-labs/graphql-playground">GraphQL Playground</a> - Repository of the GraphQL Playground IDE we used on the project.</li>
</ul>
<h3 id="heading-ides">IDEs 💻</h3>
<ul>
<li><a target="_blank" href="https://plugins.jetbrains.com/plugin/8097-js-graphql">JS GraphQL</a> - WebStorm and other IntelliJ-based IDEs plugin to support GraphQL language including tagged template literals in JavaScript and TypeScript.</li>
<li><a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=Prisma.vscode-graphql">GraphQL</a> - GraphQL extension for VSCode adds syntax highlighting, validation, and language features like go to definition, hover information, and autocompletion for GraphQL projects. This extension also works with queries annotated with gql tag.</li>
<li><a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=kumar-harsh.graphql-for-vscode">GraphQL for VSCode</a> - VSCode GraphQL syntax highlighting, linting, auto-complete, and more!</li>
</ul>
<h3 id="heading-extras">Extras 🍍</h3>
<ul>
<li><a target="_blank" href="https://github.com/APIs-guru/graphql-apis">GraphQL APIs</a> - A list of public GraphQL APIs to test your skills or to build something with them.</li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=783ccP__No8">GraphQL: The Documentary</a> - A 30 min video that explores the story of why and how GraphQL appeared, and the impact it's having on big tech companies worldwide, including Facebook, Twitter, Airbnb, and Github.</li>
</ul>
<p>I hope you enjoyed this article. You can read <a target="_blank" href="https://ramonmorcillo.com/getting-started-with-graphql-and-nodejs/">it too on my site</a> along with others! If you've got any questions, suggestions, or feedback in general, don't hesitate to reach out on any of the social networks from <a target="_blank" href="https://ramonmorcillo.com/">my site</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Fetch GraphQL Data in Next.js with Apollo GraphQL ]]>
                </title>
                <description>
                    <![CDATA[ Next.js has been steadily growing as a must-have tool for developers creating React apps. Part of what makes it great is its data fetching APIs that request data for each page. But how can we use that API to make GraphQL queries for our app? What is... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-fetch-graphql-data-in-next-js-with-apollo-graphql/</link>
                <guid isPermaLink="false">66b8e35d0cedc1f2a4f7069d</guid>
                
                    <category>
                        <![CDATA[ Apollo GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Next.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Tue, 01 Dec 2020 16:22:46 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/11/apollo.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Next.js has been steadily growing as a must-have tool for developers creating React apps. Part of what makes it great is its data fetching APIs that request data for each page. But how can we use that API to make GraphQL queries for our app?</p>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-graphql">What is GraphQL?</a></li>
<li><a class="post-section-overview" href="#heading-what-is-apollo-graphql">What is Apollo GraphQL?</a></li>
<li><a class="post-section-overview" href="#heading-fetching-data-in-nextjs">Fetching data in Next.js</a></li>
<li><a class="post-section-overview" href="#heading-what-are-we-going-to-build">What are we going to build?</a></li>
<li><a class="post-section-overview" href="#heading-step-0-creating-a-new-nextjs-app">Step 0: Creating a new Next.js app</a></li>
<li><a class="post-section-overview" href="#heading-step-1-adding-apollo-graphql-to-a-nextjs-app">Step 1: Adding Apollo GraphQL to a Next.js app</a></li>
<li><a class="post-section-overview" href="#heading-step-2-adding-data-to-a-nextjs-page-with-getstaticprops">Step 2: Adding data to a Next.js page with getStaticProps</a></li>
<li><a class="post-section-overview" href="#heading-step-3-fetch-data-with-a-graphql-query-in-nextjs-using-apollo-client">Step 3: Fetch data with a GraphQL query in Next.js using Apollo Client</a></li>
<li><a class="post-section-overview" href="#heading-step-4-adding-spacex-launch-data-to-the-page">Step 4: Adding SpaceX launch data to the page</a></li>
</ul>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/oxUPXhZ1t9I" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-what-is-graphql">What is GraphQL?</h2>
<p><a target="_blank" href="https://graphql.org/">GraphQL</a> is a query language and runtime that provides a different way of interacting with an API than what you would expect with a traditional REST API.</p>
<p>When fetching data, instead of making a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET">GET</a> request to a URL to grab that data, GraphQL endpoints take a “query”. That query consists of what data you want to grab, whether it’s an entire dataset or a limited portion of it.</p>
<p>If your data looks something like this:</p>
<pre><code>Movie {
  <span class="hljs-string">"title"</span>: <span class="hljs-string">"Sunshine"</span>,
  <span class="hljs-string">"releaseYear"</span>: <span class="hljs-string">"2007"</span>,
  <span class="hljs-string">"actors"</span>: [...],
  <span class="hljs-string">"writers"</span>: [...]
}
</code></pre><p>And you only want to grab the title and the year it was released, you could send in a query like this:</p>
<pre><code>Movie {
  title
  releaseYear
}
</code></pre><p>Grabbing only the data you need.</p>
<p>The cool thing is, you can also provide complex relationships between the data. With a single query, you could additionally request that data from different parts of the database that would traditionally take multiple requests with a REST API.</p>
<h2 id="heading-what-is-apollo-graphql">What is Apollo GraphQL?</h2>
<p><a target="_blank" href="https://www.apollographql.com/">Apollo GraphQL</a> at its core is a GraphQL implementation that helps people bring together their data as a graph.</p>
<p>Apollo also provides and maintains a GraphQL client, which is what we’re going to use, that allows people to programmatically interact with a GraphQL API.</p>
<p>Using Apollo’s GraphQL client, we’ll be able to make requests to a GraphQL API similar to what we would expect with a REST-based request client.</p>
<h2 id="heading-fetching-data-in-nextjs">Fetching data in Next.js</h2>
<p>When fetching data with Next.js, you have a few options for how you want to fetch that data.</p>
<p>First, you could go the client side route and make the request once the page loads. The issue with this is that you’re then putting the burden on the client to take the time to make those requests.</p>
<p>The Next.js APIs like <code>getStaticProps</code> and <code>getServerSideProps</code> allow you to collect data at different parts of the lifecycle, giving us the opportunity to <a target="_blank" href="https://www.youtube.com/watch?v=6ElI2ZJ4Uro">make a completely static app</a> or one that’s server-side rendered. That will serve the data already rendered to the page straight to the browser.</p>
<p>By using one of those methods, we can request data along with our pages and inject that data as props right into our app.</p>
<h2 id="heading-what-are-we-going-to-build">What are we going to build?</h2>
<p>We’re going to create a Next.js app that shows the latest launches from SpaceX.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/11/spacex-launches-demo.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>SpaceX launches demo</em></p>
<p>We’ll use the API maintained by <a target="_blank" href="https://spacex.land/">SpaceX Land</a> to make a GraphQL query that grabs the last 10 flights. Using <a target="_blank" href="https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation">getStaticProps</a>, we’ll make that request at build time, meaning our page will be rendered statically with our data.</p>
<h2 id="heading-step-0-creating-a-new-nextjs-app">Step 0: Creating a new Next.js app</h2>
<p>Using Create Next App, we can quickly spin up a new Next.js app that we can use to immediately start diving into the code.</p>
<p>Inside your terminal, run the command:</p>
<pre><code>npx create-next-app my-spacex-launches
</code></pre><p><em>Note: you don’t have to use <code>my-spacex-app</code>, feel free to replace that with whatever name you want to give the project.</em></p>
<p>After running that script, Next.js will set up a new project and install the dependencies.</p>
<p>Once finished, you can start up your development server:</p>
<pre><code>cd my-spacex-launches
npm run dev
</code></pre><p>This will start a new server at <a target="_blank" href="http://localhost:3000">http://localhost:3000</a> where you can now visit your new app!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/11/new-nextjs-app-1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>New Next.js app</em></p>
<h2 id="heading-step-1-adding-apollo-graphql-to-a-nextjs-app">Step 1: Adding Apollo GraphQL to a Next.js app</h2>
<p>To get started with making a GraphQL query, we’ll need a GraphQL client. We’ll use the Apollo GraphQL Client to make our queries to the SpaceX GraphQL server.</p>
<p>Back inside of the terminal, run the following command to install our new dependencies:</p>
<pre><code>npm install @apollo/client graphql
</code></pre><p>This will add the Apollo Client as well as GraphQL, which we’ll need to to form the GraphQL query.</p>
<p>And once installation completes, we’ll be ready to get started Using Apollo Client.</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-spacex-launches/commit/0fcc3a0141e7bfb795c3c91c355fdfc459a17332">Follow along with the commit!</a></p>
<h2 id="heading-step-2-adding-data-to-a-nextjs-page-with-getstaticprops">Step 2: Adding data to a Next.js page with getStaticProps</h2>
<p>Before we fetch any data with Apollo, we’re going to set up our page to be able to request data then pass that data as a prop to our page at build time.</p>
<p>Let’s define a new function at the bottom of the page below our <code>Home</code> component called <code>getStaticProps</code>:</p>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getStaticProps</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// Code will go here</span>
}
</code></pre><p>When Next.js builds our app, it knows to look for this function. So when we export it, we’re letting Next.js know we want to run code in that function.</p>
<p>Inside our <code>getStaticProps</code> function, we’re going to be ultimately returning our props to the page. To test this out, let’s add the following to our function:</p>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getStaticProps</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">props</span>: {
      <span class="hljs-attr">launches</span>: []
    }
  }
}
</code></pre><p>Here, we’re passing a new prop of <code>launches</code> and setting it to an empty array.</p>
<p>Now, back inside of our <code>Home</code> component, let’s add a new destructured argument that will serve as our prop along with a <code>console.log</code> statement to test our new prop:</p>
<pre><code><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Home</span>(<span class="hljs-params">{ launches }</span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'launches'</span>, launches);
</code></pre><p>If we reload the page, we can see that we’re now logging out our new prop <code>launches</code> which includes an empty array just like we defined.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/11/nextjs-console-log-launches-array.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Logging launches prop</em></p>
<p>The great thing about this is that given that the <code>getStaticProps</code> function we’re creating is asynchronous, we can make any request we’d like (including a GraphQL query) and return it as props to our page, which is what we’ll do next.</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-spacex-launches/commit/868a4f6b31200cd2407b4aa2fe37a243fc235932">Follow along with the commit!</a></p>
<h2 id="heading-step-3-fetch-data-with-a-graphql-query-in-nextjs-using-apollo-client">Step 3: Fetch data with a GraphQL query in Next.js using Apollo Client</h2>
<p>Now that our application is prepared to add props to the page and we have Apollo installed, we can finally make a request to grab our SpaceX data.</p>
<p>Here, we’re going to use the Apollo Client, which will allow us to interface with the SpaceX GraphQL server. We’ll make our request to the API using the Next.js getStaticProps method, allowing us to dynamically create props for our page when it builds.</p>
<p>First, let’s import our Apollo dependencies into the project. At the top of the page add:</p>
<pre><code><span class="hljs-keyword">import</span> { ApolloClient, InMemoryCache, gql } <span class="hljs-keyword">from</span> <span class="hljs-string">'@apollo/client'</span>;
</code></pre><p>This is going to include the Apollo Client itself, <code>InMemoryCache</code> which allows Apollo to optimize by reading from cache, and <code>gql</code> which we’ll use to form our GraphQL query.</p>
<p>Next, to use the Apollo Client, we need to set up a new instance of it.</p>
<p>Inside the top of the <code>getStaticProps</code> function, add:</p>
<pre><code><span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> ApolloClient({
  <span class="hljs-attr">uri</span>: <span class="hljs-string">'https://api.spacex.land/graphql/'</span>,
  <span class="hljs-attr">cache</span>: <span class="hljs-keyword">new</span> InMemoryCache()
});
</code></pre><p>This creates a new Apollo Client instance using the SpaceX API endpoint that we’ll use to query against.</p>
<p>With our client, we can finally make a query. Add the following code below the client:</p>
<pre><code><span class="hljs-keyword">const</span> { data } = <span class="hljs-keyword">await</span> client.query({
  <span class="hljs-attr">query</span>: gql<span class="hljs-string">`
    query GetLaunches {
      launchesPast(limit: 10) {
        id
        mission_name
        launch_date_local
        launch_site {
          site_name_long
        }
        links {
          article_link
          video_link
          mission_patch
        }
        rocket {
          rocket_name
        }
      }
    }
  `</span>
});
</code></pre><p>This does a few things:</p>
<ul>
<li>Creates a new GraphQL query inside of the <code>gql</code> tag</li>
<li>Creates a new query request using <code>client.query</code></li>
<li>It uses <code>await</code> to make sure it finishes the request before continuing</li>
<li>And finally destructures <code>data</code> from the results, which is where the information we need is stored</li>
</ul>
<p>Inside of the GraphQL query, we’re telling the SpaceX API that we want to get <code>launchesPast</code>, which are the previous launches from SpaceX, and we want to get the last 10 of them (limit). Inside that, we define the data we’d like to query.</p>
<p>If we take a second to add a new console log statement after that, we can see what <code>data</code> looks like.</p>
<p>Once you refresh the page though, you’ll notice that you’re not seeing anything inside of the browser’s console.</p>
<p><code>getStaticProps</code> runs during the build process, meaning, it runs in node. Because of that, we can look inside of our terminal and we can see our logs there:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/11/logging-static-props-terminal.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Logging data to the terminal</em></p>
<p>After seeing that, we know that inside of the <code>data</code> object, we have a property called <code>launchesPast</code>, which includes an array of launch details.</p>
<p>Now, we can update our return statement to use <code>launchesPast</code>:</p>
<pre><code><span class="hljs-keyword">return</span> {
  <span class="hljs-attr">props</span>: {
    <span class="hljs-attr">launches</span>: data.launchesPast
  }
}
</code></pre><p>And if we add our <code>console.log</code> statement back to the top of the page to see what our <code>launches</code> prop looks like, we can see our launch data is now available as a prop to our page:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/11/logging-static-props-web-console.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Logging props to web console</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-spacex-launches/commit/f273bcde3d2baccd54e4c65930ab499dbe4862ed">Follow along with the commit!</a></p>
<h2 id="heading-step-4-adding-spacex-launch-data-to-the-page">Step 4: Adding SpaceX launch data to the page</h2>
<p>Now for the exciting part!</p>
<p>We have our launch data that we were able to use Apollo Client to request from the SpaceX GraphQL server. We made that request in <code>getStaticProps</code> so that we could make our data available as the <code>launches</code> prop that contains our launch data.</p>
<p>Digging into the page, we’re going to take advantage of what already exists. For instance, we can start by updating the <code>h1</code> tag and the paragraph below it to something that describes our page a little bit better.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/11/updated-page-title.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Updated page title</em></p>
<p>Next, we can use the already existing link cards to include all of our launch information.</p>
<p>To do this, let’s first add a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map">map</a> statement inside of the page’s grid, where the component we return is one of the cards, with launch details filled in:</p>
<pre><code>&lt;div className={styles.grid}&gt;
  {launches.map(<span class="hljs-function"><span class="hljs-params">launch</span> =&gt;</span> {
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{launch.id}</span> <span class="hljs-attr">href</span>=<span class="hljs-string">{launch.links.video_link}</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{styles.card}</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>{ launch.mission_name }<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">strong</span>&gt;</span>Launch Date:<span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span> { new Date(launch.launch_date_local).toLocaleDateString("en-US") }<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span></span>
    );
  })}
</code></pre><p>We can also get rid of the rest of the default Next.js cards including Documentation and Learn.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/11/list-of-spacex-launches.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Page with SpaceX launches</em></p>
<p>Our page now includes the last 10 launches from SpaceX along with the date of the launch!</p>
<p>We can even click any of those cards, and because we linked to the video link, we can now see the launch video.</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-spacex-launches/commit/e35ed076253e3648fa5d8cd62e993e4e9e436396">Follow along with the commit!</a></p>
<h2 id="heading-whats-next">What’s next?</h2>
<p>From here, we can include any additional data from inside of our <code>launches</code> array on our page. The API even includes mission patch images, which we can use to show nice graphics for each launch.</p>
<p>You can even add additional data to the GraphQL query. Each launch has a lot of information available including the launch crew and more details about the rocket.</p>
<p><a target="_blank" href="https://api.spacex.land/graphql/">https://api.spacex.land/graphql/</a></p>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://jamstackhandbook.com/">
      <img src="https://www.freecodecamp.org/news/content/images/size/w1600/2020/11/jamstack-handbook-banner.jpg" alt="Jamstack Handbook" width="600" height="400" loading="lazy">
    </a>
  </p>
</div>

<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">🐦 Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">📺 Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">📫 Sign Up For My Newsletter</a>
    </li>
    <li>
      <a href="https://github.com/sponsors/colbyfayock">💝 Sponsor Me</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The React + Apollo Tutorial for 2020 (Real-World Examples) ]]>
                </title>
                <description>
                    <![CDATA[ If you want to build apps with React and GraphQL, Apollo is the library you should use. I've put together a comprehensive cheatsheet that goes through all of the core concepts in the Apollo library, showing you how to use it with React from front to ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/react-apollo-client-2020-tutorial/</link>
                <guid isPermaLink="false">66d037b131fbfb6c3390f209</guid>
                
                    <category>
                        <![CDATA[ 2020 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Apollo GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ apollo client ]]>
                    </category>
                
                    <category>
                        <![CDATA[ cheatsheet ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Tutorial ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Reed ]]>
                </dc:creator>
                <pubDate>Sat, 04 Jul 2020 13:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/07/React---Apollo-2020-Cheatsheet.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you want to build apps with React and GraphQL, Apollo is the library you should use.</p>
<p>I've put together a comprehensive cheatsheet that goes through all of the core concepts in the Apollo library, showing you how to use it with React from front to back.</p>
<h3 id="heading-want-your-own-copy">Want Your Own Copy?</h3>
<p>You can grab the PDF cheatsheet <strong><a target="_blank" href="https://reedbarger.com/resources/react-apollo-2020/">right here</a></strong> (it takes 5 seconds).</p>
<p>Here are some quick wins from grabbing the downloadable version:</p>
<ul>
<li>✓ Quick reference to review however and whenever</li>
<li>✓ Tons of useful code snippets based off of real-world projects</li>
<li>✓ Read this guide offline, wherever you like. On the train, at your desk, standing in line — anywhere.</li>
</ul>
<h3 id="heading-prefer-video-lessons">Prefer Video Lessons?</h3>
<p>A great deal of this cheatsheet is based off of the app built in the React + GraphQL 2020 Crash Course. </p>
<p>If you want some more hands-on video lessons, plus see how to build apps with React, GraphQL and Apollo, you can watch the course <a target="_blank" href="https://bit.ly/2020-react-graphql">right here</a>.</p>
<blockquote>
<p>Note: This cheatsheet does assume familiarity with React and GraphQL. If you need a quick refresher on GraphQL and how to write it, a great resource is the <a target="_blank" href="https://graphql.org/learn/">official GraphQL website</a>.</p>
</blockquote>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<h3 id="heading-getting-started">Getting Started</h3>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-apollo-and-why-do-we-need-it">What is Apollo and why do we need it?</a></li>
<li><a class="post-section-overview" href="#heading-apollo-client-basic-setup">Apollo Client setup</a></li>
<li><a class="post-section-overview" href="#heading-creating-a-new-apollo-client-basic-setup">Creating a new Apollo Client</a></li>
<li><a class="post-section-overview" href="#heading-providing-the-client-to-react-components">Providing the client to React components</a></li>
<li><a class="post-section-overview" href="#heading-using-the-client-directly">Using the client directly</a></li>
<li><a class="post-section-overview" href="#heading-writing-graphql-operations-in-js-files-gql">Writing GraphQL in .js files with gql</a></li>
</ul>
<h3 id="heading-core-apollo-react-hooks">Core Apollo React Hooks</h3>
<ul>
<li><a class="post-section-overview" href="#heading-usequery-hook">useQuery Hook</a></li>
<li><a class="post-section-overview" href="#heading-uselazyquery-hook">useLazyQuery Hook</a></li>
<li><a class="post-section-overview" href="#heading-usemutation-hook">useMutation Hook</a></li>
<li><a class="post-section-overview" href="#heading-usesubscription-hook">useSubscription Hook</a></li>
</ul>
<h3 id="heading-essential-recipes">Essential Recipes</h3>
<ul>
<li><a class="post-section-overview" href="#heading-manually-setting-the-fetch-policy">Manually setting the fetch policy</a></li>
<li><a class="post-section-overview" href="#heading-updating-the-cache-upon-a-mutation">Updating the cache upon a mutation</a></li>
<li><a class="post-section-overview" href="#heading-refetching-queries-with-usequery">Refetching queries with useQuery</a></li>
<li><a class="post-section-overview" href="#heading-refetching-queries-with-usemutation">Refetching queries with useMutation</a></li>
<li><a class="post-section-overview" href="#heading-using-the-client-with-useapolloclient">Accessing the client with useApolloClient</a></li>
</ul>
<h3 id="heading-what-is-apollo-and-why-do-we-need-it">What is Apollo and why do we need it?</h3>
<p>Apollo is a library that brings together two incredibly useful technologies used to build web and mobile apps: React and GraphQL. </p>
<p>React was made for creating great user experiences with JavaScript. GraphQL is a very straightforward and declarative new language to more easily and efficiently fetch and change data, whether it is from a database or even from static files. </p>
<p>Apollo is the glue that binds these two tools together. Plus it makes working with React and GraphQL a lot easier by giving us a lot of custom React hooks and features that enable us to both write GraphQL operations and execute them with JavaScript code. </p>
<p>We'll cover these features in-depth throughout the course of this guide.</p>
<h3 id="heading-apollo-client-basic-setup">Apollo Client basic setup</h3>
<p>If you are starting a project with a React template like Create React App, you will need to install the following as your base dependencies to get up and running with Apollo Client:</p>
<pre><code class="lang-bash">// with npm:
npm i @apollo/react-hooks apollo-boost graphql

// with yarn:
yarn add @apollo/react-hooks apollo-boost graphql
</code></pre>
<p><code>@apollo/react-hooks</code> gives us React hooks that make performing our operations and working with Apollo client better</p>
<p><code>apollo-boost</code> helps us set up the client along with parse our GraphQL operations</p>
<p><code>graphql</code> also takes care of parsing the GraphQL operations (along with gql)</p>
<h3 id="heading-apollo-client-subscriptions-setup">Apollo Client + subscriptions setup</h3>
<p>To use all manner of GraphQL operations (queries, mutations, and subscriptions), we need to install more specific dependencies as compared to just <code>apollo-boost</code>:</p>
<pre><code class="lang-bash">// with npm:
npm i @apollo/react-hooks apollo-client graphql graphql-tag apollo-cache-inmemory apollo-link-ws

// with yarn:
yarn add @apollo/react-hooks apollo-client graphql graphql-tag apollo-cache-inmemory apollo-link-ws
</code></pre>
<p><code>apollo-client</code> gives us the client directly, instead of from <code>apollo-boost</code></p>
<p><code>graphql-tag</code> is integrated into <code>apollo-boost</code>, but not included in <code>apollo-client</code></p>
<p><code>apollo-cache-inmemory</code> is needed to setup our own cache (which <code>apollo-boost</code>, in comparison, does automatically)</p>
<p><code>apollo-link-ws</code> is needed for communicating over websockets, which subscriptions require</p>
<h3 id="heading-creating-a-new-apollo-client-basic-setup">Creating a new Apollo Client (basic setup)</h3>
<p>The most straightforward setup for creating an Apollo client is by instantiating a new client and providing just the <code>uri</code> property, which will be your GraphQL endpoint:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> ApolloClient <span class="hljs-keyword">from</span> <span class="hljs-string">"apollo-boost"</span>;

<span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> ApolloClient({
  <span class="hljs-attr">uri</span>: <span class="hljs-string">"https://your-graphql-endpoint.com/api/graphql"</span>,
});
</code></pre>
<p><code>apollo-boost</code> was developed in order to make doing things like creating an Apollo Client as easy as possible. What it lacks for the time being, however, is support for GraphQL subscriptions over a websocket connection. </p>
<p>By default, it performs the operations over an http connection (as you can see through our provided uri above).</p>
<p>In short, use <code>apollo-boost</code> to create your client if you only need to execute queries and mutations in your app. </p>
<p>It setups an in-memory cache by default, which is helpful for storing our app data locally. We can read from and write to our cache to prevent having to execute our queries after our data is updated. We'll cover how to do that a bit later.</p>
<h3 id="heading-creating-a-new-apollo-client-subscriptions-setup">Creating a new Apollo Client (+ subscriptions setup)</h3>
<p>Subscriptions are useful for more easily displaying the result of data changes (through mutations) in our app. </p>
<p>Generally speaking, we use subscriptions as an improved kind of query. Subscriptions use a websocket connection to 'subscribe' to updates and data, enabling new or updated data to be immediately displayed to our users without having to reexecute queries or update the cache.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> ApolloClient <span class="hljs-keyword">from</span> <span class="hljs-string">"apollo-client"</span>;
<span class="hljs-keyword">import</span> { WebSocketLink } <span class="hljs-keyword">from</span> <span class="hljs-string">"apollo-link-ws"</span>;
<span class="hljs-keyword">import</span> { InMemoryCache } <span class="hljs-keyword">from</span> <span class="hljs-string">"apollo-cache-inmemory"</span>;

<span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> ApolloClient({
  <span class="hljs-attr">link</span>: <span class="hljs-keyword">new</span> WebSocketLink({
    <span class="hljs-attr">uri</span>: <span class="hljs-string">"wss://your-graphql-endpoint.com/v1/graphql"</span>,
    <span class="hljs-attr">options</span>: {
      <span class="hljs-attr">reconnect</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">connectionParams</span>: {
        <span class="hljs-attr">headers</span>: {
          <span class="hljs-attr">Authorization</span>: <span class="hljs-string">"Bearer yourauthtoken"</span>,
        },
      },
    },
  }),
  <span class="hljs-attr">cache</span>: <span class="hljs-keyword">new</span> InMemoryCache(),
});
</code></pre>
<h3 id="heading-providing-the-client-to-react-components">Providing the client to React components</h3>
<p>After creating a new client, passing it to all components is essential in order to be able to use it within our components to perform all of the available GraphQL operations.</p>
<p>The client is provided to the entire component tree using React Context, but instead of creating our own context, we import a special context provider from <code>@apollo/react-hooks</code> called <code>ApolloProvider</code> . We can see how it differs from the regular React Context due to it having a special prop, <code>client</code>, specifically made to accept the created client.</p>
<p>Note that all of this setup should be done in your index.js or App.js file (wherever your Routes declared) so that the Provider can be wrapped around all of your components. </p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { ApolloProvider } <span class="hljs-keyword">from</span> <span class="hljs-string">"@apollo/react-hooks"</span>;

<span class="hljs-keyword">const</span> rootElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"root"</span>);
ReactDOM.render(
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">React.StrictMode</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ApolloProvider</span> <span class="hljs-attr">client</span>=<span class="hljs-string">{client}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">BrowserRouter</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Switch</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">exact</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/"</span> <span class="hljs-attr">component</span>=<span class="hljs-string">{App}</span> /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">exact</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/new"</span> <span class="hljs-attr">component</span>=<span class="hljs-string">{NewPost}</span> /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">exact</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/edit/:id"</span> <span class="hljs-attr">component</span>=<span class="hljs-string">{EditPost}</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Switch</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">BrowserRouter</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">ApolloProvider</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">React.StrictMode</span>&gt;</span></span>,
  rootElement
);
</code></pre>
<h3 id="heading-using-the-client-directly">Using the client directly</h3>
<p>The Apollo client is most important part of the library due to the fact that it is responsible for executing all of the GraphQL operations that we want to perform with React.</p>
<p>We can use the created client directly to perform any operation we like. It has methods corresponding to queries (<code>client.query()</code>), mutations (<code>client.mutate()</code>), and subscriptions (<code>client.subscribe()</code>). </p>
<p>Each method accepts an object and it's own corresponding properties:</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// executing queries</span>
client
  .query({
    <span class="hljs-attr">query</span>: GET_POSTS,
    <span class="hljs-attr">variables</span>: { <span class="hljs-attr">limit</span>: <span class="hljs-number">5</span> },
  })
  .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(response.data))
  .catch(<span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> <span class="hljs-built_in">console</span>.error(err));

<span class="hljs-comment">// executing mutations</span>
client
  .mutate({
    <span class="hljs-attr">mutation</span>: CREATE_POST,
    <span class="hljs-attr">variables</span>: { <span class="hljs-attr">title</span>: <span class="hljs-string">"Hello"</span>, <span class="hljs-attr">body</span>: <span class="hljs-string">"World"</span> },
  })
  .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(response.data))
  .catch(<span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> <span class="hljs-built_in">console</span>.error(err));

<span class="hljs-comment">// executing subscriptions</span>
client
  .subscribe({
    <span class="hljs-attr">subscription</span>: GET_POST,
    <span class="hljs-attr">variables</span>: { <span class="hljs-attr">id</span>: <span class="hljs-string">"8883346c-6dc3-4753-95da-0cc0df750721"</span> },
  })
  .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(response.data))
  .catch(<span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> <span class="hljs-built_in">console</span>.error(err));
</code></pre>
<p>Using the client directly can be a bit tricky, however, since in making a request, it returns a promise. To resolve each promise, we either need <code>.then()</code> and <code>.catch()</code> callbacks as above or to <code>await</code> each promise within a function declared with the <code>async</code> keyword.</p>
<h3 id="heading-writing-graphql-operations-in-js-files-gql">Writing GraphQL operations in .js files (gql)</h3>
<p>Notice above that I didn't specify the contents of the variables <code>GET_POSTS</code>, <code>CREATE_POST</code>, and <code>GET_POST</code>. </p>
<p>They are the operations written in the GraphQL syntax which specify how to perform the query, mutation, and subscription respectively. They are what we would write in any GraphiQL console to get and change data.</p>
<p>The issue here, however, is that we can't write and execute GraphQL instructions in JavaScript (.js) files, like our React code has to live in. </p>
<p>To parse the GraphQL operations, we use a special function called a tagged template literal to allow us to express them as JavaScript strings. This function is named <code>gql</code>.</p>
<pre><code class="lang-jsx">
<span class="hljs-comment">// if using apollo-boost</span>
<span class="hljs-keyword">import</span> { gql } <span class="hljs-keyword">from</span> <span class="hljs-string">"apollo-boost"</span>;
<span class="hljs-comment">// else, you can use a dedicated package graphql-tag</span>
<span class="hljs-keyword">import</span> gql <span class="hljs-keyword">from</span> <span class="hljs-string">"graphql-tag"</span>;

<span class="hljs-comment">// query</span>
<span class="hljs-keyword">const</span> GET_POSTS = gql<span class="hljs-string">`
  query GetPosts($limit: Int) {
    posts(limit: $limit) {
      id
      body
      title
      createdAt
    }
  }
`</span>;

<span class="hljs-comment">// mutation</span>
<span class="hljs-keyword">const</span> CREATE_POST = gql<span class="hljs-string">`
  mutation CreatePost($title: String!, $body: String!) {
    insert_posts(objects: { title: $title, body: $body }) {
      affected_rows
    }
  }
`</span>;

<span class="hljs-comment">// subscription</span>
<span class="hljs-keyword">const</span> GET_POST = gql<span class="hljs-string">`
  subscription GetPost($id: uuid!) {
    posts(where: { id: { _eq: $id } }) {
      id
      body
      title
      createdAt
    }
  }
`</span>;
</code></pre>
<h3 id="heading-usequery-hook">useQuery Hook</h3>
<p>The <code>useQuery</code> hook is arguably the most convenient way of performing a GraphQL query, considering that it doesn't return a promise that needs to be resolved.</p>
<p>It is called at the top of any function component (as all hooks should be) and receives as a first required argument—a query parsed with <code>gql</code>.</p>
<p>It is best used when you have queries that should be executed immediately, when a component is rendered, such as a list of data which the user would want to see immediately when the page loads.</p>
<p><code>useQuery</code> returns an object from which we can easily destructure the values that we need. Upon executing a query, there are three primary values will need to use within every component in which we fetch data. They are <code>loading</code>, <code>error</code>, and <code>data</code>.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> GET_POSTS = gql<span class="hljs-string">`
  query GetPosts($limit: Int) {
    posts(limit: $limit) {
      id
      body
      title
      createdAt
    }
  }
`</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { loading, error, data } = useQuery(GET_POSTS, {
    <span class="hljs-attr">variables</span>: { <span class="hljs-attr">limit</span>: <span class="hljs-number">5</span> },
  });

  <span class="hljs-keyword">if</span> (loading) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Error!<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;

  <span class="hljs-keyword">return</span> data.posts.map(<span class="hljs-function">(<span class="hljs-params">post</span>) =&gt;</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Post</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{post.id}</span> <span class="hljs-attr">post</span>=<span class="hljs-string">{post}</span> /&gt;</span></span>);
}
</code></pre>
<p>Before we can display the data that we're fetching, we need to handle when we're loading (when <code>loading</code> is set to true) and we are attempting to fetch the data.</p>
<p>At that point, we display a div with the text 'Loading' or a loading spinner. We also need to handle the possibility that there is an error in fetching our query, such as if there's a network error or if we made a mistake in writing our query (syntax error).</p>
<p>Once we're done loading and there's no error, we can use our data in our component, usually to display to our users (as we are in the example above).</p>
<p>There are other values which we can destructure from the object that <code>useQuery</code> returns, but you'll need <code>loading</code>, <code>error</code>, and <code>data</code> in virtually every component where you execute <code>useQuery</code>. You can see a full list of all of the data we can get back from useQuery <a target="_blank" href="https://www.apollographql.com/docs/react/api/react-hooks/#result">here</a>.</p>
<h3 id="heading-uselazyquery-hook">useLazyQuery Hook</h3>
<p>The <code>useLazyQuery</code> hook provides another way to perform a query, which is intended to be executed at some time after the component is rendered or in response to a given data change.</p>
<p><code>useLazyQuery</code> is very useful for things that happen at any unknown point of time, such as in response to a user's search operation.</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Search</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [query, setQuery] = React.useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [searchPosts, { data }] = useLazyQuery(SEARCH_POSTS, {
    <span class="hljs-attr">variables</span>: { <span class="hljs-attr">query</span>: <span class="hljs-string">`%<span class="hljs-subst">${query}</span>%`</span> },
  });
  <span class="hljs-keyword">const</span> [results, setResults] = React.useState([]);

  React.useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (!query) <span class="hljs-keyword">return</span>;
    <span class="hljs-comment">// function for executing query doesn't return a promise</span>
    searchPosts();
    <span class="hljs-keyword">if</span> (data) {
      setResults(data.posts);
    }
  }, [query, data, searchPosts]);

  <span class="hljs-keyword">if</span> (called &amp;&amp; loading) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;

  <span class="hljs-keyword">return</span> results.map(<span class="hljs-function">(<span class="hljs-params">result</span>) =&gt;</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">SearchResult</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{result.id}</span> <span class="hljs-attr">result</span>=<span class="hljs-string">{result}</span> /&gt;</span></span>
  ));
}
</code></pre>
<p><code>useLazyQuery</code> differs from <code>useQuery</code>, first of all, in what's returned from the hook. It returns an array which we can destructure, instead of an object.</p>
<p>Since we want to perform this query sometime after the component is mounted, the first element that we can destructure is a function which you can call to perform that query when you choose. This query function is named <code>searchPosts</code> in the example above.</p>
<p>The second destructured value in the array is an object, which we can use object destructuring on and from which we can get all of the same
properties as we did from <code>useQuery</code>, such as <code>loading</code>, <code>error</code>, and <code>data</code>.</p>
<p>We also get an important property named <code>called</code>,
which tells us if we've actually called this function to perform our query.
In that case, if <code>called</code> is true and <code>loading</code> is true, we want to
return "Loading..." instead of our actual data, because are waiting for the data to be returned. This is how <code>useLazyQuery</code> handles fetching data in a synchronous way without any promises.</p>
<p>Note that we again pass any required variables for the query operation as a property, variables, to the second argument. However, if we need, we can pass those variables on an object provided to the query function itself.</p>
<h3 id="heading-usemutation-hook">useMutation Hook</h3>
<p>Now that we know how to execute lazy queries, we know exactly how to work with the <code>useMutation</code> hook. </p>
<p>Like the <code>useLazyQuery</code> hook, it returns an array which we can destructure into its two elements. In the first element, we get back a function, which in this case, we can call it to perform our mutation operation. For next element, we can again destructure an object which returns to us <code>loading</code>, <code>error</code> and <code>data</code>. </p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useMutation } <span class="hljs-keyword">from</span> <span class="hljs-string">"@apollo/react-hooks"</span>;
<span class="hljs-keyword">import</span> { gql } <span class="hljs-keyword">from</span> <span class="hljs-string">"apollo-boost"</span>;

<span class="hljs-keyword">const</span> CREATE_POST = gql<span class="hljs-string">`
  mutation CreatePost($title: String!, $body: String!) {
    insert_posts(objects: { body: $body, title: $title }) {
      affected_rows
    }
  }
`</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">NewPost</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [title, setTitle] = React.useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [body, setBody] = React.useState(<span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [createPost, { loading, error }] = useMutation(CREATE_POST);

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleCreatePost</span>(<span class="hljs-params">event</span>) </span>{
    event.preventDefault();
    <span class="hljs-comment">// the mutate function also doesn't return a promise</span>
    createPost({ <span class="hljs-attr">variables</span>: { title, body } });
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>New Post<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleCreatePost}</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(event)</span> =&gt;</span> setTitle(event.target.value)} /&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(event)</span> =&gt;</span> setBody(event.target.value)} /&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">disabled</span>=<span class="hljs-string">{loading}</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>
          Submit
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        {error &amp;&amp; <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{error.message}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>}
      <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>Unlike with queries, however, we don't use <code>loading</code> or <code>error</code> in order to conditionally render something. We generally use <code>loading</code> in such situations as when we're submitting a form to prevent it being submitted multiple times, to avoid executing the same mutation needlessly (as you can see in the example above). </p>
<p>We use <code>error</code> to display what goes wrong with our mutation to our users. If for example, some required values to our mutation are not provided, we can easily use that error data to conditionally render an error message within the page so the user can hopefully fix what's going wrong.</p>
<p>As compared to passing variables to the second argument of <code>useMutation</code>, we can access a couple of useful callbacks when certain things take place, such as when the mutation is completed and when there is an error. These callbacks are named <code>onCompleted</code> and <code>onError</code>. </p>
<p>The <code>onCompleted</code> callback gives us access to the returned mutation data and it's very helpful to do something when the mutation is done, such as going to a different page. The <code>onError</code> callback gives us the returned error when there is a problem with the mutation and gives us other patterns for handling our errors.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> [createPost, { loading, error }] = useMutation(CREATE_POST, {
  <span class="hljs-attr">onCompleted</span>: <span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Data from mutation"</span>, data),
  <span class="hljs-attr">onError</span>: <span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error creating a post"</span>, error),
});
</code></pre>
<h3 id="heading-usesubscription-hook">useSubscription Hook</h3>
<p>The useSubscription hook works just like the useQuery hook. </p>
<p>useSubscription returns an object that we can destructure, that includes the same properties, loading, data, and error. </p>
<p>It executes our subscription immediately when the component is rendered. This means we  need to handle loading and error states, and only afterwards display/use our data.  </p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { useSubscription } <span class="hljs-keyword">from</span> <span class="hljs-string">"@apollo/react-hooks"</span>;
<span class="hljs-keyword">import</span> gql <span class="hljs-keyword">from</span> <span class="hljs-string">"graphql-tag"</span>;

<span class="hljs-keyword">const</span> GET_POST = gql<span class="hljs-string">`
  subscription GetPost($id: uuid!) {
    posts(where: { id: { _eq: $id } }) {
      id
      body
      title
      createdAt
    }
  }
`</span>;

<span class="hljs-comment">// where id comes from route params -&gt; /post/:id</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PostPage</span>(<span class="hljs-params">{ id }</span>) </span>{
  <span class="hljs-keyword">const</span> { loading, error, data } = useSubscription(GET_POST, {
    <span class="hljs-attr">variables</span>: { id },
    <span class="hljs-comment">// shouldResubscribe: true (default: false)</span>
    <span class="hljs-comment">// onSubscriptionData: data =&gt; console.log('new data', data)</span>
    <span class="hljs-comment">// fetchPolicy: 'network-only' (default: 'cache-first')</span>
  });

  <span class="hljs-keyword">if</span> (loading) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Error!<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;

  <span class="hljs-keyword">const</span> post = data.posts[<span class="hljs-number">0</span>];

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>{post.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{post.body}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>Just like useQuery, useLazyQuery and useMutation, useSubscription accepts <code>variables</code> as a property provided on the second argument. </p>
<p>It also accepts, however, some useful properties such as <code>shouldResubscribe</code>. This is a boolean value, which will allow our subscription to automatically resubscribe, when our props change. This is useful for when we're passing variables to our you subscription hub props that we know will change. </p>
<p>Additionally, we have a callback function called <code>onSubscriptionData</code>, which enables us to call a function whenever the subscription hook receives new data. Finally, we can set the <code>fetchPolicy</code>, which defaults to 'cache-first'.</p>
<h3 id="heading-manually-setting-the-fetch-policy">Manually Setting the Fetch Policy</h3>
<p>What can be very useful about Apollo is that it comes with its own cache, which it uses to manage the data that we query from our GraphQL endpoint. </p>
<p>Sometimes, however, we find that due to this cache, things aren't updated in the UI in the way that we want. </p>
<p>In many cases we don't, as in the example below, where we are editing a post on the edit page, and then after editing our post, we navigate to the home page to see it in a list of all posts, but we see the old data instead:</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// route: /edit/:postId</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">EditPost</span>(<span class="hljs-params">{ id }</span>) </span>{
  <span class="hljs-keyword">const</span> { loading, data } = useQuery(GET_POST, { <span class="hljs-attr">variables</span>: { id } });
  <span class="hljs-keyword">const</span> [title, setTitle] = React.useState(loading ? data?.posts[<span class="hljs-number">0</span>].title : <span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [body, setBody] = React.useState(loading ? data?.posts[<span class="hljs-number">0</span>].body : <span class="hljs-string">""</span>);
  <span class="hljs-keyword">const</span> [updatePost] = useMutation(UPDATE_POST, {
    <span class="hljs-comment">// after updating the post, we go to the home page</span>
    <span class="hljs-attr">onCompleted</span>: <span class="hljs-function">() =&gt;</span> history.push(<span class="hljs-string">"/"</span>),
  });

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleUpdatePost</span>(<span class="hljs-params">event</span>) </span>{
    event.preventDefault();
    updatePost({ <span class="hljs-attr">variables</span>: { title, body, id } });
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleUpdatePost}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(event)</span> =&gt;</span> setTitle(event.target.value)}
        defaultValue={title}
      /&gt;
      <span class="hljs-tag">&lt;<span class="hljs-name">input</span>
        <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(event)</span> =&gt;</span> setBody(event.target.value)}
        defaultValue={body}
      /&gt;
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span></span>
  );
}

<span class="hljs-comment">// route: / (homepage)</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { loading, error, data } = useQuery(GET_POSTS, {
    <span class="hljs-attr">variables</span>: { <span class="hljs-attr">limit</span>: <span class="hljs-number">5</span> },
  });

  <span class="hljs-keyword">if</span> (loading) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Error!<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;

  <span class="hljs-comment">// updated post not displayed, still see old data</span>
  <span class="hljs-keyword">return</span> data.posts.map(<span class="hljs-function">(<span class="hljs-params">post</span>) =&gt;</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Post</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{post.id}</span> <span class="hljs-attr">post</span>=<span class="hljs-string">{post}</span> /&gt;</span></span>);
}
</code></pre>
<p>This not only due to the Apollo cache, but also the instructions for what data the query should fetch. We can changed how the query is fetched by using the <code>fetchPolicy</code> property. </p>
<p>By default, the <code>fetchPolicy</code> is set to 'cache-first'. It's going to try to look at the cache to get our data instead of getting it from the network. </p>
<p>An easy way to fix this problem of not seeing new data is to change the fetch policy. However, this approach is not ideal from a performance standpoint, because it requires making an additional request (using the cache directly does not, because it is local data). </p>
<p> There are many different options for the fetch policy listed below:</p>
<pre><code class="lang-jsx">{
  <span class="hljs-attr">fetchPolicy</span>: <span class="hljs-string">"cache-first"</span>; <span class="hljs-comment">// default</span>
  <span class="hljs-comment">/* 
    cache-and-network
    cache-first
    cache-only
    network-only
    no-cache
    standby
  */</span>
}
</code></pre>
<p>I won't go into what each policy does exactly, but to solve our immediate problem, if you always want a query to get the latest data by requesting it from the network, we set <code>fetchPolicy</code> to 'network-first'.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> { loading, error, data } = useQuery(GET_POSTS, {
  <span class="hljs-attr">variables</span>: { <span class="hljs-attr">limit</span>: <span class="hljs-number">5</span> },
  <span class="hljs-attr">fetchPolicy</span>: <span class="hljs-string">"network-first"</span>
});
</code></pre>
<h3 id="heading-updating-the-cache-upon-a-mutation">Updating the cache upon a mutation</h3>
<p>Instead of bypassing the cache by changing the fetch policy of <code>useQuery</code>, let's attempt to fix this problem by manually updating the cache. </p>
<p>When performing a mutation with <code>useMutation</code>. We have access to another callback, known as <code>update</code>. </p>
<p><code>update</code> gives us direct access to the cache as well as the data that is returned from a successful mutation. This enables us to read a given query from the cache, take that new data and write the new data to the query, which will then update what the user sees. </p>
<p>Working with the cache manually is a tricky process that a lot of people tend to avoid, but it's very helpful because it saves some time and resources by not having to perform the same request multiple times to update the cache manually. </p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">EditPost</span>(<span class="hljs-params">{ id }</span>) </span>{
  <span class="hljs-keyword">const</span> [updatePost] = useMutation(UPDATE_POST, {
    <span class="hljs-attr">update</span>: <span class="hljs-function">(<span class="hljs-params">cache, data</span>) =&gt;</span> {
      <span class="hljs-keyword">const</span> { posts } = cache.readQuery(GET_POSTS);
      <span class="hljs-keyword">const</span> newPost = data.update_posts.returning;
      <span class="hljs-keyword">const</span> updatedPosts = posts.map(<span class="hljs-function">(<span class="hljs-params">post</span>) =&gt;</span>
        post.id === id ? newPost : post
      );
      cache.writeQuery({ <span class="hljs-attr">query</span>: GET_POSTS, <span class="hljs-attr">data</span>: { <span class="hljs-attr">posts</span>: updatedPosts } });
    },
    <span class="hljs-attr">onCompleted</span>: <span class="hljs-function">() =&gt;</span> history.push(<span class="hljs-string">"/"</span>),
  });

  <span class="hljs-comment">// ...</span>
}
</code></pre>
<p>We first want to read the query and get the previous data from it. Then we need to take the new data. In this case, to find the post with a given id and replace it with <code>newPost</code> data, otherwise have it be the previous data, and then write that data back to the same query, making sure that it has the same data structure as before. </p>
<p>After all this, whenever we edit a post and are navigated back to the home page, we should see that new post data.</p>
<h3 id="heading-refetching-queries-with-usequery">Refetching queries with useQuery</h3>
<p>Let's say we display a list of posts using a <code>GET_POSTS</code> query and are deleting one of them with a <code>DELETE_POST</code> mutation.</p>
<p>When a user deletes a post, what do we want to happen?</p>
<p>Naturally, we want it to be removed from the list, both the data and what is displayed to the users. When a mutation is performed, however, the query doesn't know that the data is changed. </p>
<p>There are a few ways of updating what we see, but one approach is to reexecute the query. </p>
<p>We can do so by grabbing the <code>refetch</code> function which we can destructure from the object returned by the <code>useQuery</code> hook and pass it down to the mutation to be executed when it is completed, using the <code>onCompleted</code> callback function:</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Posts</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { loading, data, refetch } = useQuery(GET_POSTS);

  <span class="hljs-keyword">if</span> (loading) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;

  <span class="hljs-keyword">return</span> data.posts.map(<span class="hljs-function">(<span class="hljs-params">post</span>) =&gt;</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Post</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{post.id}</span> <span class="hljs-attr">post</span>=<span class="hljs-string">{post}</span> <span class="hljs-attr">refetch</span>=<span class="hljs-string">{refetch}</span> /&gt;</span></span>
  ));
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Post</span>(<span class="hljs-params">{ post, refetch }</span>) </span>{
  <span class="hljs-keyword">const</span> [deletePost] = useMutation(DELETE_POST, {
    <span class="hljs-attr">onCompleted</span>: <span class="hljs-function">() =&gt;</span> refetch(),
  });

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleDeletePost</span>(<span class="hljs-params">id</span>) </span>{
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">window</span>.confirm(<span class="hljs-string">"Are you sure you want to delete this post?"</span>)) {
      deletePost({ <span class="hljs-attr">variables</span>: { id } });
    }
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>{post.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{post.body}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> handleDeletePost(post.id)}&gt;Delete<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<h3 id="heading-refetching-queries-with-usemutation">Refetching Queries with useMutation</h3>
<p>Note that we can also utilize the <code>useMutation</code> hook to reexecute our queries through an argument provided to the mutate function, called <code>refetchQueries</code>. </p>
<p>It accepts an array of queries that we want to refetch after a mutation is performed. Each queries is provided within an object, just like we would provide it to client.query(), and consists of a query property and a variables property. </p>
<p>Here is a minimal example to refetch our <code>GET_POSTS</code> query after a new post is created:</p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">NewPost</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [createPost] = useMutation(CREATE_POST, {
    <span class="hljs-attr">refetchQueries</span>: [
      { 
        <span class="hljs-attr">query</span>: GET_POSTS, 
        <span class="hljs-attr">variables</span>: { <span class="hljs-attr">limit</span>: <span class="hljs-number">5</span> } 
      }
    ],
  });

  <span class="hljs-comment">// ...</span>
}
</code></pre>
<h3 id="heading-using-the-client-with-useapolloclient">Using the client with useApolloClient</h3>
<p>We can get access to the client across our components with the help of a special hook called use Apollo client. This execute the hook at the top of our function component and we get back the client itself. </p>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Logout</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> client = useApolloClient();
  <span class="hljs-comment">// client is the same as what we created with new ApolloClient()</span>

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleLogout</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// handle logging out user, then clear stored data</span>
    logoutUser();
    client.resetStore().then(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"logged out!"</span>));
    <span class="hljs-comment">/* Be aware that .resetStore() is async */</span>
  }

  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{handleLogout}</span>&gt;</span>Logout<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>;
}
</code></pre>
<p>And from there we can execute all the same queries, mutations, and subscriptions.</p>
<p>Note that there are a ton more features that come with methods that come with the client. Using the client, we can also write and read data to and from the cache that Apollo sets up (using <code>client.readData()</code> and <code>client.writeData()</code>). </p>
<p>Working with the Apollo cache deserves its own crash course in itself. A great benefit of working with Apollo is that we can also use it as a state management system to replace solutions like Redux for our global state. If you want to learn more about using Apollo to manage global app state you can <a target="_blank" href="https://www.apollographql.com/docs/react/data/local-state/">check out the following link</a>.</p>
<p>I attempted to make this cheatsheet as comprehensive as possible, though it still leaves out many Apollo features that are worth investigating. </p>
<p>If you want to more about Apollo, be sure to check out the <a target="_blank" href="https://www.apollographql.com/docs/react/">official Apollo documentation</a>.</p>
<h3 id="heading-download-the-cheatsheet">Download the cheatsheet</h3>
<p>Want a quick reference of all of these concepts?</p>
<p><a target="_blank" href="https://reedbarger.com/resources/react-apollo-2020/"><img src="https://dev-to-uploads.s3.amazonaws.com/i/7herw99hu78t8gspo88d.png" alt="React and Apollo 2020 Cheatsheet" width="762" height="500" loading="lazy"></a><em>Click to grab the complete PDF cheatsheet</em></p>
<h2 id="heading-become-a-professional-react-developer">Become a Professional React Developer</h2>
<p>React is hard. You shouldn't have to figure it out yourself.</p>
<p>I've put everything I know about React into a single course, to help you reach your goals in record time:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><strong>Introducing: The React Bootcamp</strong></a></p>
<p><strong>It’s the one course I wish I had when I started learning React.</strong></p>
<p>Click below to try the React Bootcamp for yourself:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><img src="https://reedbarger.nyc3.digitaloceanspaces.com/reactbootcamp/react-bootcamp-cta-alt.png" alt="Click to join the React Bootcamp" width="600" height="400" loading="lazy"></a>
<em>Click to get started</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The React + GraphQL 2020 Crash Course ]]>
                </title>
                <description>
                    <![CDATA[ Have you heard a lot about using React with GraphQL but don't know how to combine them to build amazing apps? In this crash course, you'll learn how to do just that by building a complete social blogging app.  Within an afternoon, you will gain the c... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-react-graphql-2020-crash-course/</link>
                <guid isPermaLink="false">66d037fa386d35c4e3bb3c26</guid>
                
                    <category>
                        <![CDATA[ 2020 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Apollo GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ apollo client ]]>
                    </category>
                
                    <category>
                        <![CDATA[ beginner ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ react hooks ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Reed ]]>
                </dc:creator>
                <pubDate>Tue, 30 Jun 2020 13:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/06/React---GraphQL-2020-Crash-Course-Cover--Large--1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Have you heard a lot about using React with GraphQL but don't know how to combine them to build amazing apps? In this crash course, you'll learn how to do just that by building a complete social blogging app. </p>
<p>Within an afternoon, you will gain the core skills to build your own React and GraphQL projects.</p>
<h2 id="heading-why-you-should-learn-react-with-graphql">Why you should learn React with GraphQL ?</h2>
<p>React is the go-to library for building amazing app experiences with JavaScript. GraphQL, on the other hand, is a tool that gives us a better, more straightforward means of getting and changing our data.</p>
<p>That data could be from a standard database (as we'll be using in our app) or as React frameworks like Gatsby have made possible, even from static files such as markdown files. Regardless of how it's stored, GraphQL makes working with data in our apps better.</p>
<p>We'll see how to leverage the powers of React and GraphQL by creating a social blogging app from start to finish, where you can create, read, edit and delete posts.</p>
<p><a target="_blank" href="https://bit.ly/2020-react-graphql"><img src="https://dev-to-uploads.s3.amazonaws.com/i/o51wpa2tgx9k85p8rse8.gif" alt="Click to access the course" width="1280" height="720" loading="lazy"></a></p>
<p>You can <a target="_blank" href="https://courses.reedbarger.com/p/2020-react-graphql">click here</a> to access the course.</p>
<h2 id="heading-what-tools-well-be-using">What tools we'll be using ?️</h2>
<p>The crash course is meant for developers who are somewhat familiar with React (including the core React Hooks, such as <code>useState</code> and <code>useEffect</code>), but aren't familiar with GraphQL yet.</p>
<p>Basic React knowledge is assumed, but GraphQL knowledge is not required. We'll cover all the core GraphQL concepts you need along the way.</p>
<p>Throughout the course, we'll utilize the following technologies to create our app:</p>
<ul>
<li><strong>React</strong> (to build our user interface)</li>
<li><strong>GraphQL</strong> (to get and change data in a declarative way)</li>
<li><strong>Apollo Client</strong> (to allow us to use React and GraphQL together)</li>
<li><strong>Hasura</strong> (to create and manage our GraphQL API + database)</li>
</ul>
<p>To top it off, we'll be using the online IDE CodeSandbox. This will allow us to code our entire application within the browser in realtime, without the need to create any files, folders, or install dependencies on our own.</p>
<h2 id="heading-creating-a-graphql-api-from-scratch">Creating a GraphQL API from scratch</h2>
<p>To get started working with GraphQL, we'll see how to make an entire GraphQL API from scratch that will communicate with our database. </p>
<p>Fortunately, using the (free) service <strong>Hasura</strong>, this process is very simple and straightforward. Within seconds, we'll see how to create and deploy a complete GraphQL API to the web, which is connected to a Postgres database that will take care of storing our app data.</p>
<p><a target="_blank" href="https://learn.codeartistry.io/courses/2020-react-graphql/lectures/19445637"><img src="https://dev-to-uploads.s3.amazonaws.com/i/ss4wp2tt4ernoe5ukea8.png" alt="Click to access the course" width="1104" height="731" loading="lazy"></a><em>Click to watch this lecture</em></p>
<h2 id="heading-getting-familiar-with-graphql">Getting familiar with GraphQL</h2>
<p>In the second lecture, we'll cover how to write in the GraphQL language using our API's built-in console called <strong>GraphiQL</strong>. </p>
<p>First, we will create a table in our database for all of our posts data. After which, Hasura will automatically create the <strong>queries</strong> and <strong>mutations</strong> we need, which are the names of GraphQL operations that allow us to get and change data in our database. </p>
<p>Throughout this lesson, we'll get very familiar performing queries and mutations in GraphiQL, which will enable us to get entire sets of posts and individual posts, as well as to create, update, and delete our individual post data. </p>
<p><a target="_blank" href="https://learn.codeartistry.io/courses/2020-react-graphql/lectures/19445640"><img src="https://dev-to-uploads.s3.amazonaws.com/i/bo5twcv0hhal7xtj1ksw.png" alt="Click to access the course" width="1280" height="800" loading="lazy"></a><em>Click to watch this lecture</em></p>
<h2 id="heading-connecting-react-with-our-graphql-api-using-apollo-client">Connecting React with our GraphQL API using Apollo Client</h2>
<p>Now that we're comfortable with using GraphQL and understand its core features, we'll see how to connect it with our React client. </p>
<p>The way that we connect our React app with the GraphQL API we created is through a library called <strong>Apollo</strong>. We'll see how to set up the Apollo client, by providing the GraphQL endpoint, which points to our API, like so:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> ApolloClient <span class="hljs-keyword">from</span> <span class="hljs-string">"apollo-boost"</span>;

<span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> ApolloClient({
  <span class="hljs-attr">uri</span>: <span class="hljs-string">"https://react-graphql.herokuapp.com/v1/graphql"</span>
});
</code></pre>
<p>With our newly created client, we have the ability to execute any GraphQL operation through React. To do this, however, we need to pass our client to our entire to all of our React components. We do that with the help of the Apollo provider, as you see below:</p>
<p><a target="_blank" href="https://learn.codeartistry.io/courses/2020-react-graphql/lectures/19445642"><img src="https://dev-to-uploads.s3.amazonaws.com/i/iplsbo37x2oujohn7ulc.png" alt="Click to access the course" width="1280" height="800" loading="lazy"></a><em>Click to watch this lecture</em></p>
<h3 id="heading-getting-posts-with-usequery">Getting posts with useQuery</h3>
<p>After setting up our client, we'll see how to execute different GraphQL operations with them, using some special React hooks that come with the package <code>@apollo/react-hooks</code>.</p>
<p>The hook that allows us to query for data with GraphQL is called <code>useQuery</code>. With it, we'll first see how to get and display all of our post data in our homepage.</p>
<p>Additionally, we'll learn how to write our GraphQL queries directly in our JavaScript files with the help of a special function called <code>gql</code>.</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { useQuery } <span class="hljs-keyword">from</span> <span class="hljs-string">"@apollo/react-hooks"</span>;
<span class="hljs-keyword">import</span> { gql } <span class="hljs-keyword">from</span> <span class="hljs-string">"apollo-boost"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> GET_POSTS = gql<span class="hljs-string">`
  query getPosts {
    posts {
      id
      title
      body
      createdAt
    }
  }
`</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { data, loading } = useQuery(GET_POSTS);

  <span class="hljs-keyword">if</span> (loading) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>;
  <span class="hljs-keyword">if</span> (data.posts.length === <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Empty</span> /&gt;</span></span>;

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{classes.header}</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{classes.h2}</span>&gt;</span>All Posts<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/new"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{classes.newPost}</span>&gt;</span>
          New Post
        <span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
      {data.posts.map(post =&gt; (
        <span class="hljs-tag">&lt;<span class="hljs-name">Post</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{post.id}</span> <span class="hljs-attr">post</span>=<span class="hljs-string">{post}</span> /&gt;</span>
      ))}
    <span class="hljs-tag">&lt;/&gt;</span></span>
  );
}
</code></pre>
<h2 id="heading-creating-and-editing-new-posts-with-usemutation">Creating and editing new posts with useMutation</h2>
<p>After that, we'll see how to create new posts with the <code>useMutation</code> hook. In order to do this, we'll take a look at how to work with GraphQL variables to pass our mutation dynamic values that will change with each execution. </p>
<p>Following that we'll take a look at how to edit our posts. To do so, we'll need to fetch an individual post and display it within our form, so that our user can make changes to the data. Then we'll need to execute a mutation that will perform the update, based on the posts id. </p>
<p><a target="_blank" href="https://learn.codeartistry.io/courses/2020-react-graphql/lectures/19445643"><img src="https://dev-to-uploads.s3.amazonaws.com/i/n9swv8j0qr962spqxhkx.png" alt="Click to access the course" width="1280" height="800" loading="lazy"></a><em>Click to watch this lecture</em></p>
<h2 id="heading-handle-loading-and-errors">Handle loading and errors</h2>
<p>In the following lecture, we'll cover some essential patterns for handling the process of loading our data. </p>
<p>It's important to do so when we execute a mutation, to make sure we don't submit our forms multiple times as our mutation is being executed. We'll also take a look at how to handle errors in the event that our mutation is not executed correctly. </p>
<p><a target="_blank" href="https://learn.codeartistry.io/courses/2020-react-graphql/lectures/19445638"><img src="https://dev-to-uploads.s3.amazonaws.com/i/548ekws3psm3cbfpqy8e.png" alt="Click to access the course" width="1280" height="800" loading="lazy"></a><em>Click to watch this lecture</em></p>
<h2 id="heading-deleting-posts">Deleting posts</h2>
<p>Finally, we'll cover how to delete posts from our app. First, we'll confirm that the user wants to actually delete the post that they've made, then perform the mutation. </p>
<p>Additionally, we'll take a look at how to update our UI in response to mutations with  the helpful <code>refetch</code> function that Apollo gives us. It will enable us to re-execute a query on demand. In this case, we'll do it after the delete mutation has been successfully performed.</p>
<p><a target="_blank" href="https://learn.codeartistry.io/courses/2020-react-graphql/lectures/19445639"><img src="https://dev-to-uploads.s3.amazonaws.com/i/ojjd4jjxuh0h7p1048ck.png" alt="Click to access the course" width="1280" height="800" loading="lazy"></a><em>Click to watch this lecture</em></p>
<h2 id="heading-become-a-professional-react-developer">Become a Professional React Developer</h2>
<p>React is hard. You shouldn't have to figure it out yourself.</p>
<p>I've put everything I know about React into a single course, to help you reach your goals in record time:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><strong>Introducing: The React Bootcamp</strong></a></p>
<p><strong>It’s the one course I wish I had when I started learning React.</strong></p>
<p>Click below to try the React Bootcamp for yourself:</p>
<p><a target="_blank" href="https://www.thereactbootcamp.com"><img src="https://reedbarger.nyc3.digitaloceanspaces.com/reactbootcamp/react-bootcamp-cta-alt.png" alt="Click to join the React Bootcamp" width="600" height="400" loading="lazy"></a>
<em>Click to get started</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Apollo GraphQL: How to Build a Full-stack App with React and Node Js ]]>
                </title>
                <description>
                    <![CDATA[ By Ibrahima Ndaw Apollo Client is a complete state management library for JavaScript apps. It's a powerful tool since it can be used on both the back end and front end side. In this tutorial, we will use it on the front end and back end by building a... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/apollo-graphql-how-to-build-a-full-stack-app-with-react-and-node-js/</link>
                <guid isPermaLink="false">66d8501cf6f7ca5a60462509</guid>
                
                    <category>
                        <![CDATA[ Apollo GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ node ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 29 Apr 2020 17:03:39 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/04/cover-3.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ibrahima Ndaw</p>
<p>Apollo Client is a complete state management library for JavaScript apps. It's a powerful tool since it can be used on both the back end and front end side.</p>
<p>In this tutorial, we will use it on the front end and back end by building an Apollo GraphQL Server with Node JS. Then we will consume the data on the client-side using React JS.</p>
<p>If you're new to GraphQl, <a target="_blank" href="https://www.ibrahima-ndaw.com/blog/graphql-api-express-mongodb/">this tutorial</a> might help you. Otherwise, let's get started.</p>
<ul>
<li><a class="post-section-overview" href="#heading-building-the-server-with-apollo-node-and-graphql">Building the server with Apollo, Node, and GraphQl</a></li>
<li><a class="post-section-overview" href="#heading-graphql-schema">GraphQl Schema</a></li>
<li><a class="post-section-overview" href="#heading-graphql-resolvers">GraphQl resolvers</a></li>
<li><a class="post-section-overview" href="#heading-creating-the-apollo-server">Creating the Apollo Server</a></li>
<li><a class="post-section-overview" href="#heading-building-the-client-side-with-react">Building the Client-side with React</a></li>
<li><a class="post-section-overview" href="#heading-connecting-react-to-apollo">Connecting React to Apollo</a></li>
<li><a class="post-section-overview" href="#heading-fetching-the-data">Fetching the data</a></li>
<li><a class="post-section-overview" href="#heading-showing-the-data">Showing the data</a></li>
</ul>
<h2 id="heading-building-the-server-with-apollo-node-and-graphql">Building the server with Apollo, Node, and GraphQl</h2>
<p>In this guide, I will use the Github API to have data to show, and that operation will be done by the GraphQl server built with Apollo and Node JS.</p>
<p>To make this happen, we need to run the following command on the terminal to set up a new Node JS project:</p>
<pre><code class="lang-shell">  yarn init
</code></pre>
<p>Once the set up is done, we can now install the necessary packages by running this command:</p>
<pre><code class="lang-shell">  yarn add apollo-server graphql axios
</code></pre>
<p>Great, we now have all we need to build a server. So first let's create a new file <code>app.js</code> in the root which will be the entry point of our server.</p>
<p>Next, we need to define a Graphql schema that mirrors the way our data should look.</p>
<h3 id="heading-graphql-schema">GraphQl Schema</h3>
<p>A schema describes the shape of your data graph. It defines a set of types with fields that are populated from your back-end data stores. So, let's add a new schema in the <code>app.js</code> file.</p>
<ul>
<li><code>app.js</code></li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { ApolloServer, gql } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"apollo-server"</span>)
<span class="hljs-keyword">const</span> axios = <span class="hljs-built_in">require</span>(<span class="hljs-string">"axios"</span>)

<span class="hljs-keyword">const</span> typeDefs = gql<span class="hljs-string">`
  type User {
    id: ID
    login: String
    avatar_url: String
  }

  type Query {
    users: [User]
  }
`</span>
</code></pre>
<p>As you can see we don't use all data provided by the Github API. We just need the id that will be used as a reference key on the React App, the login, and the avatar_url. We also have a query <code>users</code> that returns an array of users.</p>
<p>Now that we have a GraphQL schema, it's time to build the corresponding resolvers to complete the query operation.</p>
<h3 id="heading-graphql-resolvers">GraphQl resolvers</h3>
<p>A resolver is a collection of functions that helps generate a response from a GraphQL query. So, let's add a new resolver in the <code>app.js</code> file.</p>
<ul>
<li><code>app.js</code></li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> resolvers = {
  <span class="hljs-attr">Query</span>: {
    <span class="hljs-attr">users</span>: <span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">const</span> users = <span class="hljs-keyword">await</span> axios.get(<span class="hljs-string">"https://api.github.com/users"</span>)
        <span class="hljs-keyword">return</span> users.data.map(<span class="hljs-function">(<span class="hljs-params">{ id, login, avatar_url }</span>) =&gt;</span> ({
          id,
          login,
          avatar_url,
        }))
      } <span class="hljs-keyword">catch</span> (error) {
        <span class="hljs-keyword">throw</span> error
      }
    },
  },
}
</code></pre>
<p>A resolver has to match the appropriate schema by name. Therefore, here <code>users</code> refers to the <code>users</code> query defined in our schema. It's a function that fetches the data from the API with the help of <code>axios</code> and returns as expected the id, the login, and the avatar_url.</p>
<p>And that operation can take time to complete. That's why async/await is used here to handle it.</p>
<p>With that, we can now create the Apollo Server in the next section.</p>
<h3 id="heading-creating-the-apollo-server">Creating the Apollo Server</h3>
<p>If you remember, in the <code>app.js</code> file, we had imported <code>ApolloServer</code> from the <code>apollo-server</code> package. It's a constructor that receives an object as an argument. And that object must contain the schema and the resolver to be able to create the server.</p>
<p>So, let's tweak <code>app.js</code> a bit with <code>ApolloServer</code>.</p>
<ul>
<li><code>app.js</code></li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> server = <span class="hljs-keyword">new</span> ApolloServer({
  typeDefs,
  resolvers,
})
<span class="hljs-comment">//  typeDefs: typeDefs,</span>
<span class="hljs-comment">//  resolvers: resolvers</span>
server.listen().then(<span class="hljs-function">(<span class="hljs-params">{ url }</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Server ready at <span class="hljs-subst">${url}</span>`</span>))
</code></pre>
<p>Here, we pass as a parameter an object that holds the schema and the resolver to <code>ApolloServer</code> to create the server and then listens to it. With that in place, we now have a functional server to work with.</p>
<p>You can already play with it and send queries with the help of GraphQL playground by running this command:</p>
<pre><code class="lang-shell">  yarn start
</code></pre>
<p>You can now preview it on <code>http://localhost:400</code></p>
<ul>
<li>The complete <code>app.js</code> file</li>
</ul>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> { ApolloServer, gql } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"apollo-server"</span>)
<span class="hljs-keyword">const</span> axios = <span class="hljs-built_in">require</span>(<span class="hljs-string">"axios"</span>)

<span class="hljs-keyword">const</span> typeDefs = gql<span class="hljs-string">`
  type User {
    id: ID
    login: String
    avatar_url: String
  }

  type Query {
    users: [User]
  }
`</span>

<span class="hljs-keyword">const</span> resolvers = {
  <span class="hljs-attr">Query</span>: {
    <span class="hljs-attr">users</span>: <span class="hljs-keyword">async</span> () =&gt; {
      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">const</span> users = <span class="hljs-keyword">await</span> axios.get(<span class="hljs-string">"https://api.github.com/users"</span>)
        <span class="hljs-keyword">return</span> users.data.map(<span class="hljs-function">(<span class="hljs-params">{ id, login, avatar_url }</span>) =&gt;</span> ({
          id,
          login,
          avatar_url,
        }))
      } <span class="hljs-keyword">catch</span> (error) {
        <span class="hljs-keyword">throw</span> error
      }
    },
  },
}

<span class="hljs-keyword">const</span> server = <span class="hljs-keyword">new</span> ApolloServer({
  typeDefs,
  resolvers,
})

server.listen().then(<span class="hljs-function">(<span class="hljs-params">{ url }</span>) =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Server ready at <span class="hljs-subst">${url}</span>`</span>))
</code></pre>
<p>A server alone does not do much. We need to add a start script in the <code>package.json</code> file to, as you guessed, start the server.</p>
<ul>
<li><code>package.json</code></li>
</ul>
<pre><code class="lang-js">  <span class="hljs-comment">// first add nodemon: yarn add nodemon --dev</span>
  <span class="hljs-string">"scripts"</span>: {
    <span class="hljs-string">"start"</span>: <span class="hljs-string">"nodemon src/index.js"</span>
  }
</code></pre>
<p>With that, we have a server to fetch data from the Github API. So now it's time to move to the client-side and consume the data.</p>
<p><em>Let's do it.</em></p>
<p><img src="https://media.giphy.com/media/huJxyJPiPk1jwQWPAN/source.gif" alt="yaay" width="400" height="148" loading="lazy"></p>
<h2 id="heading-building-the-client-side-with-react">Building the Client-side with React</h2>
<p>The first thing we have to do is create a fresh React App by running the following command in the terminal:</p>
<pre><code class="lang-shell">npx create-react-app client-react-apollo
</code></pre>
<p>Next, we need to install the Apollo and GraphQl packages:</p>
<pre><code class="lang-shell">  yarn add apollo-boost @apollo/react-hooks graphql
</code></pre>
<p>Now, we can connect Apollo with our React App by updating the <code>index.js</code> file.</p>
<h3 id="heading-connecting-react-to-apollo">Connecting React to Apollo</h3>
<ul>
<li><code>index.js</code></li>
</ul>
<pre><code class="lang-shell">import React from 'react';
import ReactDOM from 'react-dom';
import ApolloClient from 'apollo-boost'
import { ApolloProvider } from '@apollo/react-hooks';

import App from './App';
import './index.css';
import * as serviceWorker from './serviceWorker';

const client = new ApolloClient({
  uri: 'https://7sgx4.sse.codesandbox.io'
})


ReactDOM.render(
  &lt;React.StrictMode&gt;
    &lt;ApolloProvider client={client}&gt;
      &lt;App /&gt;
    &lt;/ApolloProvider&gt;
  &lt;/React.StrictMode&gt;,
  document.getElementById('root')
);

serviceWorker.unregister();
</code></pre>
<p>As you can see, we start by importing <code>ApolloClient</code> and <code>ApolloProvider</code>. The first helps us inform Apollo about which URL to use when fetching data. And if no <code>uri</code> is passed to <code>ApolloClient</code>, it will take the current domain name plus <code>/graphql</code>.</p>
<p>The second is the Provider which expects to receive the client object to be able to connect Apollo to React.</p>
<p>That said, we can now create a component that shows the data.</p>
<h3 id="heading-fetching-the-data">Fetching the data</h3>
<ul>
<li><code>App.js</code></li>
</ul>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>
<span class="hljs-keyword">import</span> { useQuery } <span class="hljs-keyword">from</span> <span class="hljs-string">"@apollo/react-hooks"</span>
<span class="hljs-keyword">import</span> gql <span class="hljs-keyword">from</span> <span class="hljs-string">"graphql-tag"</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">"./App.css"</span>

<span class="hljs-keyword">const</span> GET_USERS = gql<span class="hljs-string">`
  {
    users {
      id
      login
      avatar_url
    }
  }
`</span>
</code></pre>
<p>Here, we have a simple GraphQL query that fetches the data. That query will be passed later to <code>useQuery</code> to tell Apollo which data to fetch.</p>
<ul>
<li><code>App.js</code></li>
</ul>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> User = <span class="hljs-function">(<span class="hljs-params">{ user: { login, avatar_url } }</span>) =&gt;</span> (
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Card"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"avatar"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Card--avatar"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{avatar_url}</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Card--name"</span>&gt;</span>{login}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">https:</span>//<span class="hljs-attr">github.com</span>/${<span class="hljs-attr">login</span>}`} <span class="hljs-attr">className</span>=<span class="hljs-string">"Card--link"</span>&gt;</span>
      See profile
    <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
)
</code></pre>
<p>This presentational component will be used to display a user. It receives the data from the App component and displays it.</p>
<h3 id="heading-showing-the-data">Showing the data</h3>
<ul>
<li><code>App.js</code></li>
</ul>
<pre><code class="lang-jsx"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { loading, error, data } = useQuery(GET_USERS)

  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Something went wrong!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>
  <span class="hljs-keyword">if</span> (loading) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">main</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Github | Users<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      {data.users.map(user =&gt; (
        <span class="hljs-tag">&lt;<span class="hljs-name">User</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{user.id}</span> <span class="hljs-attr">user</span>=<span class="hljs-string">{user}</span> /&gt;</span>
      ))}
    <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></span>
  )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App
</code></pre>
<p>The <code>useQuery</code> hook provided by Apollo receives the GraphQL query and returns three states: the loading, the error, and the data.</p>
<p>If the data are successfully fetched, we pass it to the User component. Otherwise we throw an error.</p>
<ul>
<li>The complete <code>App.js</code> file</li>
</ul>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>
<span class="hljs-keyword">import</span> { useQuery } <span class="hljs-keyword">from</span> <span class="hljs-string">"@apollo/react-hooks"</span>
<span class="hljs-keyword">import</span> gql <span class="hljs-keyword">from</span> <span class="hljs-string">"graphql-tag"</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">"./App.css"</span>

<span class="hljs-keyword">const</span> GET_USERS = gql<span class="hljs-string">`
  {
    users {
      id
      login
      avatar_url
    }
  }
`</span>

<span class="hljs-keyword">const</span> User = <span class="hljs-function">(<span class="hljs-params">{ user: { login, avatar_url } }</span>) =&gt;</span> (
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Card"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"avatar"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Card--avatar"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{avatar_url}</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"Card--name"</span>&gt;</span>{login}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">https:</span>//<span class="hljs-attr">github.com</span>/${<span class="hljs-attr">login</span>}`} <span class="hljs-attr">className</span>=<span class="hljs-string">"Card--link"</span>&gt;</span>
      See profile
    <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
)

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> { loading, error, data } = useQuery(GET_USERS)

  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Something went wrong!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>
  <span class="hljs-keyword">if</span> (loading) <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">main</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"App"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Github | Users<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      {data.users.map(user =&gt; (
        <span class="hljs-tag">&lt;<span class="hljs-name">User</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{user.id}</span> <span class="hljs-attr">user</span>=<span class="hljs-string">{user}</span> /&gt;</span>
      ))}
    <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span></span>
  )
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App
</code></pre>
<p>Great! With that, we are now done building a full-stack Apollo GraphQL app using React and Node JS.</p>
<p>Preview the Apollo GraphQL Server <a target="_blank" href="https://codesandbox.io/s/node-apollo-graphql-7sgx4?file=/package.json:139-193">here</a></p>
<p>Preview the React App <a target="_blank" href="https://codesandbox.io/s/react-apollo-graphql-1qu75">here</a></p>
<p>Find the source code <a target="_blank" href="https://github.com/ibrahima92/apollo-graphql-full-stack">here</a></p>
<p>You can find other great content like this on <a target="_blank" href="https://www.ibrahima-ndaw.com/blog/apollo-graphql-fullstack-app-with-react-and-nodejs/">my blog</a></p>
<p>Thanks for reading!</p>
<p><img src="https://media.giphy.com/media/OcZp0maz6ALok/source.gif" alt="congrats" width="160" height="160" loading="lazy"></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ ⚡ How to Add a GraphQL Server to a RESTful Express.js API in 2 Minutes ]]>
                </title>
                <description>
                    <![CDATA[ By Khalil Stemmler You can get a lot done in 2 minutes, like microwaving popcorn, sending a text message, eating a cupcake, and hooking up a GraphQL server. Yup. If you have an old Express.js RESTful API lying around or you're interested in increment... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/add-a-graphql-server-to-a-restful-express-js-api-in-2-minutes/</link>
                <guid isPermaLink="false">66d45f64a326133d124409f3</guid>
                
                    <category>
                        <![CDATA[ Apollo GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express JS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GraphQL ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 22 Jan 2020 21:34:31 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/01/ghgojj3wde2074i3n9bu.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Khalil Stemmler</p>
<p>You can get a lot done in 2 minutes, like microwaving popcorn, sending a text message, eating a cupcake, and <strong>hooking up a GraphQL server</strong>.</p>
<p>Yup. If you have an old Express.js RESTful API lying around or you're interested in incrementally adopting GraphQL, we only need 2 minutes to hook it up with a fresh new GraphQL Server.</p>
<p>Ready? Set. Go!</p>
<p>Let's say that your server looked something like the following.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>;
<span class="hljs-keyword">import</span> { apiRouter } <span class="hljs-keyword">from</span> <span class="hljs-string">'./router'</span>;

<span class="hljs-keyword">const</span> app = express();
<span class="hljs-keyword">const</span> port = process.env.PORT || <span class="hljs-number">5000</span>;

<span class="hljs-comment">// Existing routes for our Express.js app</span>
app.use(<span class="hljs-string">'/api/v1'</span>, apiRouter);

app.listen(port, <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`[App]: Listening on port <span class="hljs-subst">${port}</span>`</span>))
</code></pre>
<p>At the root of your project, <code>npm install</code> <a target="_blank" href="https://github.com/apollographql/apollo-server/tree/master/packages/apollo-server-express">apollo-server-express</a> as a dependency.</p>
<pre><code>npm install apollo-server-express --save
</code></pre><p>Go to where your Express app is defined and import <code>ApolloServer</code> and <code>gql</code> from <code>apollo-server-express</code>.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { ApolloServer, gql } <span class="hljs-keyword">from</span> <span class="hljs-string">'apollo-server-express'</span>
</code></pre>
<p>Next, create an instance of an <code>ApolloServer</code> with the <em>simplest possible</em> GraphQL <strong>type definitions</strong> and <strong>resolvers</strong>.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> server = <span class="hljs-keyword">new</span> ApolloServer({
  typeDefs: gql<span class="hljs-string">`
    type Query {
      hello: String
    }
  `</span>,
  resolvers: {
    Query: {
      hello: <span class="hljs-function">() =&gt;</span> <span class="hljs-string">'Hello world!'</span>,
    },
  }
})
</code></pre>
<p>Lastly, use <code>ApolloServer</code>'s <a target="_blank" href="https://www.apollographql.com/docs/apollo-server/api/apollo-server/?utm_source=devto&amp;utm_medium=blog_post&amp;utm_campaign=add_graphl_server_express_2_mins#apolloserverapplymiddleware">applyMiddleware</a> method to pass in our Express.js server.</p>
<pre><code class="lang-typescript">server.applyMiddleware({ app })
</code></pre>
<p>Boom. That's it!</p>
<p>Your code should look something like this.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>;
<span class="hljs-keyword">import</span> { v1Router } <span class="hljs-keyword">from</span> <span class="hljs-string">'./api/v1'</span>;
<span class="hljs-keyword">import</span> { ApolloServer, gql } <span class="hljs-keyword">from</span> <span class="hljs-string">'apollo-server-express'</span>

<span class="hljs-keyword">const</span> app = express();
<span class="hljs-keyword">const</span> port = process.env.PORT || <span class="hljs-number">5000</span>;

<span class="hljs-keyword">const</span> server = <span class="hljs-keyword">new</span> ApolloServer({
  typeDefs: gql<span class="hljs-string">`
    type Query {
      hello: String
    }
  `</span>,
  resolvers: {
    Query: {
      hello: <span class="hljs-function">() =&gt;</span> <span class="hljs-string">'Hello world!'</span>,
    },
  }
})

server.applyMiddleware({ app })

app.use(<span class="hljs-string">'/api/v1'</span>, v1Router);

app.listen(port, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`[App]: Listening on port <span class="hljs-subst">${port}</span>`</span>)
})
</code></pre>
<p>If you navigate to <code>localhost:5000/graphql</code>, you should be able to see your GraphQL schema in the GraphQL playground.</p>
<p><img src="https://thepracticaldev.s3.amazonaws.com/i/wd4tiobfydytzdtamlef.png" alt="Alt Text" width="1328" height="982" loading="lazy"></p>
<p>Note: If you want to change the URL that the GraphQL endpoint sits at from <code>/graphql</code> to something else, you can pass in a <code>path</code> option to <code>server.applyMiddleware()</code> with the URL you want, like <code>path: '/specialUrl'</code>. Check out the <a target="_blank" href="https://www.apollographql.com/docs/apollo-server/api/apollo-server/?utm_source=devto&amp;utm_medium=blog_post&amp;utm_campaign=add_graphl_server_express_2_mins#apolloserverapplymiddleware">docs</a> for full API usage.</p>
<p>How simple was that? Is your popcorn finished? ?</p>
<h2 id="heading-summary">Summary</h2>
<p>Here's what we did.</p>
<ol>
<li>Install <code>apollo-server-express</code></li>
<li>Create a <code>new ApolloServer</code></li>
<li>Connect your GraphQL Server with <code>server.applyMiddleware</code></li>
</ol>
<p>I personally really love the fact that Apollo Server is non-intrusive and can be tacked on any project as an alternative way to communicate between services and applications.</p>
<h2 id="heading-where-to-go-from-here">Where to go from here</h2>
<p>If you're new to Apollo and GraphQL, a great way to learn is to actually build something in real life. For that reason, I highly recommend checking out the <a target="_blank" href="https://www.apollographql.com/docs/tutorial/introduction?utm_source=freecodecamp&amp;utm_medium=blog_post&amp;utm_campaign=add_graphl_server_express_2_mins">Apollo Fullstack Tutorial (you can also learn in TypeScript now ?)</a>.</p>
<p>I'm <a target="_blank" href="https://twitter.com/stemmlerjs">Khalil Stemmler</a>, a Developer Advocate at Apollo GraphQL. I teach advanced TypeScript, GraphQL, and Node.js best practices for large-scale applications. Feel free to ping me on <a target="_blank" href="https://twitter.com/stemmlerjs">Twitter</a> if you need help with anything Apollo, TypeScript, or architecture-related. Cheers ?</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ A comparison between Vulcan and AUSK: how to use Node, React and GraphQL to their full potential ]]>
                </title>
                <description>
                    <![CDATA[ By Eric Burel The NRG stack for faster development You've probably never heard of either Vulcan.js or Apollo Universal Starter Kit – at least not yet. But I am pretty sure you've heard about React, Node.js and GraphQL. Okay, that’s what we call an un... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/vulcan-and-ausk-use-node-react-and-graphql-to-their-full-potential-3/</link>
                <guid isPermaLink="false">66d45e45052ad259f07e4aa1</guid>
                
                    <category>
                        <![CDATA[ Vulcan.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Apollo GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 02 Oct 2019 14:58:50 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/10/sayan_ausk_vulcan_banner_1600.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Eric Burel</p>
<h2 id="heading-the-nrg-stack-for-faster-development">The NRG stack for faster development</h2>
<p>You've probably never heard of either Vulcan.js or Apollo Universal Starter Kit – at least not yet.</p>
<p>But I am pretty sure you've heard about React, Node.js and GraphQL. Okay, that’s what we call an understatement: you’ve likely seen millions of tweets, blog articles, meetups and podcasts about those three and their magical powers.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/10/tweet.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sums up 2017-2020 in one tweet</em></p>
<p>There are a lot of good reasons why those technologies are praised by web developers. Yet, if you ever tried to write a modern full-stack JavaScript application from scratch, you may have noticed the amount of boilerplate it can produce.</p>
<p>This is especially annoying with generic features: setting up authentication, setting up the database, setting up the main App component, setting up the settings…</p>
<p>Both Vulcan.js and AUSK aim to make you a fast and efficient full-stack JavaScript developer. Both rely on a modular architecture, with React for the UI, Node for the backend, and Apollo graphQL for the client/server communication layer. Both provide tons of pre-coded modules so you can focus on valuable features.</p>
<p>However, they each take very different approaches to the problem, so I thought you might enjoy a comparison.</p>
<p>First of all let’s introduce the competitors.</p>
<p><em>Disclaimer: I am a contributor of Vulcan.js, however I used both of those technologies for my client’s projects so I’ll stay as objective as can be.</em></p>
<h2 id="heading-apollo-universal-starter-kit">Apollo UNIVERSAL Starter Kit</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/10/ausk_400.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Okay, when they say universal, they mean UNIVERSAL. Have you ever seen a JavaScript boilerplate that includes a Scala server for big work? And a full React Native setup with Expo? They even close the eternal (and annoying) Angular versus React debate by supporting both.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/10/ausk-stack.png" alt="Image" width="600" height="400" loading="lazy">
<em>Technologies included in AUSK: Node, Scala, React, Angular and React Native, all tied by GraphQL. Kind of the Oscar ceremony of modern web development.</em></p>
<p>I don’t have much else to say. I mean, look again at this stack, that’s a web developer’s wildest dream! </p>
<p>I actually have something to add: it also includes Bootstrap and Ant Design as styling frameworks, Knex to connect to SQL database (MongoDB connection is not included but easily doable), and it’s written in TypeScript. All core features of a JS/GraphQL application are provided in the boilerplate (menu, auth, etc.)+ a few higher level modules that serve as examples.</p>
<p>Link: <a target="_blank" href="https://github.com/sysgears/apollo-universal-starter-kit">https://github.com/sysgears/apollo-universal-starter-kit</a></p>
<h2 id="heading-vulcan-beyond-universal-isomorphic">Vulcan: beyond universal, isomorphic</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/10/vulcan.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Remember Meteor and Telescope? I know the JS ecosystem moves fast, but this golden era was like only 2 or 3 years ago.</p>
<p>Meteor was the first framework to fully exploit the combination of server-side and client-side JavaScript, by allowing to write isomorphic code that runs on both environment. Telescope was a Meteor boilerplate app meant to fully enjoy its package-oriented architecture.</p>
<p>Though still used in many professional apps and known by a whole lot of developers, Meteor is crippled by some technical limitations that prevents a wider usage: its webpack-incompatible build system, its package manager that is now surpassed by NPM, or its RAM-consuming real-time data exchange protocol.</p>
<p>And I am yet to discover a framework that makes devs half as productive as Meteor. But don’t worry, there’s now a serious contender. You get it : Vulcan !</p>
<p>The use of Apollo GraphQL and a rational package-oriented architecture allow Vulcan to overcome Meteor's limitations while enjoying the same advantages: fully modular architecture, declarative programming, isomorphism and so on.</p>
<p>Vulcan is meant to be the Rails of the JavaScript ecosystem. Easy to get started with but complete enough to write any app.</p>
<p><a target="_blank" href="http://:%20https://medium.com/dailyjs/write-less-code-ship-more-apps-how-vulcan-js-makes-me-an-efficient-developer-71c829c76417">Check my previous article for a more complete description of Vulcan patterns targeting development speed</a>.</p>
<p>Link: <a target="_blank" href="http://vulcanjs.org/">http://vulcanjs.org/</a></p>
<h2 id="heading-1-framework-vs-boilerplate">#1: Framework VS Boilerplate</h2>
<p>First major difference between these tools: AUSK is a boilerplate, while Vulcan is a framework. Where does the distinction lie, you may wonder?</p>
<h3 id="heading-vulcan-a-framework">Vulcan, a framework</h3>
<p>A framework is meant to make you a more efficient developer on a daily basis by providing a specific set of functions and helpers. It is usually designed to stay separate from your app. You can update your app from time-to-time whenever a new version of the framework is published.</p>
<p>We usually distinguish frameworks and librairies based on the level of specialization. A framework usually allows delivering business-level features, while a library is a more specialized technical tool. But both mostly works the same.</p>
<p>The limitation with frameworks or libs is that you may feel lost when they abandon you. What do you do when the bug is not in your app, but in React or Apollo?</p>
<p>My rule of thumb is that when using a framework, you should be ready to contribute to its development, at least by opening issues whenever you encounter a bug.</p>
<h3 id="heading-ausk-a-boilerplate">AUSK, a boilerplate</h3>
<p>A boilerplate is a well written piece of code with a fully working development environment. That’s all. With a boilerplate it’s harder to keep up with updates because the boilerplate code is not clearly separated from your app. Kind of like Create React App after you eject.</p>
<p>It usually provides only few custom methods. You will feel faster in the first month and you will benefit from a battle-tested architecture, but your cruise speed will end up being mostly the same than without a boilerplate.</p>
<p>A boilerplate is far more freedom than a framework but also less impact on your efficiency.</p>
<h2 id="heading-2-learning-curve">#2 Learning Curve</h2>
<h3 id="heading-vulcan-graphql-made-easy">Vulcan: GraphQL made easy</h3>
<p>Vulcan can be a good way to get a first grasp of GraphQL because… you don’t need to actually write GraphQL. The framework generates the GraphQL schema and resolvers for you based on your data model. Using developer tools like GraphiQL or GraphQL Voyager, you can visualize and play around with the schema to get a grasp of how your features translate into GraphQL.</p>
<p>The second step is to understand the logic of Vulcan itself. A live tutorial is included in the “Vulcan Starter” app to help you in the process.</p>
<h3 id="heading-ausk-for-purists">AUSK: for purists</h3>
<p>AUSK architecture is far closer to what Express developers are used to. Think of your canonical Express app, but with GraphQL installed and a package-based architecture. No surprises.</p>
<p>This also means that you’ll need to grasp the basics of GraphQL to use AUSK, in addition of course to Node, Express and React and whatever database you use (but the same goes for Vulcan). Luckily, it provides a few examples to help you in the process, including creating and listing data and even uploading files.</p>
<h3 id="heading-conclusion-full-stack-devs-have-a-lot-to-master">Conclusion: Full-stack devs have a lot to master</h3>
<p>The JavaScript ecosystem is maturing more and more, which also means it is harder to learn and understand for beginners.</p>
<p>To fully enjoy those technologies, you’ll need at least some knowledge of modern JavaScript and React development.</p>
<p>Don’t expect to be fully productive at day one. That said, there are pleeenty of courses, free or paid, to learn modern full-stack JavaScript development. Studying AUSK and Vulcan can be an incredible source of inspiration.</p>
<h2 id="heading-3-development-speed">#3 Development speed</h2>
<h3 id="heading-vulcan-automate-all-the-things">Vulcan: automate all the things</h3>
<p>When well used, <a target="_blank" href="https://www.freecodecamp.org/news/how-i-built-an-app-with-vulcan-js-in-four-days-6368814077b1/">Vulcan is just incredibly fast at delivering features</a>. This is because it relies on automated generation a lot, so it can produces the most relevant parts of an app in a matter of hours as long as your data model is correctly defined.</p>
<p>This pattern is called declarative programming: you “declare” how your app works and let the framework do the job. It’s difficult to implement but can be extremely powerful.</p>
<h3 id="heading-ausk-more-freedom">AUSK: more freedom</h3>
<p>Since AUSK is boilerplate-focused, it’s a bit tougher to add basic features as it’s a multi-step process:</p>
<ul>
<li>write your GraphQL schema</li>
<li>same for resolvers, mutations</li>
<li>same for your database model (using Knex or Mongoose)</li>
<li>same for your React components</li>
<li>…</li>
</ul>
<p>However, if you need to write a custom feature, it’s gonna be easier with AUSK than with Vulcan. So if you have very few data models but complex features, AUSK will be more efficient than Vulcan.</p>
<p>Hopefully there are ongoing work to make AUSK more declarative, through an innovative Domain Driven Design inspired schema system, <a target="_blank" href="https://github.com/sysgears/domain-schema">domain-schema</a>.</p>
<h3 id="heading-conclusion-select-the-right-tool-for-the-right-use-case">Conclusion: select the right tool for the right use case</h3>
<p>There’s no magical universal technology for full-stack JS development. The development speed with each framework depends a lot on the underlying use case. I tend to prefer Vulcan for data-oriented platforms and professional tools, and AUSK for B2C SaaS platforms that require more custom features.</p>
<h2 id="heading-4-community-support-and-maturity">#4 Community, support and maturity</h2>
<h3 id="heading-vulcan-heir-of-meteor">Vulcan: heir of Meteor</h3>
<p>Vulcan is a framework from Sacha Greif, who is a long time Meteor developer and very invested in the JavaScript community (<a target="_blank" href="https://stateofjs.com/">State of JS</a> and <a target="_blank" href="https://stateofcss.com/">State of CSS</a> among other things).</p>
<p>There is an active Slack where beginners and other enthusiasts can quickly find answers to their questions.</p>
<h3 id="heading-ausk-an-actively-maintained-project">AUSK: an actively maintained project</h3>
<p>AUSK is maintained by <a target="_blank" href="https://sysgears.com/">SysGears</a>, in particular by Victor Vlasenko, the founder of the company.</p>
<p>The project is associated with Gitter. During my latest freelance mission with AUSK, Victor responded very quickly to my issues and questions. He even merged the Storybook support after I gave it a shot.</p>
<h3 id="heading-conclusion-small-but-rich-communities">Conclusion: small but rich communities</h3>
<p>Both technologies are used in production in multiple projects, so they are already safe to use. The communities are growing actively and beginner-friendly.</p>
<p>If you need to build a team, don’t expect to find freelancers that precisely know those technologies, they are too specific. Instead focus on finding full-stack JavaScript developers who will be able to quickly learn them. Alternatively, you can go to the source and find true specialists among the <a target="_blank" href="http://slack.vulcanjs.org/">Vulcan</a> or <a target="_blank" href="https://gitter.im/sysgears/apollo-fullstack-starter-kit">AUSK</a> communities.</p>
<h2 id="heading-5-deployment">#5 Deployment</h2>
<p>Not much to compare, both frameworks allow deployment on platforms offering free services like Zeit Now and Heroku as well as deployment on your own custom server.</p>
<h2 id="heading-6-code-scalability-and-modular-patterns">#6 Code scalability and modular patterns</h2>
<h3 id="heading-vulcan-share-efforts">Vulcan: share efforts</h3>
<p>One advantage of a framework is effort sharing. End usage is clearer, and thus allows us to integrate various optimizations within the framework itself.</p>
<p>Vulcan provides patterns like callbacks/hooks, enhancement and central registration to fully benefit from its package-oriented architecture. For example, we are able to add Material UI to an app, including SSR, without changing a single line of code in the Vulcan Core module.</p>
<p>More precisely, Vulcan provides different <code>register</code> methods for each data structure, like <code>registerComponent</code> , and also callbacks, like <code>router.wrapper</code> that allow to wrap the root <code>App</code> React component. You only need to import your file once at the package entry level ( <code>main</code> files).</p>
<h3 id="heading-ausk-start-on-the-right-track-finish-by-yourself">AUSK: start on the right track, finish by yourself</h3>
<p>The modular architecture limits the temptation of writing spaghetti code. It favors code reuse across applications. Each package possesses an <code>index.ts</code> file that declares relevant middlewares, startup functions, graphQL functions shared with other modules.</p>
<p>The well-named <code>module</code> module provides classes for each environment to register a new module, like <code>ServerModule</code> and <code>ClientModule</code> . That’s the only module that is actually used directly at the app level.</p>
<pre><code>
export default new ServerModule({
    onAppCreate: [ callback1, callback2]
})
</code>
</pre>

<p>Internally all modules will be merged into one big module, that will eventually be used to create the app. For example, all <code>onAppCreate</code> callbacks will be run one after the other.</p>
<p>That’s a relatively clean pattern and a very smart architecture. I mean, even the module manager is a module, isn’t that beautiful?</p>
<p>But the rest is up to you. Nice, you’ll be able to optimize everything! So, are you going to loose couple your GraphQL resolvers and your Mongo database? Using which tools? How do you convert your GraphQL schema into Mongo projections? Are you going to write connectors, use DataLoader?</p>
<p>Here’s the point: writing a scalable app is hard. Very hard. If you want to learn, then good for you. I am very glad to use AUSK for this very reason, doing things by yourself is the best way to learn.</p>
<h3 id="heading-conclusion-are-you-risk-averse">Conclusion: are you risk-averse?</h3>
<p>For both AUSK and Vulcan, code scalability means a modular architecture. Whenever code becomes too complex or unreadable, the solution is easy: cut it into smaller, simpler pieces.</p>
<p>Vulcan architecture is bolder, everything can be modular. This ambition comes at a risk, it may sometimes be difficult to get who registered what and when.</p>
<p>AUSK modular patterns are easier to read, but also a bit less powerful. It may for example be difficult to add complex global features without touching the core package code. Yet they are definitely sufficient for most use cases, you don’t have to be a modularity purist to write good apps.</p>
<h2 id="heading-6-mobile">#6 Mobile</h2>
<h3 id="heading-vulcan-with-cordova">Vulcan: with Cordova</h3>
<p>Meteor, which Vulcan is based on, embeds Cordova. So your web app can be bundled as a mobile application with a single command line.</p>
<p>However Vulcan does not provide tools for native apps. Of course you can still create an independent React Native app and plug it to Vulcan. Improvements on the auth system (currently the last piece of Vulcan really relying on Meteor) are planned in the months to come to facilitate such connections.</p>
<h3 id="heading-ausk-with-react-native">AUSK: with React Native</h3>
<p>Combining both a setup for “vanilla” React and React Native is one of the best features of AUSK. After all, it’s a Universal starter kit! I don’t do much mobile myself but it’s reassuring to be able to quickly create a native mobile app sharing the same server as my web interface.</p>
<h3 id="heading-conclusion-ausk-is-better-at-mobile-first">Conclusion: AUSK is better at mobile-first</h3>
<p>AUSK will be more suited if you specifically need to write a mobile app. Nonetheless Vulcan allows to build a mobile app from your code in just one command-line, which is okay if the mobile version is more secondary to you.</p>
<h2 id="heading-7-change-the-ui-a-tough-issue">#7 Change the UI: a tough issue</h2>
<p>Creating a fullstack framework that allows instantaneous UI library change is a dream only achieved during the era of CSS. Remember those websites that allowed to switch  theme by clicking on a single button?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/10/fire.png" alt="Image" width="600" height="400" loading="lazy">
<em>“What logo can we pick for our nice CSS-in-JS lib?” “I don’t know, kind of a badass warrior woman?” “Yeah it makes total sense” — creators of <a target="_blank" href="https://github.com/emotion-js/emotion">Emotion</a>, probably</em></p>
<p>Then the JS nations attacked. Using React components, it is very difficult to provide such a feature (except for trivial color changes), because style and design is now very tied to the underlying React/Angular/Vue components.</p>
<p>Each React UI lib has its own way to define a button, without even speaking about theming. That’s a problem for full-stack technologies like AUSK and Vulcan, because picking a styling framework is a matter of taste. They can’t just propose a definitive choice and force you to stick to it. Bootstrap is no longer at monopoly and each developer has their own favorite lib.</p>
<p>To tackle this issue, both have a similar approach. They wrote a canonical set of components with Bootstrap, then tried to allow the replacement of those components with another lib like Ant Design or Material UI.</p>
<p>It makes the code weird. For example, AUSK Button will take a <code>color</code> prop, because it is how Bootstrap work. If you switch to Ant Design, you will also need to use the color prop, even if Ant Design uses a <code>type</code> prop instead.</p>
<p>Since UI framework selection usually happens only once, being obligated to use a non-canonical set of props during all the developments seems a very high price for multiple UI framework support.</p>
<p>During development, I’d suggest to avoid using those pre-coded components for custom UI as much as possible. They are cool to build the example and generic features provided by the boilerplate/framework, but not that much when it comes to write the custom parts of your app.</p>
<p>Instead use the underlying components provided by Ant Design or Bootstrap or Material UI depending on your choice, and try to write your own UI lib. You could checkout Storybook to help you in the process, as it is included in both AUSK and Vulcan.</p>
<h2 id="heading-8-free-fight">#8 FREE FIGHT</h2>
<p>If I were to retain differentiating features specific to each of these technologies, they would be these.</p>
<h3 id="heading-vulcan">Vulcan</h3>
<p>The schema system. To my best knowledge,  no framework is able to generate the database structure, the server entry points, the client/server communication layer, and a production-ready frontend (forms, lists etc.) from a single JSON schema.</p>
<p>Vulcan.js can do that while using the latest JS technologies.</p>
<h3 id="heading-ausk">AUSK</h3>
<p>I did not manage to pick only one, so my loved features of AUSK would be TypeScript and React Native.</p>
<p>There has been debates for a few years around the benefits of statically typed JavaScript, whether to prefer Flow or TypeScript… And TypeScript definitely won the fight. Working with TypeScript is possible in Vulcan but, due to the use of Meteor, is currently feels unnatural and compilation is slow. AUSK uses TypeScript as a default and that’s awesome.</p>
<p>And React Native… well, there are also debates whether using React to write mobile apps is relevant. You may choose to stick to a responsive web app, but at least you know everything is setup for you, given that configuring a dev env for React Native is not always an easy task.</p>
<hr>
<h2 id="heading-so-have-you-made-your-choice">So, have you made your choice?</h2>
<p>There are so many points that should be taken into consideration like performance, security, DevOps, auth management… Picking the right tool to build your JavaScript app is certainly not an easy choice. I hope that this article gave you valuable insights to help you in this decision.</p>
<p>If you still feel hesitant, reach me out on Vulcan's Slack, I’d be glad to answer them :)</p>
<p>You can also direct any question on AUSK to Victor Vlasenko and his team at <a target="_blank" href="https://sysgears.com/">SysGears</a>, and join <a target="_blank" href="http://slack.telescopeapp.org/">Vulcan’s dedicated Slack</a> to access the Vulcan community.</p>
<p>My last advice will be that simple: give both Vulcan and AUSK a shot, they are worth your time!</p>
<p><em>Thanks to Sacha Greif and Victor Vlasenko for reviewing this article.</em></p>
<p><a href="https://twitter.com/lbke_fr">
<img src="https://www.freecodecamp.org/news/content/images/2019/10/Medium-follow-2019.png" alt="LBKE banner twitter" width="600" height="400" loading="lazy">
</a></p>
<hr>
<p>I am the co-founder of the French company Lebrun Burel Knowledge Engineering (LBKE) —  <a target="_blank" href="https://www.lbke.fr">https://www.lbke.fr</a></p>
<p><em>Always happy to talk about code, machine learning, innovation and entrepreneurship!</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use GraphQL with Apollo on Your Website ]]>
                </title>
                <description>
                    <![CDATA[ By Ondrej Polesny In my previous article, I explained why it makes sense to decouple the front-end part of a website from its back-end services. I introduced GraphQL, Apollo and other tools that enable such abstraction and make maintenance of product... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-graphql-with-apollo-on-your-website-ecb6046e139/</link>
                <guid isPermaLink="false">66d460993a8352b6c5a2aadf</guid>
                
                    <category>
                        <![CDATA[ Apollo GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 21 Feb 2019 16:00:53 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*DQ22UoX0M8_mdFj3rkc5sQ@2x.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ondrej Polesny</p>
<p>In my <a target="_blank" href="http://bit.ly/2TW60L6">previous article</a>, I explained why it makes sense to decouple the front-end part of a website from its back-end services. I introduced GraphQL, Apollo and other tools that enable such abstraction and make maintenance of production websites a nice experience.</p>
<p>In this article, I will show you a boilerplate that already has all these tools set up and saves you a lot of time when starting the development.</p>
<p><a target="_blank" href="http://bit.ly/2GGHIB5">Check out the live demo of the boilerplate</a></p>
<h1 id="heading-boilerplate-to-speed-up-the-start">Boilerplate to Speed Up the Start</h1>
<p>Let’s start with the tools I used:</p>
<ul>
<li>Node.js — runtime</li>
<li>Express — web application framework</li>
<li>Apollo server — middleware service with GraphQL support</li>
<li>Apollo client — GraphQL client</li>
<li>Kentico Cloud tools — headless CMS</li>
<li>Pug — template engine</li>
</ul>
<h1 id="heading-schema-and-resolvers-code">Schema and Resolvers Code</h1>
<p>The first step in building the site is to create or generate a schema. I already mentioned in the previous article that I am using <a target="_blank" href="http://bit.ly/2QzUALM">Content-as-a-Service platform Kentico Cloud</a> for content storage. The content that is stored there is already structured within defined model structures. Therefore I can quickly generate the schema using the <a target="_blank" href="http://bit.ly/2SqEAju">schema generator</a>:</p>
<p>kc-generate-gql-schema — projectId {projectID} — createModule</p>
<p>But it’s also possible to define all the models manually in the following syntax.</p>
<p>const TYPE_DEFINITION = `  </p>
<p>  type SystemInfo {<br>    id: String!<br>    name: String!<br>    codename: String!<br>    language: String!<br>    type: String!<br>    lastModified: String!<br>  }  </p>
<p>  interface ContentItem {<br>    system: SystemInfo!<br>  }<br>  ...<br>  type FactAboutUsContentType implements ContentItem {<br>    system: SystemInfo!<br>    description: RichTextElement<br>    title: TextElement<br>    image: AssetElement<br>  }<br>  ...`module.exports = {<br>  TYPE_DEFINITION<br>}</p>
<p><em>(See the whole file on</em> <a target="_blank" href="https://github.com/Kentico/cloud-boilerplate-express-apollo/blob/master/graphQL/types.js"><em>GitHub</em></a><em>.)</em></p>
<p>The model generator lists all the system types including links, texts, datetime fields, images and others (<code>SystemInfo</code> above), followed by the data models of each of the custom content models (<code>FactAboutUsContentType</code>). We will need to use the type definition as a module, hence the last argument <code>createModule</code>.</p>
<p>The next step is to create GraphQL queries and resolvers. As the content API is read-only, the queries are quite simple and limited to fetch all items or items grouped by type:</p>
<p>const queryTypes = <code>type Query {  
    items: [ContentItem],  
    itemsByType(type: String!, limit: Int, depth: Int, order: String): [ContentItem]  
  }</code>;</p>
<p><em>(See the whole file on</em> <a target="_blank" href="https://github.com/Kentico/cloud-boilerplate-express-apollo/blob/master/graphQL/queries.js"><em>GitHub</em></a><em>.)</em></p>
<p>And right after the definition, we can create a resolver for the headless CMS API:</p>
<p>const deliveryClient = new DeliveryClient(deliveryConfig);<br>const resolvers = {<br>  ...<br>  Query: {<br>    items: async () =&gt; {<br>      const response = await deliveryClient.items()<br>        .getPromise();<br>      return response.items;<br>    },<br>    itemsByType: async (_, { type, limit, depth, order }) =&gt; {<br>      const query = deliveryClient.items()<br>        .type(type);<br>      limit &amp;&amp; query.limitParameter(limit);<br>      depth &amp;&amp; query.depthParameter(depth);<br>      order &amp;&amp; query.orderParameter(order);<br>      const response = await query.getPromise();<br>      return response.items;<br>    }<br>  },<br>};</p>
<p><em>(See the whole file on</em> <a target="_blank" href="https://github.com/Kentico/cloud-boilerplate-express-apollo/blob/master/graphQL/queries.js"><em>GitHub</em></a><em>.)</em></p>
<p>Did you notice that the queries always return generic type <code>ContentItem</code> even though there are more specific types like <code>FactAboutUsContentType</code> that inherit <code>ContentItem</code> defined? If you did, great job! Defining a specific query for every single type would be inefficient (there would be so many of them). Therefore both our queries return <code>ContentItem</code> data. But how do we ensure the right models are returned at runtime?</p>
<p>Every content item that comes from the headless CMS contains information about its type. You can see the string property <code>Type</code> in the definition of <code>SystemInfo</code> data model above.</p>
<p>{<br>  "system": {<br>    "type": "fact_about_us"<br>    ...<br>  }<br>...<br>}</p>
<p>Now we know that the content item is of type <code>fact_about_us</code> which corresponds to generated data model <code>FactAboutUsContentType</code>. Therefore we need to translate the type name to pascal case and ensure that GraphQL uses the right data model. We can ensure this using a special resolver for the generic data model:</p>
<p>...<br>const resolvers = {<br>  ContentItem: {<br>    __resolveType(item, _context, _info) {<br>    // fact_about_us -&gt; FactAboutUs<br>    const type = convertSnakeCaseToPascalCase(item);<br>    // FactAboutUs -&gt; FactAboutUsContentType<br>    return type + 'ContentType';<br>  }<br>},<br>...</p>
<p><em>(See the whole file on</em> <a target="_blank" href="https://github.com/Kentico/cloud-boilerplate-express-apollo/blob/master/graphQL/queries.js"><em>GitHub</em></a><em>.)</em></p>
<p>And add a simple function to translate the type name to the data model name:</p>
<p>...<br>// fact_about<em>us -&gt; FactAboutUs<br>const convertSnakeCaseToPascalCase = (item) =&gt; {<br>  return item.system.type<br>    .split('</em>')<br>    .map((str) =&gt; str.slice(0, 1).toUpperCase() + str.slice(1, str.length))<br>    .join('');<br>  }<br>...</p>
<p><em>(See the whole file on</em> <a target="_blank" href="https://github.com/Kentico/cloud-boilerplate-express-apollo/blob/master/graphQL/queries.js"><em>GitHub</em></a><em>.)</em></p>
<p>You see that for the implementation of the resolver you need to know the target service API, or in this case the specifics of the SDK. The developer working on the front-end only needs to know the GraphQL schema regardless of the services you use.</p>
<h1 id="heading-putting-it-all-together">Putting It All Together</h1>
<p>To bring our data models, queries and resolvers to life, we need to create the Apollo server instance in the main <code>app.js</code> file and connect it with Express and our GraphQL schema definitions:</p>
<p>const { TYPE_DEFINITION } = require('./graphQL/types');<br>const { queryTypes, resolvers } = require('./graphQL/queries');<br>const app = express();<br>const apolloServer = new ApolloServer({<br>  introspection: true,<br>  playground: true,<br>  typeDefs: [<br>    TYPE_DEFINITION,<br>    queryTypes<br>  ],<br>  resolvers<br>});<br>apolloServer.applyMiddleware({<br>  app,<br>  path: graphQLPath<br>});</p>
<p><em>(See the whole file on</em> <a target="_blank" href="https://github.com/Kentico/cloud-boilerplate-express-apollo/blob/master/app.js"><em>GitHub</em></a><em>.)</em></p>
<p>In this code, we are telling Apollo which schema to use. The definitions are provided in the <code>typeDefs</code> array and correspond to previously created queries and resolvers.</p>
<p>The rest of the code in <code>app.js</code> (omitted here, but you may take a look at the <a target="_blank" href="https://github.com/Kentico/cloud-boilerplate-express-apollo/blob/master/app.js">whole file on GitHub</a>) is related to Pug templating and routing engine. Pug enables building pages and routes in MVC structure, so it’s easy and straightforward. Take a look at the <code>routes/index.js</code> file (<a target="_blank" href="https://github.com/Kentico/cloud-boilerplate-express-apollo/blob/routes/index.js">file on GitHub</a>) that contains the definition of the only route in the boilerplate project:</p>
<p>...<br>router.get('/', async function (_req, res, _next) {<br>  const result = await apolloClient.query({<br>    query: gql<code>{  
      itemsByType(type: "article", limit: 3, depth: 0, order: "elements.post_date") {  
        ... on ArticleContentType {  
          title {  
            value  
          }  
          summary {  
            value  
          }  
          teaser_image {  
            assets {  
              name  
              url  
            }  
          }  
        }  
      }  
    }</code><br>  });<br>  res.render('index', {<br>    articles: result.data.itemsByType,<br>    ...<br>  });<br>});module.exports = router;</p>
<p>Yes! Finally, a GraphQL query. You see it requests all articles ordered by <code>post_date</code> and specifies which data fields should be provided in the response (<code>title</code>, <code>summary</code>, <code>teaser_image</code>).</p>
<p>Note here that in the query we need to specify which data model we are expecting because not all children of <code>ContentItem</code> must contain requested fields (for example <code>summary</code> or <code>teaser_image</code>). By <code>… on ArticleContentType</code> we are basically creating a <code>switch</code> case that will return defined fields (<code>title</code>, <code>summary</code> and <code>teaser_image</code>) if the returned content item is of type <code>ArticleContentType</code>.</p>
<p>The Apollo Client sends this request to the Apollo Server which forwards it to the Kentico Cloud resolver. The resolver translates the GraphQL query into the REST API. The content takes the same way back to Pug which renders the page according to template in <code>views/index.pug</code>.</p>
<p>How does it all work together? Take a look at the <a target="_blank" href="http://bit.ly/2GGHIB5">live demo</a>.</p>
<h1 id="heading-spare-some-time-for-a-beer">Spare Some Time for a Beer</h1>
<p>All the tools I’ve used and shown you are easy to put together, but why reinvent the wheel? When you want to start implementing a website using Apollo and React or any other JavaScript framework, remember this boilerplate to save yourself some time and effort. If you find anything missing or wish to enhance it, feel free to <a target="_blank" href="http://bit.ly/2ByzwiJ">raise an issue</a> or <a target="_blank" href="http://bit.ly/2TGTmPW">add it directly</a> to the code base.</p>
<p>Do you have experience using Apollo and GraphQL to separate concerns? Would you recommend it to others? Let me know in comments.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to build an Apollo GraphQL server with TypeScript and Webpack Hot Module Replacement ]]>
                </title>
                <description>
                    <![CDATA[ By Derek Fong Let’s build an Apollo GraphQL Server with TypeScript and Webpack HMR! Prerequisites ? Node.js with NPM installed on your computer. At the time of writing, Node.js version 6 or above is required by Apollo Server. Preferably basic unders... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-an-apollo-graphql-server-with-typescript-and-webpack-hot-module-replacement-hmr-3c339d05184f/</link>
                <guid isPermaLink="false">66c3466e2d93bf5de64ebdee</guid>
                
                    <category>
                        <![CDATA[ Apollo GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Software Engineering ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 02 Jan 2019 16:24:13 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*vgURbG0lXqmF05TGz0DU9g.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Derek Fong</p>
<p>Let’s build an Apollo GraphQL Server with TypeScript and Webpack HMR!</p>
<h3 id="heading-prerequisites">Prerequisites ?</h3>
<ul>
<li><a target="_blank" href="https://nodejs.org/">Node.js with NPM</a> installed on your computer. At the time of writing, <a target="_blank" href="https://github.com/apollographql/apollo-server/blob/master/package.json#L34">Node.js version 6 or above</a> is required by Apollo Server.</li>
<li><em>Preferably</em> basic understanding of the…</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ A major 5 line efficiency hack for your GraphQL API Type resolvers ]]>
                </title>
                <description>
                    <![CDATA[ By Vampiire Using Apollo Server and Postgres — Sequelize, we’ll create a proof of concept exploiting the info parameter of the resolver function for a 94% reduction in database load on Type queries*. If you are already familiar with the Apollo Server... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/a-5-line-major-efficiency-hack-for-your-graphql-api-type-resolvers-b58438b62864/</link>
                <guid isPermaLink="false">66c341b5a1d481faeda49ace</guid>
                
                    <category>
                        <![CDATA[ Apollo GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ efficiency ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 08 Aug 2018 14:16:56 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*_5uB_PojUyPvVW0UkpMDUw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Vampiire</p>
<p>Using Apollo Server and Postgres — Sequelize, we’ll create a proof of concept exploiting the info parameter of the resolver function for a 94% reduction in database load on Type queries*.</p>
<p>If you are already familiar with the Apollo Server resolver signature and its <code>info</code> parameter and want to <a target="_blank" href="https://medium.com/@vampiire/a-5-line-major-efficiency-hack-for-your-graphql-api-type-resolvers-b58438b62864#a693"><strong>skip to the hack, click here</strong></a>. Thanks to my inquisitive friend <a target="_blank" href="https://www.freecodecamp.org/news/a-5-line-major-efficiency-hack-for-your-graphql-api-type-resolvers-b58438b62864/undefined">Sloan Brantley Gwaltney</a> for tipping me off to the <code>info</code> parameter’s potential.</p>
<h3 id="heading-background-the-resolver-function-signature">Background — The resolver function signature</h3>
<p>Apollo Server provides the following resolver function signature <a target="_blank" href="https://www.apollographql.com/docs/graphql-tools/resolvers#Resolver-function-signature">from their docs</a>:</p>
<pre><code>fieldName(obj, args, context, info) { result }
</code></pre><p>Back in April, I wrote some notes on the signature to teach to some teammates who were new to GraphQL / Apollo Server. Below is my (slightly) modified version of the signature:</p>
<pre><code>(instance, <span class="hljs-built_in">arguments</span>, context, info) { ...returning data... }
</code></pre><h4 id="heading-instance"><code>**instance**</code></h4>
<blockquote>
<p><em>obj / root / instance</em><br> <em>— GraphQL Type associated with the resolver</em><br> <em>— only used in Type custom field resolvers (for other Types / renamed fields)</em><br> <em>— exists as an <strong>instance</strong> of the Type’s corresponding <strong>database Model</strong></em></p>
<p><code>ex:</code><br> <code>Type: User</code><br> <code>Model: User, instance is ‘user’</code><br> <code>Type custom field resolver:</code><br> <code>user =&gt; user.property/.relationshipGette</code>r()</p>
</blockquote>
<h4 id="heading-arguments"><code>**arguments**</code></h4>
<blockquote>
<p><em>arguments / Input object</em><br> <em>— arguments to the Query or Mutation</em><br> <em>— typically in the form of an Input Type object [defined in the Schema]</em><br> <em>— Inputs are reusable objects that may contain many fields, a subset of which are appropriate for each resolver</em><br> <em>— flexible inputs that can be used for both Query and Mutation resolvers</em><br> <em>— destructuring in the resolver allows selectivity of the Input object fields</em></p>
<p><code>ex:</code><br> <code>UserInput: { id, username, avatar, githubID }</code><br> <code>resolver: (root, { id }) =&gt; User.findById(id);</code><br> <code>// destructures 1 of 4 UserInput fie</code>lds</p>
</blockquote>
<h4 id="heading-context"><code>**context**</code></h4>
<blockquote>
<p><em>context / ctx</em><br> <em>— the context object is injected at runtime in the Apollo middleware declaration of app.js</em><br> <em>— it is the most versatile of the resolver parameters</em><br> <em>— allows you to pass in things like utility functions, database models, authenticated User, and so on</em><br> <em>— by passing these in the context, you no longer need ‘require’ statements for models and helpers. They are accessible directly from the resolver.</em><br> <em>— typically defined as a nesting object with each subcontext having its own object</em></p>
</blockquote>
<h4 id="heading-info"><code>**info**</code></h4>
<blockquote>
<p><em>no idea?</em></p>
</blockquote>
<p>…That was until a serendipitous conversation with Sloan led to discussing this <strong>useless</strong> parameter. Sloan mentioned that it contained information about the incoming Query. This got my gears turning on improving resolver efficiency.</p>
<h3 id="heading-the-info-parameter">The info parameter</h3>
<p>The <code>info</code> object holds details about your entire API Schema and other bits that I assume Apollo Server uses for processing. In particular, it holds information about the Query itself — specifically the set of Type fields requested.</p>
<h4 id="heading-sequelize-and-the-tale-of-gross-inefficiency">Sequelize and the Tale of Gross Inefficiency</h4>
<p>As it turns out, when Sequelize (and I believe every other OR/DM*) resolves rows or documents, it does so in their entirety. On the front / receiving end the data is indeed trimmed to specifications. But on the back end, the process appears to be:</p>
<p><code>DB query for **entire** row/doc</code> → <code>map / custom resolver requested fields</code> → <code>filter data and resolve requested fields</code></p>
<p>This was proven with a Postgres echo I ran from Sequelize on a User query:</p>
<pre><code>SELECT <span class="hljs-string">"id"</span>, <span class="hljs-string">"role"</span>, <span class="hljs-string">"email"</span>, ...wtf Sequelize..., <span class="hljs-string">"timezone"</span>, <span class="hljs-string">"country_id"</span>, <span class="hljs-string">"city_id"</span>, <span class="hljs-string">"created_at"</span>, <span class="hljs-string">"updated_at"</span> FROM <span class="hljs-string">"users"</span> AS <span class="hljs-string">"User"</span> WHERE <span class="hljs-string">"User"</span>.<span class="hljs-string">"github_username"</span> = <span class="hljs-string">'the-vampiire'</span> LIMIT <span class="hljs-number">1</span>;
</code></pre><p>The Postgres query <strong>selects</strong> <strong>all 17 fields</strong> while the API Query itself only requests 1:</p>
<p><code>user(username:”the-vampiire”) { id }</code></p>
<h4 id="heading-digging-into-the-info-object">Digging Into the info Object</h4>
<p>With a bit of digging into the <code>info</code> object, I was able to get to my target: the requested fields. My theory was that if I knew the fields, I could pass them in as the <code>attributes</code> property of the Sequelize query object to reduce the load on the Postgres server.</p>
<p><code>info.fieldNodes[].selectionSet.selections[].name.value</code></p>
<h4 id="heading-notes">notes</h4>
<ul>
<li><code>fieldNodes</code> is an array with the <code>0th</code> element is the first query. My guess is that it’s an array to support batch queries.</li>
<li><code>selections</code> is an array with objects for each requested field of the Type</li>
<li>the field name itself is buried under <code>selections.name.value</code></li>
</ul>
<h3 id="heading-the-hack">The Hack</h3>
<p>So what does all of this mean? Well with a couple of lines of code, a Model (from the context of course!), and the <code>info</code> argument, I wrote the following utility and proof of concept. It uses the Sequelize <code>attributes</code> property of the query object to get data only from the requested columns.</p>
<p>Using this utility resulted in a <strong>94% decrease in the size of the query</strong>. This, of course, scales with the number of fields requested.</p>
<p>One of the major known benefits of using a GraphQL API is that it allows the front end to request a payload of the exact shape and size needed.</p>
<p>Using my utility allows the back end to reflect the same benefits by similarly reducing the load on the database server.</p>
<p>The first and last lines of the <code>mapAttributes</code> function ensure only directly mapped Model fields are passed as <code>attributes</code> to the query object.</p>
<p>This prevents errors that arise from requesting fields that do not exist as columns on the Model.</p>
<p>These would arise from fields that require custom Type field resolvers (like Type relationships or custom Type field names).</p>
<h4 id="heading-proof-of-concept">Proof of Concept</h4>
<p><code>User Type query: user(username:”the-vampiire”) { id }</code></p>
<p><code>before</code> → all 17 fields of the User table are queried</p>
<pre><code>SELECT <span class="hljs-string">"id"</span>, <span class="hljs-string">"role"</span>, <span class="hljs-string">"email"</span>, ...wtf Sequelize..., <span class="hljs-string">"timezone"</span>, <span class="hljs-string">"country_id"</span>, <span class="hljs-string">"city_id"</span>, <span class="hljs-string">"created_at"</span>, <span class="hljs-string">"updated_at"</span> FROM <span class="hljs-string">"users"</span> AS <span class="hljs-string">"User"</span> WHERE <span class="hljs-string">"User"</span>.<span class="hljs-string">"github_username"</span> = <span class="hljs-string">'the-vampiire'</span> LIMIT <span class="hljs-number">1</span>;
</code></pre><p><code>after</code> → only the single requested field is queried</p>
<pre><code>Executing (<span class="hljs-keyword">default</span>): SELECT <span class="hljs-string">"status"</span>, <span class="hljs-string">"id"</span> FROM <span class="hljs-string">"users"</span> AS <span class="hljs-string">"User"</span> WHERE <span class="hljs-string">"User"</span>.<span class="hljs-string">"github_username"</span> = <span class="hljs-string">'the-vampiire'</span> LIMIT <span class="hljs-number">1</span>;
</code></pre><p><img src="https://cdn-media-1.freecodecamp.org/images/1*uY5yPukkf28oxZUtcQVXFw.jpeg" alt="Image" width="670" height="852" loading="lazy">
<em>This hack is officially abided by The Dude</em></p>
<h3 id="heading-caveats">Caveats*</h3>
<ul>
<li>I have not tested this with Mongoose or other popular OR/DMs, but in principle, the effect should be the same. The <code>mapAttributes</code> function and query object would just need a few customizations.</li>
<li>I have not tested this with batch queries with different fields being requested (it may affect the <code>fieldNodes</code> property of <code>info</code>).</li>
<li>Does not work with custom Type field resolvers for renamed fields</li>
<li>The benefits will scale by the ratio of requested Type fields to total fields on the corresponding Model.</li>
</ul>
<p>— Vamp</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to use Apollo’s brand new Query components to manage local state ]]>
                </title>
                <description>
                    <![CDATA[ Note: This article deals with utilizing Apollo’s brand new Query and Mutation components, instead of the HOCs. For those that have read the original article here, be aware that the two articles are very similar. Introduction One of Web Development’s ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/updated-for-apollo-v2-1-managing-local-state-with-apollo-d1882f2fbb7/</link>
                <guid isPermaLink="false">66bb8e01bec1b237336e9683</guid>
                
                    <category>
                        <![CDATA[ Apollo GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Andrico Karoulla ]]>
                </dc:creator>
                <pubDate>Mon, 04 Jun 2018 07:52:49 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*CMxI-q0DAMtcF-VGs10G0Q.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Note: This article deals with utilizing Apollo’s brand new Query and Mutation components, instead of the HOCs. For those that have read the original article <a target="_blank" href="https://itnext.io/managing-local-state-with-apollo-client-3be522258645">here</a>, be aware that the two articles are very similar.</p>
<h3 id="heading-introduction">Introduction</h3>
<p>One of Web Development’s biggest strengths — and weaknesses — is its approach to modularity. A key programming mantra is to choose something (a function, a package) to do a single job and to do it well. The downside to this approach is that a single project can involve juggling dozens of separate technologies and concepts, each focusing on something specific.</p>
<p>So choosing Apollo Client to handle my local state as well as my remote data seems like a no brainer. Why deal with Redux’s boilerplate and idioms when I’ve already got Apollo/GraphQL set up to get data from my backend?</p>
<p>While this article is going to deal with setting up Apollo to handle local state, it’s not going to be an introduction to the tech. (This legit <a target="_blank" href="https://www.howtographql.com/">howtographql</a> tutorial is a good start for that).</p>
<p>Note: The finished repo can be found <a target="_blank" href="https://github.com/andrico1234/apollo-local-state-starter">here</a>. You can pore through the code if you get stuck or feel confused.</p>
<h3 id="heading-getting-set-up">Getting set up</h3>
<p>We’ll start by cloning the corresponding repo from <a target="_blank" href="https://github.com/andrico1234/apollo-state-blog-repo">here</a>. This repo contains a simple react website, with a sidebar, header, and a body. It’s pretty static in nature, no dynamic content (…yet). By the end of this tutorial, we’ll have Apollo managing the state of the website. Clicking an item in the sidebar will change the state of the website, which in turn updates the header to display the new data.</p>
<p>If you check <code>package.json</code> you’ll see that we’ve only got the basics, plus some additional packages pertaining to our parcel setup.</p>
<p>After cloning the repo, run your standard commands in your command line interface.</p>
<pre><code>&gt; yarn
&gt; yarn dev
</code></pre><p>To install all of your packages and to whip up a local server, go to localhost:1234 and you’ll hopefully see the demo website in all of its glory. It’s static right now, so clicking around won’t do a thing.</p>
<p>What we want to do first and foremost is to get Apollo in our project, so install these packages. <code>apollo-client</code> lets us configure our instance of Apollo, and <code>react-apollo</code> is the driver that allows us to integrate it into our React application. Due to an issue with parcel (I think) we’ll also need to install <code>graphql</code>.</p>
<pre><code>&gt; yarn add apollo-client react-apollo graphql
</code></pre><p>Create a new directory <code>src/apollo</code>, crack open an <code>index.js</code> file, and add the following:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> ApolloClient <span class="hljs-keyword">from</span> ‘apollo-client’;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> ApolloClient({});
</code></pre>
<p>This initializes our Apollo Client, which we will then use to wrap our React application by adding the following inside of our <code>src/index.js</code> file.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { ApolloProvider } <span class="hljs-keyword">from</span> ‘react-apollo’;
<span class="hljs-keyword">import</span> { client } <span class="hljs-keyword">from</span> ‘./apollo’;

<span class="hljs-keyword">const</span> WrappedApp = (
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">ApolloProvider</span> <span class="hljs-attr">client</span>=<span class="hljs-string">{client}</span> &gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">ApolloProvider</span>&gt;</span></span>
);

ReactDOM.render(WrappedApp, <span class="hljs-built_in">document</span>.getElementById(‘root’));
<span class="hljs-comment">// Don’t be a sap. Wrap your app.</span>
</code></pre>
<p>We now have Apollo ready to use in our app. Everything builds when we restart our dev server, but we get an error when we try and access it in the browser. The console will tell us that we need to specify the link and cache properties for our Apollo client, so let’s do that.</p>
<pre><code>&gt; yarn add apollo-link apollo-cache-inmemory apollo-link-state
</code></pre><p>The previous line adds the new Apollo dependencies to our application while the following code resolves the console errors we were getting. So go back to <code>apollo/index.js</code> and update it so the file looks like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> ApolloClient <span class="hljs-keyword">from</span> ‘apollo-client’;
<span class="hljs-keyword">import</span> { InMemoryCache } <span class="hljs-keyword">from</span> ‘apollo-cache-inmemory’;
<span class="hljs-keyword">import</span> { ApolloLink } <span class="hljs-keyword">from</span> ‘apollo-link’;
<span class="hljs-keyword">import</span> { withClientState } <span class="hljs-keyword">from</span> ‘apollo-link-state’;

<span class="hljs-keyword">const</span> cache = <span class="hljs-keyword">new</span> InMemoryCache();
<span class="hljs-keyword">const</span> stateLink = withClientState({
  cache
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> ApolloClient({
  cache,
  <span class="hljs-attr">link</span>: ApolloLink.from([
    stateLink,
  ]),
})
</code></pre>
<p>Let’s create an instance of our cache. The cache is Apollo’s normalized data store that stores the results of the query in a flattened data structure. We will read from the cache when we make our GraphQL query, and we’ll write to the cache when we make our mutation resolver.</p>
<p>You can see we’ve also added <code>link</code> to our client object. The <code>ApolloLink.from()</code>method lets us modularly configure how our queries are sent over HTTP. We can use this to handle errors and authorization, and to provide access to our backend. We’re not going to be doing any of this in the tutorial, but we will set up our client state here. So we create <code>const stateLink</code> above and pass in our cache. We’ll add our default state and resolvers here later.</p>
<p>Going back to the browser, you’ll see our lovely static site displaying in all of its magnificence. Let’s add some default state to our project and fire off our first query.</p>
<p>Inside of the Apollo directory, create a new directory called <code>defaults</code> and add an <code>index.js</code> inside of it. The file will contain the following:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">apolloClientDemo</span>: {
    <span class="hljs-attr">__typename</span>: ‘ApolloClientDemo’,
    <span class="hljs-attr">currentPageName</span>: ‘Apollo Demo’,
  }
}
</code></pre>
<p>We create an object which acts as the default state of our site. apolloClientDemo is the name of the data structure we want to access when we make our queries. The <code>__typename</code> is the mandatory identifier that our cache uses, and the currentPageName is the specific item of data that our header will use to — you guessed it — display the current page name.</p>
<p>We’ll need to add this to our <code>apollo/index.js</code> file:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> defaults <span class="hljs-keyword">from</span> ‘./defaults’;

<span class="hljs-keyword">const</span> stateLink = withClientState({
  cache,
  defaults,
});
</code></pre>
<p>Let’s clear this up a little bit. <code>import</code> and <code>default</code> are both keywords associated with importing modules, but coincidentally the name of the object we’re exporting from <code>./defaults</code> is also called <code>defaults</code> (so don’t be thinking that I’m using <code>import/export</code> wrong). Treat this import line as if it was just any regular ol’ named import.</p>
<p>With that out of the way, let’s go make a query!</p>
<h3 id="heading-how-to-make-a-query">How to make a query</h3>
<p>Add the following package to your project:</p>
<pre><code>&gt; yarn add graphql-tag
</code></pre><p>and create a new directory <code>src/graphql</code>. In there, create two new files: <code>index.js</code> and <code>getPageName.js</code>. The GraphQL directory will house all the queries and mutations. We’ll create our query in <code>getPageName.js</code> by writing the following:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> gql <span class="hljs-keyword">from</span> ‘graphql-tag’;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getPageNameQuery = gql<span class="hljs-string">`
  query {
    apolloClientDemo @client {
      currentPageName
    }
  }
`</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getPageNameOptions = ({
  <span class="hljs-attr">props</span>: <span class="hljs-function">(<span class="hljs-params">{ data: { apolloClientDemo } }</span>) =&gt;</span> ({
    apolloClientDemo
  })
});
</code></pre>
<p>So we’re exporting two variables, the query and the options. If you’ve used GraphQL before, then the query will look familiar. We’re querying against the apolloClientDemo data structure, retrieving back nothing more than the currentPageName. You’ll notice that we’ve added the <code>@client</code> directive to our query. This tells Apollo to query our local state instead of sending the request to the backend.</p>
<p>Below you’ll see that we’re exporting some options. This is simply defining how we want the data to look when we map the results to the props. We’re destructuring the GraphQL response and sending it to our view so it looks like this:</p>
<pre><code class="lang-js">props: {
  <span class="hljs-attr">currentPageName</span>: ‘Apollo Demo’,
}
<span class="hljs-comment">// and not this</span>
<span class="hljs-attr">props</span>: {
  <span class="hljs-attr">data</span>: {
    <span class="hljs-attr">apolloClientDemo</span>: {
      <span class="hljs-attr">currentPageName</span>: ‘Apollo Demo’,
    }
  }
}
</code></pre>
<p>Go to the <code>graphql/index.js</code> file and export the query as follows:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> { getPageNameQuery, getPageNameOptions } <span class="hljs-keyword">from</span> ‘./getPageName’;
</code></pre>
<p>Again, while this isn’t completely necessary for a small demo/project, this file is handy should your application grow larger. Having your queries exported from a single centralized location keeps everything organized and scalable.</p>
<p>Add to your Header.js:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { Query } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-apollo'</span>;
<span class="hljs-keyword">import</span> { getPageNameQuery } <span class="hljs-keyword">from</span> <span class="hljs-string">'../graphql'</span>;

<span class="hljs-keyword">const</span> Header = <span class="hljs-function">() =&gt;</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Query</span> <span class="hljs-attr">query</span>=<span class="hljs-string">{getPageNameQuery}</span>&gt;</span>
        {({ loading, error, data }) =&gt; {
            if (error) return <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Error...<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>;
            if (loading || !data) return <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>;

            return <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>{data.apolloClientDemo.currentPageName}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        }}
    <span class="hljs-tag">&lt;/<span class="hljs-name">Query</span>&gt;</span></span>
);

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Header;
</code></pre>
<p>This is our first use of Apollo’s new Query Component, which was added in 2.1. We import <code>Query</code> from <code>react-apollo</code> and use it to wrap the rest of our component. We then pass the getPageNameQuery as a value in the query prop. When our component renders, it fires off the query and gives the rest of the component access to the data, which we destructure to gain access to loading, errors, and data.</p>
<p>The Query Component uses the render props pattern to give the rest of our component access to the information returned from the query. If you’ve used the React Context API in 16.3, then you’ve seen this syntax before. Otherwise it’s worth checking out the official React docs <a target="_blank" href="https://reactjs.org/docs/render-props.html">here</a>, as the Render Props pattern is becoming increasingly popular.</p>
<p>In our component, we do a few checks to see if there were any errors when firing the query or if we’re still waiting for data to be returned. If either of these scenarios are true, we return the corresponding HTML. If the query was fired correctly, the component will dynamically display the title of the current page. As we haven’t added our mutation yet, it will only display the default value. But you can change whatever’s in the default state and the website will reflect that.</p>
<p>Now all that’s left to do is mutate the data in the Apollo cache by clicking on the sidebar item.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*OHpQBcsRCsX5Wk_b." alt="Image" width="800" height="600" loading="lazy">
_A refreshing image to break up the text. [Jeff Sheldon](https://unsplash.com/@ugmonk?utm_source=medium&amp;utm_medium=referral" rel="noopener" target="<em>blank" title=")</em></p>
<h3 id="heading-mutations">Mutations</h3>
<p>Things get a little more complicated when dealing with mutations. We no longer just retrieve data from the Apollo store, but we update it too. The architecture of mutation is as follows:</p>
<p><strong>&gt; U</strong>ser clicks sidebar item</p>
<p><strong>&gt; Se</strong>nds variable to mutation</p>
<p><strong>&gt; Fi</strong>res mutation with variable</p>
<p><strong>&gt; G</strong>ets sent to the instance of Apollo</p>
<p><strong>&gt; Fi</strong>nds corresponding resolver</p>
<p><strong>&gt; Appl</strong>ies logic to the Apollo store</p>
<p><strong>&gt; Se</strong>nds data back to header</p>
<p>If that’s difficult to remember, then use this handy mnemonic created using a mnemonic generator: Urban Senile Fauns Groped Faithless Aslan Solemnly. (easy…)</p>
<p>Start by creating a file <code>graphql/updatePageName.js</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> gql <span class="hljs-keyword">from</span> ‘graphql-tag’;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> updatePageName = gql<span class="hljs-string">`
  mutation updatePageName($name: String!) {
    updatePageName(name: $name) @client {
      currentPageName
    }
  }
`</span>;
</code></pre>
<p>and export it just like we did with the query.</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> { updatePageNameMutation } <span class="hljs-keyword">from</span> ‘./updatePageName’;
</code></pre>
<p>You’ll notice a few differences regarding the mutation. First off we’ve changed the keyword from query to mutation. This lets GraphQL know the type of action we’re performing. We’re also defining the name of the query and adding types to the variables we’re passing in. Inside here we’re specifying the name of the resolver we’ll be using to carry out the changes. We’re also passing through the variable and adding the <code>@client</code> directive.</p>
<p>Unlike the query, we can’t just add the mutation to our view and expect anything to happen. We’ll have to go back to our Apollo directory and add our resolvers. So go ahead and create a new directory <code>apollo/resolvers</code>, and files <code>index.js</code> and <code>updatePageName.js</code>. Inside of <code>updatePageName.js</code>add the following:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> gql <span class="hljs-keyword">from</span> ‘graphql-tag’;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> (_, { name }, { cache }) =&gt; {
  <span class="hljs-keyword">const</span> query = gql<span class="hljs-string">`
    query GetPageName {
      apolloClientDemo @client {
        currentPageName
      }
    }
  `</span>;

  <span class="hljs-keyword">const</span> previousState = cache.readQuery({ query });

  <span class="hljs-keyword">const</span> data = {
    <span class="hljs-attr">apolloClientDemo</span>: {
      …previousState.apolloClientDemo,
      <span class="hljs-attr">currentPageName</span>: name,
    },
  };

  cache.writeQuery({
    query,
    data,
  });

  <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
};
</code></pre>
<p>There are a lot of interesting things going on in this file. Fortunately, it’s all very logical and doesn’t add many new concepts to what we’ve seen before.</p>
<p>So by default, when a resolver gets called, Apollo passes in all of the variables and the cache. The first argument is a simple ‘_’ because we don’t need to use it. The second argument is the variables object, and the final argument is the cache.</p>
<p>Before we can make changes to the Apollo store, we’ll need to retrieve it. So we make a simple request to get the current content from the store and assign it to previousState. Inside of the data variable, we create a new object with the new information we want to add to the store, which we then write to. You can see that we’ve spread the previous state inside of this object. This is so that only the data we explicitly want to change gets updated. Everything else remains as it is. This prevents Apollo from needlessly updating components whose data hasn’t changed.</p>
<p>Note: while this isn’t completely necessary for this example, it’s super useful when queries and mutations handle larger amounts of data, so I’ve kept it in for the sake of scalability.</p>
<p>Meanwhile in the <code>resolvers/index.js</code> file…</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> updatePageName <span class="hljs-keyword">from</span> ‘updatePageName’;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-attr">Mutation</span>: {
    updatePageName,
  }
};
</code></pre>
<p>This is the shape of object that Apollo expects when we pass in our resolvers in to stateLink back in <code>apollo/index.js</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> resolvers <span class="hljs-keyword">from</span> ‘./resolvers’;

<span class="hljs-keyword">const</span> stateLink <span class="hljs-keyword">from</span> = withClientState({
  cache,
  defaults,
  resolvers,
});
</code></pre>
<p>All that’s left to do is add the mutation to our sidebar component.</p>
<pre><code class="lang-js"><span class="hljs-comment">// previous imports</span>
<span class="hljs-keyword">import</span> { Mutation } <span class="hljs-keyword">from</span> ‘react-apollo’;
<span class="hljs-keyword">import</span> { updatePageNameMutation } <span class="hljs-keyword">from</span> ‘../graphql’;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Sidebar</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  render() {
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Mutation</span> <span class="hljs-attr">mutation</span>=<span class="hljs-string">{updatePageNameMutation}</span>&gt;</span>
        {updatePageName =&gt; (
          // outer div elements
          <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">className</span>=<span class="hljs-string">“sidebar-item”</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> updatePageName({ variables: { name: ‘React’} })}&gt;React<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
          // other list items and outer div elements
        )}
      <span class="hljs-tag">&lt;/<span class="hljs-name">Mutation</span>&gt;</span></span>
    );
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Sidebar;
</code></pre>
<p>Like our resolver file, there’s a lot going on in this file — but it’s new. We import our <code>Mutation</code> component from <code>react-apollo</code>, wrap it around our component, and pass the <code>updatePageNameMutation</code> inside of the <code>mutation</code> prop.</p>
<p>The component now has access to the <code>updatePageName</code> method which fires the mutation whenever it’s called. We do this by adding the method as a handler to the <code>&lt;</code>li&gt;’s onClick property. The method expects to receive on object containing the variables as a parameter, so pass in the name you want to update the header to. If everything works, you should be able to run your dev server and click the sidebar items, which should then change our header.</p>
<h3 id="heading-wrapping-up">Wrapping up</h3>
<p>Hooray! Hopefully everything worked out. If you got stuck, then check out the repo <a target="_blank" href="https://github.com/andrico1234/apollo-local-state-starter">here</a>. It contains all of the finished code. If you’re thinking of using local state management in your next React app, then you can fork this repo and continue from there. If you’re interested in having this article/topic spoken about at a meetup or conference, then send a message my way!</p>
<p>There’s a lot more I wanted to cover in this tutorial, such as async resolvers (think Redux thunk), type checking/creating a schema, and a mutation update. So who knows… maybe I’ll drop another article sometime soon.</p>
<p>I really hope that this tutorial was useful for you. I’d like to shout out <a target="_blank" href="https://www.youtube.com/watch?v=2RvRcnD8wHY">Sara Vieira’s youtube tutorial too</a>, as it helped me get my head around Apollo Client. If I haven’t done my job well enough by leaving you scratching your head, then follow the link. And finally, feel free to hit me up on social media, I’m a big music and tech fan so talk geek to me.</p>
<h4 id="heading-thanks-for-reading">Thanks for reading!</h4>
<p>If you’re interested in hosting me at a conference, meetup or as a speaking guest for any engagement then you can DM me on <a target="_blank" href="https://twitter.com/andricokaroulla?lang=en">twitter</a>!</p>
<h4 id="heading-you-can-check-out-my-other-articles-below">You can check out my other articles below:</h4>
<p><a target="_blank" href="https://medium.com/@andricokaroulla/updated-for-apollo-v2-1-managing-local-state-with-apollo-d1882f2fbb7"><em>How to use Apollo’s brand new Query components to manage local state</em></a></p>
<p>[<em>Add a touch of Suspense to your web app with React.lazy()</em>](http://Add a touch of Suspense to your web app with React.lazy())</p>
<p><a target="_blank" href="https://codeburst.io/no-need-to-wait-for-the-holidays-start-decorating-now-67b9dabd60d7"><em>No need to wait for the holidays, start Decorating now</em></a></p>
<p><a target="_blank" href="https://itnext.io/managing-local-state-with-apollo-client-3be522258645"><em>Managing local state with Apollo and Higher Order Components</em></a></p>
<p><a target="_blank" href="https://medium.com/@andricokaroulla/the-react-conference-drinking-game-7a996bfbef3"><em>The React Conference drinking game</em></a></p>
<p><a target="_blank" href="https://codeburst.io/develop-and-deploy-your-own-react-monorepo-app-in-under-2-hours-using-lerna-travis-and-now-2b140d647238"><em>Develop and Deploy your own React monorepo app in under 2 hours, using Lerna, Travis and Now</em></a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Mocking GraphQL with graphql-tools+ ]]>
                </title>
                <description>
                    <![CDATA[ By Jeff M Lowery How to mock up your GraphQL API with realistic values In my last article, I took the original Apollo LaunchPad Posts and Authors API and broke it down into domains and components. I wanted to illustrate how one could organize a large... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/mocking-graphql-with-graphql-tools-42c2dd9d0364/</link>
                <guid isPermaLink="false">66d45f7b38f2dc3808b790cf</guid>
                
                    <category>
                        <![CDATA[ Apollo GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GraphQL ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Mocking ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Testing ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Sun, 03 Sep 2017 23:15:48 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9cb38c740569d1a4cac9a0.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Jeff M Lowery</p>
<h4 id="heading-how-to-mock-up-your-graphql-api-with-realistic-values">How to mock up your GraphQL API with realistic values</h4>
<p>In <a target="_blank" href="https://medium.com/@jefflowery/declarative-graphql-with-graphql-tools-cd1645f94fc">my last article,</a> I took the original Apollo LaunchPad <a target="_blank" href="https://launchpad.graphql.com/1jzxrj179">Posts and Authors API</a> and broke it down into domains and components. I wanted to illustrate how one could organize a large GraphQL project using <a target="_blank" href="https://github.com/apollographql/graphql-tools">graphql-tools</a>.</p>
<p>Now I’d like the API to return mock data when I query it. How?</p>
<h3 id="heading-the-original-source">The original source</h3>
<p>In the original Apollo Launchpad example, we used static data structures and simple mapping resolvers to provide output for queries.</p>
<p>For instance, given this query:</p>
<pre><code class="lang-graphql"><span class="hljs-comment"># Welcome to GraphiQL</span>

<span class="hljs-keyword">query</span> PostsForAuthor {
  author(<span class="hljs-symbol">id:</span> <span class="hljs-number">1</span>) {
    firstName
    posts {
      title
      votes
    }
  }
}
</code></pre>
<p>The output would be:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"data"</span>: {
    <span class="hljs-attr">"author"</span>: {
      <span class="hljs-attr">"firstName"</span>: <span class="hljs-string">"Tom"</span>,
      <span class="hljs-attr">"posts"</span>: [
        {
          <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Introduction to GraphQL"</span>,
          <span class="hljs-attr">"votes"</span>: <span class="hljs-number">2</span>
        }
      ]
    }
  }
}
</code></pre>
<p>The resolvers object has functions that take care of mapping authors to posts and visa-versa. It’s not truly a mock, though.</p>
<p>The problem is that the more relationships and the more complex the entities become, the more code needs to go into the resolvers. Then more data needs to be provided.</p>
<p>When it comes to testing, tests are likely to sometimes reveal problems in the data or in the resolvers. You really want focus testing of the API itself.</p>
<h3 id="heading-using-mocks">Using mocks</h3>
<p>There are three Node.js modules that make mocking an API quick and easy. The first is part of the <code>graphql-tools</code> module. Using this module, a beginning step is to require or import the method <code>addMockFunctionsToSchema</code> from the module into the root <code>schema.js</code> file:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> {
    makeExecutableSchema,
    addMockFunctionsToSchema
} <span class="hljs-keyword">from</span> <span class="hljs-string">'graphql-tools'</span>;
</code></pre>
<p>Then, after creating an executable <code>schema</code> by calling <code>createExecutableSchema</code>, you add your mocks like so:</p>
<pre><code class="lang-js">    addMockFunctionsToSchema({
        <span class="hljs-attr">schema</span>: executableSchema,
    })
</code></pre>
<p>Here’s a full listing of the root <code>schema.js</code>:</p>
<pre><code class="lang-js"><span class="hljs-comment">// This example demonstrates a simple server with some relational data: Posts and Authors. You can get the posts for a particular author,</span>
<span class="hljs-comment">// and vice-versa Read the complete docs for graphql-tools here: http://dev.apollodata.com/tools/graphql-tools/generate-schema.html</span>

<span class="hljs-keyword">import</span> {
    makeExecutableSchema,
    addMockFunctionsToSchema
} <span class="hljs-keyword">from</span> <span class="hljs-string">'graphql-tools'</span>;

<span class="hljs-keyword">import</span> {
    schema <span class="hljs-keyword">as</span> authorpostsSchema,
    resolvers <span class="hljs-keyword">as</span> authorpostsResolvers
} <span class="hljs-keyword">from</span> <span class="hljs-string">'./authorposts'</span>;

<span class="hljs-keyword">import</span> {
    schema <span class="hljs-keyword">as</span> myLittleTypoSchema,
    resolvers <span class="hljs-keyword">as</span> myLittleTypeResolvers
} <span class="hljs-keyword">from</span> <span class="hljs-string">'./myLittleDomain'</span>;

<span class="hljs-keyword">import</span> {
    merge
} <span class="hljs-keyword">from</span> <span class="hljs-string">'lodash'</span>;

<span class="hljs-keyword">const</span> baseSchema = [
    <span class="hljs-string">`
    type Query {
        domain: String
    }
    type Mutation {
        domain: String
    }
    schema {
        query: Query,
        mutation: Mutation
    }`</span>
]

<span class="hljs-comment">// Put schema together into one array of schema strings and one map of resolvers, like makeExecutableSchema expects</span>
<span class="hljs-keyword">const</span> schema = [...baseSchema, ...authorpostsSchema, ...myLittleTypoSchema]

<span class="hljs-keyword">const</span> options = {
    <span class="hljs-attr">typeDefs</span>: schema,
    <span class="hljs-attr">resolvers</span>: merge(authorpostsResolvers, myLittleTypeResolvers)
}

<span class="hljs-keyword">const</span> executableSchema = makeExecutableSchema(options);

addMockFunctionsToSchema({
    <span class="hljs-attr">schema</span>: executableSchema
})

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> executableSchema;
</code></pre>
<p>So what’s the output? Executing the same query as before yields:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"data"</span>: {
    <span class="hljs-attr">"author"</span>: {
      <span class="hljs-attr">"firstName"</span>: <span class="hljs-string">"Hello World"</span>,
      <span class="hljs-attr">"posts"</span>: [
        {
          <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Hello World"</span>,
          <span class="hljs-attr">"votes"</span>: <span class="hljs-number">-70</span>
        },
        {
          <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Hello World"</span>,
          <span class="hljs-attr">"votes"</span>: <span class="hljs-number">-77</span>
        }
      ]
    }
  }
}
</code></pre>
<p>Well, that’s kind of dumb. Every string is “Hello World”, votes are negative, and there will always be exactly two posts per author. We’ll fix that, but first…</p>
<h4 id="heading-why-use-mocks">Why use mocks?</h4>
<p>Mocks are often used in unit tests to separate the functionality being tested from the dependencies that those functions rely on. You want to test the function (the unit), not a whole complex of functions.</p>
<p>At this early stage of development, mocks serve another purpose: to test the tests. In a basic test, you want to ensure first that the test is calling the API correctly, and that the results returned have the expected structure, properties, and types. I think the cool kids call this “shape”.</p>
<p>This offers more limited testing than a queryable data structure, because reference semantics are not enforced. <code>id</code> is meaningless. Nonetheless, mocks offer something to structure your tests around</p>
<h3 id="heading-realistic-mocking">Realistic mocking</h3>
<p>There’s a module called <a target="_blank" href="https://github.com/boo1ean/casual">casual</a> that I really like. It provides reasonable and variable values for a lot of common data types. If you are demonstrating your new API in front of jaded colleagues, it actually looks like you’ve done something special.</p>
<p>Here’s a wish list for mock values to display:</p>
<ol>
<li>Author’s first name should be <strong>first-name-like</strong></li>
<li>Post titles should be variable <strong>lorem ipsum</strong> text of limited length</li>
<li>votes should be positive or zero</li>
<li>the number of posts should vary between 1 and 7</li>
</ol>
<p>First thing is to create a folder called <code>mocks</code>. Next, we’ll add an <code>index.js</code> file to that folder with the mock methods. Finally, the custom mocks will be added to the generated executable schema.</p>
<p>The <strong>casual</strong> library can generate values by data type (<code>String, ID, Int, …</code>) or by property name. Also, graphql-tools MockList object will be used to vary the number of items in a list — in this case <code>posts</code>. So let’s start.</p>
<p><code>Import</code> both casual and MockList into <code>/mocks/index.js</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> casual <span class="hljs-keyword">from</span> <span class="hljs-string">'casual'</span>;
<span class="hljs-keyword">import</span> {
    MockList
} <span class="hljs-keyword">from</span> <span class="hljs-string">'graphql-tools'</span>;
</code></pre>
<p>Now let create a default export with the following properties:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
    <span class="hljs-attr">Int</span>: <span class="hljs-function">() =&gt;</span> casual.integer(<span class="hljs-number">0</span>),

    <span class="hljs-attr">Author</span>: <span class="hljs-function">() =&gt;</span> ({
        <span class="hljs-attr">firstName</span>: casual.first_name,
        <span class="hljs-attr">posts</span>: <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">new</span> MockList([<span class="hljs-number">1</span>, <span class="hljs-number">7</span>])
    }),

    <span class="hljs-attr">Post</span>: <span class="hljs-function">() =&gt;</span> ({
        <span class="hljs-attr">title</span>: casual.title
    })
}
</code></pre>
<p>The <code>Int</code> declaration takes care of all integer types appearing in our schema and it will ensure that <code>Post.votes</code> will be positive or zero.</p>
<p>Next, <code>Author.firstName</code> will be a reasonable first name. MockList is used to ensure the number of posts associated with each Author will be between 1 and 7. Finally, casual will generate a <strong>lorem ipsum</strong> <code>title</code> for each <code>Post</code>.</p>
<p>Now the generated output varies each time the query is executed. And it looks credible:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"data"</span>: {
    <span class="hljs-attr">"author"</span>: {
      <span class="hljs-attr">"firstName"</span>: <span class="hljs-string">"Eldon"</span>,
      <span class="hljs-attr">"posts"</span>: [
        {
          <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Voluptatum quae laudantium"</span>,
          <span class="hljs-attr">"votes"</span>: <span class="hljs-number">581</span>
        },
        {
          <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Vero quos"</span>,
          <span class="hljs-attr">"votes"</span>: <span class="hljs-number">85</span>
        },
        {
          <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Doloribus labore corrupti"</span>,
          <span class="hljs-attr">"votes"</span>: <span class="hljs-number">771</span>
        },
        {
          <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Qui nulla qui"</span>,
          <span class="hljs-attr">"votes"</span>: <span class="hljs-number">285</span>
        }
      ]
    }
  }
}
</code></pre>
<h3 id="heading-generating-custom-values">Generating custom values</h3>
<p>I just scratched the surface of what casual can do, but it is well-documented and there’s nothing much to add.</p>
<p>Sometimes, though, there are values that have to conform to a standard format. I would like to introduce one more module: <a target="_blank" href="https://www.npmjs.com/package/randexp">randexp</a>.</p>
<p>randexp allows you to generate values conforming to the regexp expression you provide it. For instance, ISBN numbers have the format:</p>
<p><strong>/ISBN-\d-\d{3}-\d{5}-\d/</strong></p>
<p>Now I can add Books to the schema, add books to Author, and generate ISBN and title for each <code>Book</code>:</p>
<pre><code class="lang-js"><span class="hljs-comment">// book.js</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-string">`
  type Book {
    ISBN: String
    title: String
}</span>
</code></pre>
<p>mocks.js:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> casual <span class="hljs-keyword">from</span> <span class="hljs-string">'casual'</span>;
<span class="hljs-keyword">import</span> RandExp <span class="hljs-keyword">from</span> <span class="hljs-string">'randexp'</span>;
<span class="hljs-keyword">import</span> {
    MockList
} <span class="hljs-keyword">from</span> <span class="hljs-string">'graphql-tools'</span>;
<span class="hljs-keyword">import</span> {
    startCase
} <span class="hljs-keyword">from</span> <span class="hljs-string">'lodash'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
    <span class="hljs-attr">Int</span>: <span class="hljs-function">() =&gt;</span> casual.integer(<span class="hljs-number">0</span>),

<span class="hljs-attr">Author</span>: <span class="hljs-function">() =&gt;</span> ({
        <span class="hljs-attr">firstName</span>: casual.first_name,
        <span class="hljs-attr">posts</span>: <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">new</span> MockList([<span class="hljs-number">1</span>, <span class="hljs-number">7</span>]),
        <span class="hljs-attr">books</span>: <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">new</span> MockList([<span class="hljs-number">0</span>, <span class="hljs-number">5</span>])
    }),

<span class="hljs-attr">Post</span>: <span class="hljs-function">() =&gt;</span> ({
        <span class="hljs-attr">title</span>: casual.title
    }),

<span class="hljs-attr">Book</span>: <span class="hljs-function">() =&gt;</span> ({
        <span class="hljs-attr">ISBN</span>: <span class="hljs-keyword">new</span> RandExp(<span class="hljs-regexp">/ISBN-\d-\d{3}-\d{5}-\d/</span>)
            .gen(),
        <span class="hljs-attr">title</span>: startCase(casual.title)
    })
}
</code></pre>
<p>And here’s a new query:</p>
<pre><code class="lang-graphql"><span class="hljs-keyword">query</span> PostsForAuthor {
  author(<span class="hljs-symbol">id:</span> <span class="hljs-number">1</span>) {
    firstName
    posts {
      title
      votes
    }
    books {
      title
      ISBN
    }
  }
}
</code></pre>
<p>Sample response:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"data"</span>: {
    <span class="hljs-attr">"author"</span>: {
      <span class="hljs-attr">"firstName"</span>: <span class="hljs-string">"Rosemarie"</span>,
      <span class="hljs-attr">"posts"</span>: [
        {
          <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Et ipsum quo"</span>,
          <span class="hljs-attr">"votes"</span>: <span class="hljs-number">248</span>
        },
        {
          <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Deleniti nihil"</span>,
          <span class="hljs-attr">"votes"</span>: <span class="hljs-number">789</span>
        },
        {
          <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Aut aut reprehenderit"</span>,
          <span class="hljs-attr">"votes"</span>: <span class="hljs-number">220</span>
        },
        {
          <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Nesciunt debitis mollitia"</span>,
          <span class="hljs-attr">"votes"</span>: <span class="hljs-number">181</span>
        }
      ],
      <span class="hljs-attr">"books"</span>: [
        {
          <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Consequatur Veniam Voluptas"</span>,
          <span class="hljs-attr">"ISBN"</span>: <span class="hljs-string">"ISBN-0-843-74186-9"</span>
        },
        {
          <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Totam Et Iusto"</span>,
          <span class="hljs-attr">"ISBN"</span>: <span class="hljs-string">"ISBN-6-532-70557-3"</span>
        },
        {
          <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Voluptatem Est Sunt"</span>,
          <span class="hljs-attr">"ISBN"</span>: <span class="hljs-string">"ISBN-2-323-13918-2"</span>
        }
      ]
    }
  }
}
</code></pre>
<p>So that’s the basics of mocking using graphql-tools plus a couple of other useful modules .</p>
<p><strong>Note</strong>: I use snippets throughout this post. If you want to follow along in a broader context, sample code is <a target="_blank" href="https://github.com/JeffML/graphql_authors_mock">here</a>.</p>
<p>The <a target="_blank" href="https://github.com/JeffML/graphql_authors_mock">Full source</a> is on GitHub for your perusal.</p>
<p>Give me a hand if you found this article informative.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
